[libcxx-commits] [libcxx] eb8710c - [libc++][P0980] Marked member functions move/copy/assign of char_traits constexpr.

Michael Park via libcxx-commits libcxx-commits at lists.llvm.org
Mon Nov 11 09:50:09 PST 2019


Author: Michael Park
Date: 2019-11-11T09:49:48-08:00
New Revision: eb8710cb93a5c21c168ffd97ac2b6872127cb60b

URL: https://github.com/llvm/llvm-project/commit/eb8710cb93a5c21c168ffd97ac2b6872127cb60b
DIFF: https://github.com/llvm/llvm-project/commit/eb8710cb93a5c21c168ffd97ac2b6872127cb60b.diff

LOG: [libc++][P0980] Marked member functions move/copy/assign of char_traits constexpr.

Reviewers: ldionne, EricWF, mclow.lists

Reviewed By: ldionne

Subscribers: christof, dexonsmith, libcxx-commits

Tags: #libc

Differential Revision: https://reviews.llvm.org/D68840

Added: 
    

Modified: 
    libcxx/include/__string
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/assign3.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/copy.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/move.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/assign3.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/copy.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/move.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/assign3.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/copy.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/move.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/assign3.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/copy.pass.cpp
    libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.wchar.t/move.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__string b/libcxx/include/__string
index 70fd1cc3930d..056b9b80ea50 100644
--- a/libcxx/include/__string
+++ b/libcxx/include/__string
@@ -33,9 +33,10 @@ struct char_traits
     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 @@ struct _LIBCPP_TEMPLATE_VIS char_traits
     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 @@ char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a
 }
 
 template <class _CharT>
-_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 @@ char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
 }
 
 template <class _CharT>
-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 @@ char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
 }
 
 template <class _CharT>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 _CharT*
 char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
 {
@@ -193,6 +198,37 @@ char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
     return __r;
 }
 
+// constexpr versions of move/copy/assign.
+
+template <class _CharT>
+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 <class _CharT>
+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 <class _CharT>
+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<char>
 
 template <>
@@ -217,15 +253,28 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char>
     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 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
     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 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
     _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 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
     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 @@ char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& _
     return 0;
 }
 
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 char16_t*
 char_traits<char16_t>::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 @@ char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n)
     return __r;
 }
 
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 char16_t*
 char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
 {
@@ -608,7 +683,7 @@ char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
     return __r;
 }
 
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 char16_t*
 char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
 {
@@ -640,11 +715,11 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
     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 @@ char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& _
     return 0;
 }
 
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 char32_t*
 char_traits<char32_t>::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 @@ char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n)
     return __r;
 }
 
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 char32_t*
 char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
 {
@@ -727,7 +803,7 @@ char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
     return __r;
 }
 
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 char32_t*
 char_traits<char32_t>::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
index cc10294b0140..d7a1753daf69 100644
--- 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<char>::assign(s2, 3, char(5)) == s2);
@@ -26,5 +26,16 @@ int main(int, char**)
     assert(s2[2] == char(5));
     assert(std::char_traits<char>::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
index 7e76c0bbd3db..3ac53897ebaa 100644
--- 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 @@ int main(int, char**)
     assert(std::char_traits<char>::copy(NULL, s1, 0) == NULL);
     assert(std::char_traits<char>::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
index 4a132649d503..94f10aab7717 100644
--- 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<char>::move(s1, s1+1, 2) == s1);
@@ -32,5 +32,16 @@ int main(int, char**)
     assert(std::char_traits<char>::move(NULL, s1, 0) == NULL);
     assert(std::char_traits<char>::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
index 77207826aabf..af61f97b30a4 100644
--- 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 @@ int main(int, char**)
     assert(std::char_traits<char16_t>::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
index bedc55db0ed3..5c70a7a21e50 100644
--- 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 @@ int main(int, char**)
     assert(std::char_traits<char16_t>::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
index f822437809f4..b058632a8f48 100644
--- 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 @@ int main(int, char**)
     assert(std::char_traits<char16_t>::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
index c63d02543858..b022b23aa0ee 100644
--- 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 @@ int main(int, char**)
     assert(std::char_traits<char32_t>::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
index 7f9b383b0879..75e17d082f0e 100644
--- 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 @@ int main(int, char**)
     assert(std::char_traits<char32_t>::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
index 6d335fa3c101..499009938515 100644
--- 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 @@ int main(int, char**)
     assert(std::char_traits<char32_t>::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
index 426ca075dce7..d91f05a01fa7 100644
--- 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 @@ int main(int, char**)
     assert(std::char_traits<char8_t>::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
index bfd25c93c44f..4d9dc924f06d 100644
--- 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 @@ int main(int, char**)
     assert(std::char_traits<char8_t>::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
index ffb81fd30f10..b839b29cc576 100644
--- 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 @@ int main(int, char**)
     assert(std::char_traits<char8_t>::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
index 373d374b33d5..9997770e1ab1 100644
--- 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<wchar_t>::assign(s2, 3, wchar_t(5)) == s2);
@@ -26,5 +26,16 @@ int main(int, char**)
     assert(s2[2] == wchar_t(5));
     assert(std::char_traits<wchar_t>::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
index 3665297cd166..1eb2bd51320f 100644
--- 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 @@ int main(int, char**)
     assert(std::char_traits<wchar_t>::copy(NULL, s1, 0) == NULL);
     assert(std::char_traits<wchar_t>::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
index 67610cb141be..f459f287ce6f 100644
--- 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<wchar_t>::move(s1, s1+1, 2) == s1);
@@ -32,5 +32,16 @@ int main(int, char**)
     assert(std::char_traits<wchar_t>::move(NULL, s1, 0) == NULL);
     assert(std::char_traits<wchar_t>::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;
 }


        


More information about the libcxx-commits mailing list