[libcxx-commits] [PATCH] D110598: [libc++] Implement P0980R1 (constexpr std::string)
Nikolas Klauser via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Apr 9 07:47:29 PDT 2022
philnik added inline comments.
================
Comment at: libcxx/include/string:1935-1936
{
+ if (__libcpp_is_constant_evaluated())
+ __zero();
if (__reserve > max_size())
----------------
ldionne wrote:
> What if instead of doing this, we made sure to have the invariants of the string hold before calling `__init`, and then we'd "simply" have to check whether we already have a long string allocated at the beginning of `__init`?
I think we agreed that this is OK and we make sure that `__init` is only ever called inside constructors.
================
Comment at: libcxx/include/string:2878-2884
+ if (__libcpp_is_constant_evaluated()) {
+ if (__cap - __sz >= __n)
+ __grow_by_and_replace(__cap, 0, __sz, __pos, 0, __n, __s);
+ else
+ __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
+ return *this;
+ }
----------------
ldionne wrote:
> I'd like to understand why this diff is needed. What happens if you remove it?
We may compare unrelated pointers with `__p + __pos <= __s && __s < __p + __sz`.
================
Comment at: libcxx/include/string:3093-3096
+ if (__libcpp_is_constant_evaluated()) {
+ __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s);
+ return *this;
+ }
----------------
ldionne wrote:
> Same question here -- why is this required?
Same here - we may compare unrelated pointers.
================
Comment at: libcxx/include/string:4372-4373
typename _String::size_type __rhs_sz = __rhs.size();
+ __r.__deallocate_constexpr();
__r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
__r.append(__rhs.data(), __rhs_sz);
----------------
ldionne wrote:
> Could we investigate adding a private constructor that allows passing a capacity to pre-allocate, so this could be implemented like this:
>
> ```
> using _String = basic_string<_CharT, _Traits, _Allocator>;
> typename _String::size_type __lhs_sz = __lhs.size();
> typename _String::size_type __rhs_sz = __rhs.size();
> _String __r(_String::__alloc_traits::select_on_container_copy_construction(__lhs.get_allocator()), __capacity_tag{}, __lhs_sz + __rhs_sz);
> __r.append(__lhs.data(), __lhs_sz);
> __r.append(__rhs.data(), __rhs_sz);
> return __r;
> ```
>
> Can we please do this as a separate review? That should be easy to split out.
This is D123058 now.
================
Comment at: libcxx/test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp:13
-// ~basic_string() // implied noexcept;
+// ~basic_string() // implied noexcept; // constexpr since C++20
----------------
ldionne wrote:
> Same thing here -- we don't have a runtime test for the string destructor outside of the static variable below. Please add one -- this can be done in the same review as the default ctor.
>
> You could use a special allocator and check that `deallocate()` has been called after the string is destroyed.
This is now D123129.
================
Comment at: libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_view_size.pass.cpp:154-157
// typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
// typedef std::string_view SV;
// test0<S, SV>();
// test1<S, SV>();
----------------
ldionne wrote:
> Can you try uncommenting this and seeing what happens?
Seems to just work.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D110598/new/
https://reviews.llvm.org/D110598
More information about the libcxx-commits
mailing list