diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm --- a/libcxx/include/algorithm +++ b/libcxx/include/algorithm @@ -167,20 +167,20 @@ Size count, const T& value, BinaryPredicate pred); template - OutputIterator + constexpr OutputIterator // constexpr in C++20 copy(InputIterator first, InputIterator last, OutputIterator result); template - OutputIterator + constexpr OutputIterator // constexpr in C++20 copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); template - OutputIterator + constexpr OutputIterator // constexpr in C++20 copy_n(InputIterator first, Size n, OutputIterator result); template - BidirectionalIterator2 + constexpr BidirectionalIterator2 // constexpr in C++20 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result); @@ -1631,7 +1631,7 @@ // copy template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Iter __unwrap_iter(_Iter __i) { @@ -1639,7 +1639,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1693,17 +1693,25 @@ #endif // _LIBCPP_DEBUG_LEVEL < 2 template -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 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + return __copy_constexpr(__first, __last, __result); +} + template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if < is_same::type, _Up>::value && @@ -1719,27 +1727,43 @@ } template -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 -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 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, + _OutputIterator __result) +{ + return __copy_backward_constexpr(__first, __last, __result); +} + template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if < is_same::type, _Up>::value && @@ -1758,20 +1782,26 @@ } template -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 -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 +1820,7 @@ // copy_n template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if < __is_input_iterator<_InputIterator>::value && @@ -1816,7 +1846,7 @@ } template -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 --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -1304,8 +1304,8 @@ __wrap_iter<_Iter> operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT; -template _Op _LIBCPP_INLINE_VISIBILITY copy(_Ip, _Ip, _Op); -template _B2 _LIBCPP_INLINE_VISIBILITY copy_backward(_B1, _B1, _B2); +template _Op _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy(_Ip, _Ip, _Op); +template _B2 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy_backward(_B1, _B1, _B2); template _Op _LIBCPP_INLINE_VISIBILITY move(_Ip, _Ip, _Op); template _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1, _B1, _B2); @@ -1515,8 +1515,8 @@ __wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT; - template friend _Op copy(_Ip, _Ip, _Op); - template friend _B2 copy_backward(_B1, _B1, _B2); + template friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _Op copy(_Ip, _Ip, _Op); + template friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _B2 copy_backward(_B1, _B1, _B2); template friend _Op move(_Ip, _Ip, _Op); template 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 --- 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,17 +18,17 @@ #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 +#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 void @@ -83,9 +83,9 @@ test >(); test(); -// #if TEST_STD_VER > 17 -// static_assert(test_constexpr()); -// #endif +#if TEST_STD_VER > 17 + static_assert(test_constexpr()); +#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 --- 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,18 +20,19 @@ #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 +#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 p == std::begin(ic) && + std::equal(p, p + N, std::begin(ia)) && + std::all_of(p + N, std::end(ic), [](int a) { return a == 6; }); +} +#endif template void @@ -63,9 +64,9 @@ test >(); test(); -// #if TEST_STD_VER > 17 -// static_assert(test_constexpr()); -// #endif +#if TEST_STD_VER > 17 + static_assert(test_constexpr()); +#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 --- 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,17 +20,18 @@ #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 +#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 is6 = [](int a) { return a == 6; }; + + auto p = std::copy_if(std::begin(ia), std::end(ia), std::begin(ic), is6); + return std::all_of(std::begin(ic), p, is6) && + std::all_of(p, std::end(ic), [](int a) { return a == 0; }); +} +#endif struct Pred { @@ -90,9 +91,9 @@ test >(); test(); -// #if TEST_STD_VER > 17 -// static_assert(test_constexpr()); -// #endif +#if TEST_STD_VER > 17 + static_assert(test_constexpr()); +#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 --- 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,17 +19,17 @@ #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 +#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 UDI; @@ -86,9 +86,9 @@ test >(); test(); -// #if TEST_STD_VER > 17 -// static_assert(test_constexpr()); -// #endif +#if TEST_STD_VER > 17 + static_assert(test_constexpr()); +#endif return 0; }