[libcxx-commits] [libcxx] 13c90a5 - [libc++][P0202] Marked algorithms copy/copy_n/copy_if/copy_backward constexpr

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Nov 6 04:03:28 PST 2019


Author: Louis Dionne
Date: 2019-11-06T12:02:41Z
New Revision: 13c90a57165be999c505cfcfaf38755ed518b103

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

LOG: [libc++][P0202] Marked algorithms copy/copy_n/copy_if/copy_backward constexpr

Thanks to Michael Park for the patch.

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

Added: 
    

Modified: 
    libcxx/include/algorithm
    libcxx/include/iterator
    libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp
    libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp
    libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp
    libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp
    libcxx/test/support/test_iterators.h
    libcxx/test/support/test_macros.h
    libcxx/test/support/user_defined_integral.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index 55ea5eb2cc02..419ec2ce5776 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -167,20 +167,20 @@ template <class ForwardIterator, class Size, class T, class BinaryPredicate>
              Size count, const T& value, BinaryPredicate pred);
 
 template <class InputIterator, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     copy(InputIterator first, InputIterator last, OutputIterator result);
 
 template<class InputIterator, class OutputIterator, class Predicate>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     copy_if(InputIterator first, InputIterator last,
             OutputIterator result, Predicate pred);
 
 template<class InputIterator, class Size, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     copy_n(InputIterator first, Size n, OutputIterator result);
 
 template <class BidirectionalIterator1, class BidirectionalIterator2>
-    BidirectionalIterator2
+    constexpr BidirectionalIterator2      // constexpr in C++20
     copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,
                   BidirectionalIterator2 result);
 
@@ -1631,7 +1631,7 @@ search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const
 
 // copy
 template <class _Iter>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _Iter
 __unwrap_iter(_Iter __i)
 {
@@ -1639,7 +1639,7 @@ __unwrap_iter(_Iter __i)
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename enable_if
 <
     is_trivially_copy_assignable<_Tp>::value,
@@ -1693,15 +1693,23 @@ __unwrap_iter(__wrap_iter<_Tp*> __i)
 #endif  // _LIBCPP_DEBUG_LEVEL < 2
 
 template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
-__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+__copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
 {
     for (; __first != __last; ++__first, (void) ++__result)
         *__result = *__first;
     return __result;
 }
 
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    return __copy_constexpr(__first, __last, __result);
+}
+
 template <class _Tp, class _Up>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
@@ -1719,25 +1727,39 @@ __copy(_Tp* __first, _Tp* __last, _Up* __result)
 }
 
 template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
 copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
 {
-    return _VSTD::__copy(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
+    if (__libcpp_is_constant_evaluated()) {
+        return _VSTD::__copy_constexpr(
+            __unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
+    } else {
+        return _VSTD::__copy(
+            __unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
+    }
 }
 
 // copy_backward
 
 template <class _BidirectionalIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
-__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
+__copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
 {
     while (__first != __last)
         *--__result = *--__last;
     return __result;
 }
 
+template <class _BidirectionalIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
+{
+    return __copy_backward_constexpr(__first, __last, __result);
+}
+
 template <class _Tp, class _Up>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
@@ -1758,20 +1780,26 @@ __copy_backward(_Tp* __first, _Tp* __last, _Up* __result)
 }
 
 template <class _BidirectionalIterator1, class _BidirectionalIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _BidirectionalIterator2
 copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
               _BidirectionalIterator2 __result)
 {
-    return _VSTD::__copy_backward(__unwrap_iter(__first),
-                                  __unwrap_iter(__last),
-                                  __unwrap_iter(__result));
+    if (__libcpp_is_constant_evaluated()) {
+        return _VSTD::__copy_backward_constexpr(__unwrap_iter(__first),
+                                                __unwrap_iter(__last),
+                                                __unwrap_iter(__result));
+    } else {
+        return _VSTD::__copy_backward(__unwrap_iter(__first),
+                                      __unwrap_iter(__last),
+                                      __unwrap_iter(__result));
+    }
 }
 
 // copy_if
 
 template<class _InputIterator, class _OutputIterator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
 copy_if(_InputIterator __first, _InputIterator __last,
         _OutputIterator __result, _Predicate __pred)
@@ -1790,7 +1818,7 @@ copy_if(_InputIterator __first, _InputIterator __last,
 // copy_n
 
 template<class _InputIterator, class _Size, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename enable_if
 <
     __is_input_iterator<_InputIterator>::value &&
@@ -1816,7 +1844,7 @@ copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
 }
 
 template<class _InputIterator, class _Size, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename enable_if
 <
     __is_random_access_iterator<_InputIterator>::value,

diff  --git a/libcxx/include/iterator b/libcxx/include/iterator
index 30801ea83dbd..c5c0f669ee83 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -1304,8 +1304,8 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 __wrap_iter<_Iter>
 operator+(typename __wrap_iter<_Iter>::
diff erence_type, __wrap_iter<_Iter>) _NOEXCEPT;
 
-template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY copy(_Ip, _Ip, _Op);
-template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY copy_backward(_B1, _B1, _B2);
+template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy(_Ip, _Ip, _Op);
+template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy_backward(_B1, _B1, _B2);
 template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY move(_Ip, _Ip, _Op);
 template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1, _B1, _B2);
 
@@ -1515,8 +1515,8 @@ private:
     __wrap_iter<_Iter1>
     operator+(typename __wrap_iter<_Iter1>::
diff erence_type, __wrap_iter<_Iter1>) _NOEXCEPT;
 
-    template <class _Ip, class _Op> friend _Op copy(_Ip, _Ip, _Op);
-    template <class _B1, class _B2> friend _B2 copy_backward(_B1, _B1, _B2);
+    template <class _Ip, class _Op> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _Op copy(_Ip, _Ip, _Op);
+    template <class _B1, class _B2> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _B2 copy_backward(_B1, _B1, _B2);
     template <class _Ip, class _Op> friend _Op move(_Ip, _Ip, _Op);
     template <class _B1, class _B2> friend _B2 move_backward(_B1, _B1, _B2);
 

diff  --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp
index 9dcace7a03d1..cc99859d8a74 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp
@@ -18,21 +18,9 @@
 #include "test_macros.h"
 #include "test_iterators.h"
 
-// #if TEST_STD_VER > 17
-// TEST_CONSTEXPR bool test_constexpr() {
-//     int ia[] = {1, 2, 3, 4, 5};
-//     int ic[] = {6, 6, 6, 6, 6, 6, 6};
-//
-//     auto p = std::copy(std::begin(ia), std::end(ia), std::begin(ic));
-//     return std::equal(std::begin(ia), std::end(ia), std::begin(ic), p)
-//         && std::all_of(p, std::end(ic), [](int a){return a == 6;})
-//         ;
-//     }
-// #endif
-
 template <class InIter, class OutIter>
-void
-test()
+TEST_CONSTEXPR_CXX20 void
+test_copy()
 {
     const unsigned N = 1000;
     int ia[N];
@@ -46,46 +34,54 @@ test()
         assert(ia[i] == ib[i]);
 }
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
 {
-    test<input_iterator<const int*>, output_iterator<int*> >();
-    test<input_iterator<const int*>, input_iterator<int*> >();
-    test<input_iterator<const int*>, forward_iterator<int*> >();
-    test<input_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<input_iterator<const int*>, random_access_iterator<int*> >();
-    test<input_iterator<const int*>, int*>();
+    test_copy<input_iterator<const int*>, output_iterator<int*> >();
+    test_copy<input_iterator<const int*>, input_iterator<int*> >();
+    test_copy<input_iterator<const int*>, forward_iterator<int*> >();
+    test_copy<input_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy<input_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy<input_iterator<const int*>, int*>();
 
-    test<forward_iterator<const int*>, output_iterator<int*> >();
-    test<forward_iterator<const int*>, input_iterator<int*> >();
-    test<forward_iterator<const int*>, forward_iterator<int*> >();
-    test<forward_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<forward_iterator<const int*>, random_access_iterator<int*> >();
-    test<forward_iterator<const int*>, int*>();
+    test_copy<forward_iterator<const int*>, output_iterator<int*> >();
+    test_copy<forward_iterator<const int*>, input_iterator<int*> >();
+    test_copy<forward_iterator<const int*>, forward_iterator<int*> >();
+    test_copy<forward_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy<forward_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy<forward_iterator<const int*>, int*>();
 
-    test<bidirectional_iterator<const int*>, output_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, input_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, forward_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, int*>();
+    test_copy<bidirectional_iterator<const int*>, output_iterator<int*> >();
+    test_copy<bidirectional_iterator<const int*>, input_iterator<int*> >();
+    test_copy<bidirectional_iterator<const int*>, forward_iterator<int*> >();
+    test_copy<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy<bidirectional_iterator<const int*>, int*>();
 
-    test<random_access_iterator<const int*>, output_iterator<int*> >();
-    test<random_access_iterator<const int*>, input_iterator<int*> >();
-    test<random_access_iterator<const int*>, forward_iterator<int*> >();
-    test<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<random_access_iterator<const int*>, random_access_iterator<int*> >();
-    test<random_access_iterator<const int*>, int*>();
+    test_copy<random_access_iterator<const int*>, output_iterator<int*> >();
+    test_copy<random_access_iterator<const int*>, input_iterator<int*> >();
+    test_copy<random_access_iterator<const int*>, forward_iterator<int*> >();
+    test_copy<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy<random_access_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy<random_access_iterator<const int*>, int*>();
 
-    test<const int*, output_iterator<int*> >();
-    test<const int*, input_iterator<int*> >();
-    test<const int*, forward_iterator<int*> >();
-    test<const int*, bidirectional_iterator<int*> >();
-    test<const int*, random_access_iterator<int*> >();
-    test<const int*, int*>();
+    test_copy<const int*, output_iterator<int*> >();
+    test_copy<const int*, input_iterator<int*> >();
+    test_copy<const int*, forward_iterator<int*> >();
+    test_copy<const int*, bidirectional_iterator<int*> >();
+    test_copy<const int*, random_access_iterator<int*> >();
+    test_copy<const int*, int*>();
+
+  return true;
+}
+
+int main(int, char**)
+{
+    test();
 
-// #if TEST_STD_VER > 17
-//     static_assert(test_constexpr());
-// #endif
+#if TEST_STD_VER > 17
+    static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp
index 2f012d572527..0678257b4f61 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp
@@ -20,22 +20,9 @@
 #include "test_iterators.h"
 #include "user_defined_integral.h"
 
-// #if TEST_STD_VER > 17
-// TEST_CONSTEXPR bool test_constexpr() {
-//     int ia[] = {1, 2, 3, 4, 5};
-//     int ic[] = {6, 6, 6, 6, 6, 6, 6};
-//
-//     size_t N = std::size(ia);
-//     auto p = std::copy_backward(std::begin(ia), std::end(ia), std::begin(ic) + N);
-//     return std::equal(std::begin(ic), p, std::begin(ia))
-//         && std::all_of(p, std::end(ic), [](int a){return a == 6;})
-//         ;
-//     }
-// #endif
-
 template <class InIter, class OutIter>
-void
-test()
+TEST_CONSTEXPR_CXX20 void
+test_copy_backward()
 {
     const unsigned N = 1000;
     int ia[N];
@@ -49,23 +36,31 @@ test()
         assert(ia[i] == ib[i]);
 }
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
 {
-    test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, int*>();
+    test_copy_backward<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy_backward<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy_backward<bidirectional_iterator<const int*>, int*>();
 
-    test<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<random_access_iterator<const int*>, random_access_iterator<int*> >();
-    test<random_access_iterator<const int*>, int*>();
+    test_copy_backward<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy_backward<random_access_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy_backward<random_access_iterator<const int*>, int*>();
 
-    test<const int*, bidirectional_iterator<int*> >();
-    test<const int*, random_access_iterator<int*> >();
-    test<const int*, int*>();
+    test_copy_backward<const int*, bidirectional_iterator<int*> >();
+    test_copy_backward<const int*, random_access_iterator<int*> >();
+    test_copy_backward<const int*, int*>();
+
+    return true;
+}
+
+int main(int, char**)
+{
+    test();
 
-// #if TEST_STD_VER > 17
-//     static_assert(test_constexpr());
-// #endif
+#if TEST_STD_VER > 17
+    static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp
index 903bcbe6c250..407e18f2a9e7 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp
@@ -20,26 +20,14 @@
 #include "test_macros.h"
 #include "test_iterators.h"
 
-// #if TEST_STD_VER > 17
-// TEST_CONSTEXPR bool test_constexpr() {
-//     int ia[] = {2, 4, 6, 8, 6};
-//     int ic[] = {0, 0, 0, 0, 0, 0};
-//
-//     auto p = std::copy_if(std::begin(ia), std::end(ia), std::begin(ic), is6);
-//     return std::all_of(std::begin(ic), p, [](int a){return a == 6;})
-//         && std::all_of(p, std::end(ic),   [](int a){return a == 0;})
-//         ;
-//     }
-// #endif
-
 struct Pred
 {
-    bool operator()(int i) {return i % 3 == 0;}
+    TEST_CONSTEXPR_CXX14 bool operator()(int i) {return i % 3 == 0;}
 };
 
 template <class InIter, class OutIter>
-void
-test()
+TEST_CONSTEXPR_CXX20 void
+test_copy_if()
 {
     const unsigned N = 1000;
     int ia[N];
@@ -53,46 +41,54 @@ test()
         assert(ib[i] % 3 == 0);
 }
 
+TEST_CONSTEXPR_CXX20 bool
+test()
+{
+    test_copy_if<input_iterator<const int*>, output_iterator<int*> >();
+    test_copy_if<input_iterator<const int*>, input_iterator<int*> >();
+    test_copy_if<input_iterator<const int*>, forward_iterator<int*> >();
+    test_copy_if<input_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy_if<input_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy_if<input_iterator<const int*>, int*>();
+
+    test_copy_if<forward_iterator<const int*>, output_iterator<int*> >();
+    test_copy_if<forward_iterator<const int*>, input_iterator<int*> >();
+    test_copy_if<forward_iterator<const int*>, forward_iterator<int*> >();
+    test_copy_if<forward_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy_if<forward_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy_if<forward_iterator<const int*>, int*>();
+
+    test_copy_if<bidirectional_iterator<const int*>, output_iterator<int*> >();
+    test_copy_if<bidirectional_iterator<const int*>, input_iterator<int*> >();
+    test_copy_if<bidirectional_iterator<const int*>, forward_iterator<int*> >();
+    test_copy_if<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy_if<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy_if<bidirectional_iterator<const int*>, int*>();
+
+    test_copy_if<random_access_iterator<const int*>, output_iterator<int*> >();
+    test_copy_if<random_access_iterator<const int*>, input_iterator<int*> >();
+    test_copy_if<random_access_iterator<const int*>, forward_iterator<int*> >();
+    test_copy_if<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy_if<random_access_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy_if<random_access_iterator<const int*>, int*>();
+
+    test_copy_if<const int*, output_iterator<int*> >();
+    test_copy_if<const int*, input_iterator<int*> >();
+    test_copy_if<const int*, forward_iterator<int*> >();
+    test_copy_if<const int*, bidirectional_iterator<int*> >();
+    test_copy_if<const int*, random_access_iterator<int*> >();
+    test_copy_if<const int*, int*>();
+
+  return true;
+}
+
 int main(int, char**)
 {
-    test<input_iterator<const int*>, output_iterator<int*> >();
-    test<input_iterator<const int*>, input_iterator<int*> >();
-    test<input_iterator<const int*>, forward_iterator<int*> >();
-    test<input_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<input_iterator<const int*>, random_access_iterator<int*> >();
-    test<input_iterator<const int*>, int*>();
-
-    test<forward_iterator<const int*>, output_iterator<int*> >();
-    test<forward_iterator<const int*>, input_iterator<int*> >();
-    test<forward_iterator<const int*>, forward_iterator<int*> >();
-    test<forward_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<forward_iterator<const int*>, random_access_iterator<int*> >();
-    test<forward_iterator<const int*>, int*>();
-
-    test<bidirectional_iterator<const int*>, output_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, input_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, forward_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, int*>();
-
-    test<random_access_iterator<const int*>, output_iterator<int*> >();
-    test<random_access_iterator<const int*>, input_iterator<int*> >();
-    test<random_access_iterator<const int*>, forward_iterator<int*> >();
-    test<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<random_access_iterator<const int*>, random_access_iterator<int*> >();
-    test<random_access_iterator<const int*>, int*>();
-
-    test<const int*, output_iterator<int*> >();
-    test<const int*, input_iterator<int*> >();
-    test<const int*, forward_iterator<int*> >();
-    test<const int*, bidirectional_iterator<int*> >();
-    test<const int*, random_access_iterator<int*> >();
-    test<const int*, int*>();
-
-// #if TEST_STD_VER > 17
-//     static_assert(test_constexpr());
-// #endif
+    test();
+
+#if TEST_STD_VER > 17
+    static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp
index 027dedcdc9b5..179e4f1bb340 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp
@@ -19,23 +19,11 @@
 #include "test_iterators.h"
 #include "user_defined_integral.h"
 
-// #if TEST_STD_VER > 17
-// TEST_CONSTEXPR bool test_constexpr() {
-//     int ia[] = {1, 2, 3, 4, 5};
-//     int ic[] = {6, 6, 6, 6, 6, 6, 6};
-//
-//     auto p = std::copy_n(std::begin(ia), 4, std::begin(ic));
-//     return std::equal(std::begin(ic), p, std::begin(ia))
-//         && std::all_of(p, std::end(ic), [](int a){return a == 6;})
-//         ;
-//     }
-// #endif
-
 typedef UserDefinedIntegral<unsigned> UDI;
 
 template <class InIter, class OutIter>
-void
-test()
+TEST_CONSTEXPR_CXX20 void
+test_copy_n()
 {
     const unsigned N = 1000;
     int ia[N];
@@ -49,46 +37,54 @@ test()
         assert(ia[i] == ib[i]);
 }
 
+TEST_CONSTEXPR_CXX20 bool
+test()
+{
+    test_copy_n<input_iterator<const int*>, output_iterator<int*> >();
+    test_copy_n<input_iterator<const int*>, input_iterator<int*> >();
+    test_copy_n<input_iterator<const int*>, forward_iterator<int*> >();
+    test_copy_n<input_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy_n<input_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy_n<input_iterator<const int*>, int*>();
+
+    test_copy_n<forward_iterator<const int*>, output_iterator<int*> >();
+    test_copy_n<forward_iterator<const int*>, input_iterator<int*> >();
+    test_copy_n<forward_iterator<const int*>, forward_iterator<int*> >();
+    test_copy_n<forward_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy_n<forward_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy_n<forward_iterator<const int*>, int*>();
+
+    test_copy_n<bidirectional_iterator<const int*>, output_iterator<int*> >();
+    test_copy_n<bidirectional_iterator<const int*>, input_iterator<int*> >();
+    test_copy_n<bidirectional_iterator<const int*>, forward_iterator<int*> >();
+    test_copy_n<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy_n<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy_n<bidirectional_iterator<const int*>, int*>();
+
+    test_copy_n<random_access_iterator<const int*>, output_iterator<int*> >();
+    test_copy_n<random_access_iterator<const int*>, input_iterator<int*> >();
+    test_copy_n<random_access_iterator<const int*>, forward_iterator<int*> >();
+    test_copy_n<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
+    test_copy_n<random_access_iterator<const int*>, random_access_iterator<int*> >();
+    test_copy_n<random_access_iterator<const int*>, int*>();
+
+    test_copy_n<const int*, output_iterator<int*> >();
+    test_copy_n<const int*, input_iterator<int*> >();
+    test_copy_n<const int*, forward_iterator<int*> >();
+    test_copy_n<const int*, bidirectional_iterator<int*> >();
+    test_copy_n<const int*, random_access_iterator<int*> >();
+    test_copy_n<const int*, int*>();
+
+  return true;
+}
+
 int main(int, char**)
 {
-    test<input_iterator<const int*>, output_iterator<int*> >();
-    test<input_iterator<const int*>, input_iterator<int*> >();
-    test<input_iterator<const int*>, forward_iterator<int*> >();
-    test<input_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<input_iterator<const int*>, random_access_iterator<int*> >();
-    test<input_iterator<const int*>, int*>();
-
-    test<forward_iterator<const int*>, output_iterator<int*> >();
-    test<forward_iterator<const int*>, input_iterator<int*> >();
-    test<forward_iterator<const int*>, forward_iterator<int*> >();
-    test<forward_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<forward_iterator<const int*>, random_access_iterator<int*> >();
-    test<forward_iterator<const int*>, int*>();
-
-    test<bidirectional_iterator<const int*>, output_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, input_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, forward_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
-    test<bidirectional_iterator<const int*>, int*>();
-
-    test<random_access_iterator<const int*>, output_iterator<int*> >();
-    test<random_access_iterator<const int*>, input_iterator<int*> >();
-    test<random_access_iterator<const int*>, forward_iterator<int*> >();
-    test<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
-    test<random_access_iterator<const int*>, random_access_iterator<int*> >();
-    test<random_access_iterator<const int*>, int*>();
-
-    test<const int*, output_iterator<int*> >();
-    test<const int*, input_iterator<int*> >();
-    test<const int*, forward_iterator<int*> >();
-    test<const int*, bidirectional_iterator<int*> >();
-    test<const int*, random_access_iterator<int*> >();
-    test<const int*, int*>();
-
-// #if TEST_STD_VER > 17
-//     static_assert(test_constexpr());
-// #endif
+    test();
+
+#if TEST_STD_VER > 17
+    static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
index a54787af1b63..bc07e20fbafe 100644
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -35,17 +35,17 @@ class output_iterator
     typedef It                                                 pointer;
     typedef typename std::iterator_traits<It>::reference       reference;
 
-    It base() const {return it_;}
+    TEST_CONSTEXPR_CXX14 It base() const {return it_;}
 
-    output_iterator () {}
-    explicit output_iterator(It it) : it_(it) {}
+    TEST_CONSTEXPR_CXX14 output_iterator () {}
+    explicit TEST_CONSTEXPR_CXX14 output_iterator(It it) : it_(it) {}
     template <class U>
-        output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
+        TEST_CONSTEXPR_CXX14 output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
 
-    reference operator*() const {return *it_;}
+    TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
 
-    output_iterator& operator++() {++it_; return *this;}
-    output_iterator operator++(int)
+    TEST_CONSTEXPR_CXX14 output_iterator& operator++() {++it_; return *this;}
+    TEST_CONSTEXPR_CXX14 output_iterator operator++(int)
         {output_iterator tmp(*this); ++(*this); return tmp;}
 
     template <class T>

diff  --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index 74253a2016ae..df480abbead4 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -125,6 +125,11 @@
 # else
 #   define TEST_THROW_SPEC(...) throw(__VA_ARGS__)
 # endif
+# if TEST_STD_VER > 17
+#   define TEST_CONSTEXPR_CXX20 constexpr
+# else
+#   define TEST_CONSTEXPR_CXX20
+# endif
 #else
 #if defined(TEST_COMPILER_CLANG)
 # define TEST_ALIGNOF(...) _Alignof(__VA_ARGS__)
@@ -134,6 +139,7 @@
 #define TEST_ALIGNAS(...) __attribute__((__aligned__(__VA_ARGS__)))
 #define TEST_CONSTEXPR
 #define TEST_CONSTEXPR_CXX14
+#define TEST_CONSTEXPR_CXX20
 #define TEST_NOEXCEPT throw()
 #define TEST_NOEXCEPT_FALSE
 #define TEST_NOEXCEPT_COND(...)

diff  --git a/libcxx/test/support/user_defined_integral.h b/libcxx/test/support/user_defined_integral.h
index e3d572417de5..9f9ff45296e6 100644
--- a/libcxx/test/support/user_defined_integral.h
+++ b/libcxx/test/support/user_defined_integral.h
@@ -8,12 +8,14 @@
 #ifndef SUPPORT_USER_DEFINED_INTEGRAL_H
 #define SUPPORT_USER_DEFINED_INTEGRAL_H
 
+#include "test_macros.h"
+
 template <class T>
 struct UserDefinedIntegral
 {
-    UserDefinedIntegral() : value(0) {}
-    UserDefinedIntegral(T v) : value(v) {}
-    operator T() const { return value; }
+    TEST_CONSTEXPR_CXX14 UserDefinedIntegral() : value(0) {}
+    TEST_CONSTEXPR_CXX14 UserDefinedIntegral(T v) : value(v) {}
+    TEST_CONSTEXPR_CXX14 operator T() const { return value; }
     T value;
 };
 


        


More information about the libcxx-commits mailing list