[libcxx-commits] [PATCH] D131668: [libc++] Implement P2438R2 (std::string::substr() &&)
Konstantin Varlamov via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Aug 19 00:01:56 PDT 2022
var-const added inline comments.
================
Comment at: libcxx/test/std/strings/basic.string/string.cons/substr_rvalue.pass.cpp:35
+ S substr(std::move(orig), pos);
+ LIBCPP_ASSERT(orig.__invariants());
+ LIBCPP_ASSERT(orig.empty());
----------------
Optional: consider moving the checks into a helper function to cut down on boilerplate.
================
Comment at: libcxx/test/std/strings/basic.string/string.cons/substr_rvalue.pass.cpp:53
+constexpr void
+test_string_pos_alloc(S orig, typename S::size_type pos, const typename S::allocator_type& alloc, S expected) {
+ if (pos <= orig.size()) {
----------------
Can we do some equivalent of `DisableAllocationGuard` in this test as well?
================
Comment at: libcxx/test/std/strings/basic.string/string.cons/substr_rvalue.pass.cpp:61
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ else if (!std::is_constant_evaluated()) {
+ try {
----------------
I'd split the normal case and the exceptional case in two functions. These are very different concerns, and I find the current triple-check (if `pos` is not valid, and it's not constant-evaluated, and exceptions are enabled) a little overwhelming. Making the `expected` parameter double as essentially a boolean also doesn't feel very clean. This would also be clearer at the call site (I'd group all normal cases and all exception cases together, i.e. a bunch of `test_string_pos`, `test_string_pos_n`, etc., followed by a bunch of `test_string_pos_exception`, `test_string_pos_n_exception`, etc.
I know it will increase the number of `test_string_*` functions even more, but I think it's the lesser evil. The amount of code won't increase substantially, and the smaller functions will be easier to read.
================
Comment at: libcxx/test/std/strings/basic.string/string.cons/substr_rvalue.pass.cpp:118
+constexpr void test_string(const typename S::allocator_type& alloc) {
+ test_string_pos<S>(STR(""), 0, STR(""));
+ test_string_pos<S>(STR(""), 1, STR("exception"));
----------------
Question (not for this patch): do we still need these macros even in the latest language modes, or can this now be achieved by regular code?
================
Comment at: libcxx/test/std/strings/basic.string/string.ops/string_substr/substr_rvalue.pass.cpp:28
+ if (pos <= orig.size()) {
+ auto orig_string_copy = orig;
+ auto rlen = std::min<size_t>(n, orig.size() - pos);
----------------
`orig_string_copy` seems unused?
================
Comment at: libcxx/test/std/strings/basic.string/string.ops/string_substr/substr_rvalue.pass.cpp:29
+ auto orig_string_copy = orig;
+ auto rlen = std::min<size_t>(n, orig.size() - pos);
+ S str = std::move(orig).substr(pos, n);
----------------
What's the benefit of calculating `rlen`, given that the `str == expected` check would also compare lengths? If it's necessary to check the length explicitly for some reason, I think it should be an argument to this function.
================
Comment at: libcxx/test/std/strings/basic.string/string.ops/string_substr/substr_rvalue.pass.cpp:32
+ LIBCPP_ASSERT(orig.__invariants());
+ LIBCPP_ASSERT(str.__invariants());
+ assert(str.size() == rlen);
----------------
In the constructor test we don't check `__invariants()` on `str`, can you make this consistent?
================
Comment at: libcxx/test/std/strings/basic.string/string.ops/string_substr/substr_rvalue.pass.cpp:26
+ auto rlen = std::min<size_t>(n, orig.size() - pos);
+ S str = std::move(orig).substr(pos, n);
+ LIBCPP_ASSERT(orig.__invariants());
----------------
philnik wrote:
> avogelsgesang wrote:
> > DisableAllocationGuard`?
> Same reason as above: an implementation is allowed to allocate.
The implementation is recommended to avoid allocation, though, and I think we want to check that we follow that.
================
Comment at: libcxx/test/support/count_new.h:439
{
- // Don't re-disable if already disabled.
- if (globalMemCounter.disable_allocations == true) m_disabled = false;
- if (m_disabled) globalMemCounter.disableAllocations();
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ // Don't re-disable if already disabled.
----------------
Why is this a no-op in consteval mode?
================
Comment at: libcxx/test/support/count_new.h:453
- ~DisableAllocationGuard() {
+ TEST_CONSTEXPR_CXX20 ~DisableAllocationGuard() {
release();
----------------
Why are the constexpr language versions different between member functions?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D131668/new/
https://reviews.llvm.org/D131668
More information about the libcxx-commits
mailing list