diff --git a/libcxx/include/__string b/libcxx/include/__string --- a/libcxx/include/__string +++ b/libcxx/include/__string @@ -33,9 +33,10 @@ static constexpr size_t length(const char_type* s); static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); - static char_type* move(char_type* s1, const char_type* s2, size_t n); - static char_type* copy(char_type* s1, const char_type* s2, size_t n); - static char_type* assign(char_type* s, size_t n, char_type a); + + static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); // constexpr in C++20 + static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); // constexpr in C++20 + static constexpr char_type* assign(char_type* s, size_t n, char_type a); // constexpr in C++20 static constexpr int_type not_eof(int_type c) noexcept; static constexpr char_type to_char_type(int_type c) noexcept; @@ -93,11 +94,14 @@ size_t length(const char_type* __s); _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 const char_type* find(const char_type* __s, size_t __n, const char_type& __a); - static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); + static _LIBCPP_CONSTEXPR_AFTER_CXX17 + char_type* move(char_type* __s1, const char_type* __s2, size_t __n); _LIBCPP_INLINE_VISIBILITY - static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); + static _LIBCPP_CONSTEXPR_AFTER_CXX17 + char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); _LIBCPP_INLINE_VISIBILITY - static char_type* assign(char_type* __s, size_t __n, char_type __a); + static _LIBCPP_CONSTEXPR_AFTER_CXX17 + char_type* assign(char_type* __s, size_t __n, char_type __a); static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {return eq_int_type(__c, eof()) ? ~eof() : __c;} @@ -151,9 +155,10 @@ } template -_CharT* +_LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT* char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n) { + if (__n == 0) return __s1; char_type* __r = __s1; if (__s1 < __s2) { @@ -171,7 +176,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT* char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n) { @@ -183,7 +188,7 @@ } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT* char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) { @@ -193,6 +198,37 @@ return __r; } +// constexpr versions of move/copy/assign. + +template +static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED +_CharT* __move_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; +} + +template +static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED +_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT +{ + _VSTD::copy_n(__s2, __n, __s1); + return __s1; +} + +template +static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED +_CharT* __assign_constexpr(_CharT* __s, size_t __n, _CharT __a) _NOEXCEPT +{ + _VSTD::fill_n(__s, __n, __a); + return __s; +} + // char_traits template <> @@ -217,15 +253,28 @@ length(const char_type* __s) _NOEXCEPT {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 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT - {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);} - static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __move_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n); + } + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); + return __libcpp_is_constant_evaluated() + ? __copy_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); + } + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __assign_constexpr(__s, __n, __a) + : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n); } - static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT - {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);} static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {return eq_int_type(__c, eof()) ? ~eof() : __c;} @@ -307,16 +356,28 @@ size_t length(const char_type* __s) _NOEXCEPT; static _LIBCPP_CONSTEXPR_AFTER_CXX14 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; - static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT - {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);} - static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __move_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : wmemmove(__s1, __s2, __n); + } + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n); + return __libcpp_is_constant_evaluated() + ? __copy_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : wmemcpy(__s1, __s2, __n); + } + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __assign_constexpr(__s, __n, __a) + : __n == 0 ? __s : wmemset(__s, __a, __n); } - static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT - {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);} - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {return eq_int_type(__c, eof()) ? ~eof() : __c;} static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT @@ -428,17 +489,30 @@ _LIBCPP_INLINE_VISIBILITY static constexpr const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; - static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT - {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);} + static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __move_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n); + } - static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); - } + return __libcpp_is_constant_evaluated() + ? __copy_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); + } - static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT - {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);} + static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __assign_constexpr(__s, __n, __a) + : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n); + } static inline constexpr int_type not_eof(int_type __c) noexcept {return eq_int_type(__c, eof()) ? ~eof() : __c;} @@ -521,11 +595,11 @@ size_t length(const char_type* __s) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT; static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT @@ -577,10 +651,11 @@ return 0; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char16_t* char_traits::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { + if (__n == 0) return __s1; char_type* __r = __s1; if (__s1 < __s2) { @@ -597,7 +672,7 @@ return __r; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char16_t* char_traits::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { @@ -608,7 +683,7 @@ return __r; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char16_t* char_traits::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT { @@ -640,11 +715,11 @@ size_t length(const char_type* __s) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT; static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT @@ -696,10 +771,11 @@ return 0; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char32_t* char_traits::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { + if (__n == 0) return __s1; char_type* __r = __s1; if (__s1 < __s2) { @@ -716,7 +792,7 @@ return __r; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char32_t* char_traits::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { @@ -727,7 +803,7 @@ return __r; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char32_t* char_traits::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT { diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/assign3.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/assign3.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/assign3.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/assign3.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { char s2[3] = {0}; assert(std::char_traits::assign(s2, 3, char(5)) == s2); @@ -26,5 +26,16 @@ assert(s2[2] == char(5)); assert(std::char_traits::assign(NULL, 0, char(5)) == NULL); + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/copy.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/copy.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/copy.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/copy.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { char s1[] = {1, 2, 3}; char s2[3] = {0}; @@ -28,5 +28,16 @@ assert(std::char_traits::copy(NULL, s1, 0) == NULL); assert(std::char_traits::copy(s1, NULL, 0) == s1); + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/move.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/move.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/move.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/move.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { char s1[] = {1, 2, 3}; assert(std::char_traits::move(s1, s1+1, 2) == s1); @@ -32,5 +32,16 @@ assert(std::char_traits::move(NULL, s1, 0) == NULL); assert(std::char_traits::move(s1, NULL, 0) == s1); + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/assign3.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/assign3.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/assign3.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/assign3.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS char16_t s2[3] = {0}; @@ -28,5 +28,16 @@ assert(std::char_traits::assign(NULL, 0, char16_t(5)) == NULL); #endif // _LIBCPP_HAS_NO_UNICODE_CHARS + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/copy.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/copy.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/copy.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/copy.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS char16_t s1[] = {1, 2, 3}; @@ -30,5 +30,16 @@ assert(std::char_traits::copy(s1, NULL, 0) == s1); #endif // _LIBCPP_HAS_NO_UNICODE_CHARS + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/move.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/move.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/move.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/move.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS char16_t s1[] = {1, 2, 3}; @@ -34,5 +34,16 @@ assert(std::char_traits::move(s1, NULL, 0) == s1); #endif // _LIBCPP_HAS_NO_UNICODE_CHARS + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/assign3.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/assign3.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/assign3.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/assign3.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS char32_t s2[3] = {0}; @@ -28,5 +28,16 @@ assert(std::char_traits::assign(NULL, 0, char32_t(5)) == NULL); #endif // _LIBCPP_HAS_NO_UNICODE_CHARS + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/copy.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/copy.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/copy.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/copy.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS char32_t s1[] = {1, 2, 3}; @@ -30,5 +30,16 @@ assert(std::char_traits::copy(s1, NULL, 0) == s1); #endif // _LIBCPP_HAS_NO_UNICODE_CHARS + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/move.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/move.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/move.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/move.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS char32_t s1[] = {1, 2, 3}; @@ -34,5 +34,16 @@ assert(std::char_traits::move(s1, NULL, 0) == s1); #endif // _LIBCPP_HAS_NO_UNICODE_CHARS + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp @@ -18,7 +18,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { #if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L char8_t s2[3] = {0}; @@ -29,5 +29,16 @@ assert(std::char_traits::assign(NULL, 0, char8_t(5)) == NULL); #endif + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp @@ -18,7 +18,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { #if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L char8_t s1[] = {1, 2, 3}; @@ -31,5 +31,16 @@ assert(std::char_traits::copy(s1, NULL, 0) == s1); #endif + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp @@ -18,7 +18,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { #if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L char8_t s1[] = {1, 2, 3}; @@ -35,5 +35,16 @@ assert(std::char_traits::move(s1, NULL, 0) == s1); #endif + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/assign3.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/assign3.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/assign3.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/assign3.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { wchar_t s2[3] = {0}; assert(std::char_traits::assign(s2, 3, wchar_t(5)) == s2); @@ -26,5 +26,16 @@ assert(s2[2] == wchar_t(5)); assert(std::char_traits::assign(NULL, 0, wchar_t(5)) == NULL); + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/copy.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/copy.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/copy.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/copy.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { wchar_t s1[] = {1, 2, 3}; wchar_t s2[3] = {0}; @@ -28,5 +28,16 @@ assert(std::char_traits::copy(NULL, s1, 0) == NULL); assert(std::char_traits::copy(s1, NULL, 0) == s1); + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/move.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/move.pass.cpp --- a/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/move.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/move.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { wchar_t s1[] = {1, 2, 3}; assert(std::char_traits::move(s1, s1+1, 2) == s1); @@ -32,5 +32,16 @@ assert(std::char_traits::move(NULL, s1, 0) == NULL); assert(std::char_traits::move(s1, NULL, 0) == s1); + return true; +} + +int main(int, char**) +{ + test(); + +#if TEST_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) + static_assert(test()); +#endif + return 0; }