From edb46980081c4ae78199491da71e18c99104451c Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Tue, 21 Dec 2021 11:22:50 +0100 Subject: [PATCH] [libc++] Allow __move_constexpr to work with unrelated pointers Allow `__move_constexpr` to work with unrelated pointers and `_LIBCPP_ASSERT` that `__copy_constexpr`, `__move_constexpr` and `__assign_constexpr` are only run during constant evaluation Reviewed By: ldionne, #libc Spies: libcxx-commits Differential Revision: https://reviews.llvm.org/D115986 --- libcxx/include/__string | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/libcxx/include/__string b/libcxx/include/__string index 2840819..728367b 100644 --- a/libcxx/include/__string +++ b/libcxx/include/__string @@ -290,31 +290,34 @@ char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) template static inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -_CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT +_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT { - if (__n == 0) return __s1; - if (__s1 < __s2) { - _VSTD::copy(__s2, __s2 + __n, __s1); - } else if (__s2 < __s1) { - _VSTD::copy_backward(__s2, __s2 + __n, __s1 + __n); - } - return __s1; + _LIBCPP_ASSERT(__libcpp_is_constant_evaluated(), "__copy_constexpr() should always be constant evaluated"); + _VSTD::copy_n(__s2, __n, __s1); + return __s1; } template static inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT +_CharT* __move_constexpr(_CharT* __dest, const _CharT* __source, size_t __n) _NOEXCEPT { - _VSTD::copy_n(__s2, __n, __s1); - return __s1; + _LIBCPP_ASSERT(__libcpp_is_constant_evaluated(), "__move_constexpr() should always be constant evaluated"); + if (__n == 0) + return __dest; + _CharT* __allocation = new _CharT[__n]; + _VSTD::__copy_constexpr(__allocation, __source, __n); + _VSTD::__copy_constexpr(__dest, static_cast(__allocation), __n); + delete[] __allocation; + return __dest; } template static inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT* __assign_constexpr(_CharT* __s, size_t __n, _CharT __a) _NOEXCEPT { - _VSTD::fill_n(__s, __n, __a); - return __s; + _LIBCPP_ASSERT(__libcpp_is_constant_evaluated(), "__assign_constexpr() should always be constant evaluated"); + _VSTD::fill_n(__s, __n, __a); + return __s; } // char_traits -- 2.7.4