diff options
Diffstat (limited to 'libcxx/include/__string')
| -rw-r--r-- | libcxx/include/__string | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/libcxx/include/__string b/libcxx/include/__string index 890fb21dd3f1..13ff7b35e47d 100644 --- a/libcxx/include/__string +++ b/libcxx/include/__string @@ -42,9 +42,6 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -// The the extern template ABI lists are kept outside of <string> to improve the -// readability of that header. - // The extern template ABI lists are kept outside of <string> to improve the // readability of that header. We maintain 2 ABI lists: // - _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST @@ -293,31 +290,34 @@ char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) template <class _CharT> static inline _LIBCPP_CONSTEXPR_AFTER_CXX17 -_CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT +_CharT* __copy_constexpr(_CharT* __dest, const _CharT* __source, 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(__source, __n, __dest); + return __dest; } template <class _CharT> 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<const _CharT*>(__allocation), __n); + delete[] __allocation; + return __dest; } template <class _CharT> 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<char> @@ -340,8 +340,21 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char> static _LIBCPP_CONSTEXPR_AFTER_CXX14 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; - static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14 - length(const char_type* __s) _NOEXCEPT {return __builtin_strlen(__s);} + + static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14 length(const char_type* __s) _NOEXCEPT { + // GCC currently does not support __builtin_strlen during constant evaluation. + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816 +#ifdef _LIBCPP_COMPILER_GCC + if (__libcpp_is_constant_evaluated()) { + size_t __i = 0; + for (; __s[__i] != char_type('\0'); ++__i) + ; + return __i; + } +#endif + return __builtin_strlen(__s); + } + static _LIBCPP_CONSTEXPR_AFTER_CXX14 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; static inline _LIBCPP_CONSTEXPR_AFTER_CXX17 |
