diff options
Diffstat (limited to 'libcxx/include/__string/char_traits.h')
-rw-r--r-- | libcxx/include/__string/char_traits.h | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/libcxx/include/__string/char_traits.h b/libcxx/include/__string/char_traits.h index e7c63a245cac..a2332829b414 100644 --- a/libcxx/include/__string/char_traits.h +++ b/libcxx/include/__string/char_traits.h @@ -212,23 +212,40 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char> static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT {return (unsigned char)__c1 < (unsigned char)__c2;} - static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int - compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { - if (__n == 0) - return 0; - return std::__constexpr_memcmp(__s1, __s2, __n); - } + // __constexpr_memcmp requires a trivially lexicographically comparable type, but char is not when char is a signed type + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int + compare(const char_type* __lhs, const char_type* __rhs, size_t __count) _NOEXCEPT { + if (__libcpp_is_constant_evaluated()) { +#ifdef _LIBCPP_COMPILER_CLANG_BASED + return __builtin_memcmp(__lhs, __rhs, __count); +#else + while (__count != 0) { + if (lt(*__lhs, *__rhs)) + return -1; + if (lt(*__rhs, *__lhs)) + return 1; - static inline _LIBCPP_HIDE_FROM_ABI size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s) _NOEXCEPT { - return std::__constexpr_strlen(__s); - } + __count -= sizeof(char_type); + ++__lhs; + ++__rhs; + } + return 0; +#endif // _LIBCPP_COMPILER_CLANG_BASED + } else { + return __builtin_memcmp(__lhs, __rhs, __count); + } + } - static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT { - if (__n == 0) - return nullptr; - return std::__constexpr_char_memchr(__s, static_cast<int>(__a), __n); - } + static inline _LIBCPP_HIDE_FROM_ABI size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s) _NOEXCEPT { + return std::__constexpr_strlen(__s); + } + + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT { + if (__n == 0) + return nullptr; + return std::__constexpr_char_memchr(__s, static_cast<int>(__a), __n); + } static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { |