diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm --- a/libcxx/include/algorithm +++ b/libcxx/include/algorithm @@ -2529,7 +2529,7 @@ // rotate_copy template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) { @@ -4394,6 +4394,7 @@ // merge template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator __merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) @@ -4417,7 +4418,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) @@ -4427,7 +4428,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/rotate_copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/rotate_copy.pass.cpp --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/rotate_copy.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/rotate_copy.pass.cpp @@ -18,139 +18,139 @@ #include "test_macros.h" #include "test_iterators.h" -// #if TEST_STD_VER > 17 -// TEST_CONSTEXPR bool test_constexpr() { -// int ia[] = {1, 3, 5, 2, 5, 6}; -// int ib[std::size(ia)] = {0}; -// -// const size_t N = 2; -// const auto middle = std::begin(ia) + N; -// auto it = std::rotate_copy(std::begin(ia), middle, std::end(ia), std::begin(ib)); -// -// return std::distance(std::begin(ib), it) == std::size(ia) -// && std::equal (std::begin(ia), middle, std::begin(ib) + std::size(ia) - N) -// && std::equal (middle, std::end(ia), std::begin(ib)) -// ; -// } -// #endif template -void -test() -{ - int ia[] = {0, 1, 2, 3}; - const unsigned sa = sizeof(ia)/sizeof(ia[0]); - int ib[sa] = {0}; - - OutIter r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia), OutIter(ib)); - assert(base(r) == ib); - - r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia+1), OutIter(ib)); - assert(base(r) == ib+1); - assert(ib[0] == 0); - - r = std::rotate_copy(InIter(ia), InIter(ia+1), InIter(ia+1), OutIter(ib)); - assert(base(r) == ib+1); - assert(ib[0] == 0); - - r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia+2), OutIter(ib)); - assert(base(r) == ib+2); - assert(ib[0] == 0); - assert(ib[1] == 1); - - r = std::rotate_copy(InIter(ia), InIter(ia+1), InIter(ia+2), OutIter(ib)); - assert(base(r) == ib+2); - assert(ib[0] == 1); - assert(ib[1] == 0); - - r = std::rotate_copy(InIter(ia), InIter(ia+2), InIter(ia+2), OutIter(ib)); - assert(base(r) == ib+2); - assert(ib[0] == 0); - assert(ib[1] == 1); - - r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia+3), OutIter(ib)); - assert(base(r) == ib+3); - assert(ib[0] == 0); - assert(ib[1] == 1); - assert(ib[2] == 2); - - r = std::rotate_copy(InIter(ia), InIter(ia+1), InIter(ia+3), OutIter(ib)); - assert(base(r) == ib+3); - assert(ib[0] == 1); - assert(ib[1] == 2); - assert(ib[2] == 0); - - r = std::rotate_copy(InIter(ia), InIter(ia+2), InIter(ia+3), OutIter(ib)); - assert(base(r) == ib+3); - assert(ib[0] == 2); - assert(ib[1] == 0); - assert(ib[2] == 1); - - r = std::rotate_copy(InIter(ia), InIter(ia+3), InIter(ia+3), OutIter(ib)); - assert(base(r) == ib+3); - assert(ib[0] == 0); - assert(ib[1] == 1); - assert(ib[2] == 2); - - r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia+4), OutIter(ib)); - assert(base(r) == ib+4); - assert(ib[0] == 0); - assert(ib[1] == 1); - assert(ib[2] == 2); - assert(ib[3] == 3); - - r = std::rotate_copy(InIter(ia), InIter(ia+1), InIter(ia+4), OutIter(ib)); - assert(base(r) == ib+4); - assert(ib[0] == 1); - assert(ib[1] == 2); - assert(ib[2] == 3); - assert(ib[3] == 0); - - r = std::rotate_copy(InIter(ia), InIter(ia+2), InIter(ia+4), OutIter(ib)); - assert(base(r) == ib+4); - assert(ib[0] == 2); - assert(ib[1] == 3); - assert(ib[2] == 0); - assert(ib[3] == 1); - - r = std::rotate_copy(InIter(ia), InIter(ia+3), InIter(ia+4), OutIter(ib)); - assert(base(r) == ib+4); - assert(ib[0] == 3); - assert(ib[1] == 0); - assert(ib[2] == 1); - assert(ib[3] == 2); - - r = std::rotate_copy(InIter(ia), InIter(ia+4), InIter(ia+4), OutIter(ib)); - assert(base(r) == ib+4); - assert(ib[0] == 0); - assert(ib[1] == 1); - assert(ib[2] == 2); - assert(ib[3] == 3); +TEST_CONSTEXPR_CXX20 void test() { + int ia[] = {0, 1, 2, 3}; + const unsigned sa = sizeof(ia) / sizeof(ia[0]); + int ib[sa] = {0}; + + OutIter r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia), OutIter(ib)); + assert(base(r) == ib); + + r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia + 1), OutIter(ib)); + assert(base(r) == ib + 1); + assert(ib[0] == 0); + + r = std::rotate_copy(InIter(ia), InIter(ia + 1), InIter(ia + 1), OutIter(ib)); + assert(base(r) == ib + 1); + assert(ib[0] == 0); + + r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia + 2), OutIter(ib)); + assert(base(r) == ib + 2); + assert(ib[0] == 0); + assert(ib[1] == 1); + + r = std::rotate_copy(InIter(ia), InIter(ia + 1), InIter(ia + 2), OutIter(ib)); + assert(base(r) == ib + 2); + assert(ib[0] == 1); + assert(ib[1] == 0); + + r = std::rotate_copy(InIter(ia), InIter(ia + 2), InIter(ia + 2), OutIter(ib)); + assert(base(r) == ib + 2); + assert(ib[0] == 0); + assert(ib[1] == 1); + + r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia + 3), OutIter(ib)); + assert(base(r) == ib + 3); + assert(ib[0] == 0); + assert(ib[1] == 1); + assert(ib[2] == 2); + + r = std::rotate_copy(InIter(ia), InIter(ia + 1), InIter(ia + 3), OutIter(ib)); + assert(base(r) == ib + 3); + assert(ib[0] == 1); + assert(ib[1] == 2); + assert(ib[2] == 0); + + r = std::rotate_copy(InIter(ia), InIter(ia + 2), InIter(ia + 3), OutIter(ib)); + assert(base(r) == ib + 3); + assert(ib[0] == 2); + assert(ib[1] == 0); + assert(ib[2] == 1); + + r = std::rotate_copy(InIter(ia), InIter(ia + 3), InIter(ia + 3), OutIter(ib)); + assert(base(r) == ib + 3); + assert(ib[0] == 0); + assert(ib[1] == 1); + assert(ib[2] == 2); + + r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia + 4), OutIter(ib)); + assert(base(r) == ib + 4); + assert(ib[0] == 0); + assert(ib[1] == 1); + assert(ib[2] == 2); + assert(ib[3] == 3); + + r = std::rotate_copy(InIter(ia), InIter(ia + 1), InIter(ia + 4), OutIter(ib)); + assert(base(r) == ib + 4); + assert(ib[0] == 1); + assert(ib[1] == 2); + assert(ib[2] == 3); + assert(ib[3] == 0); + + r = std::rotate_copy(InIter(ia), InIter(ia + 2), InIter(ia + 4), OutIter(ib)); + assert(base(r) == ib + 4); + assert(ib[0] == 2); + assert(ib[1] == 3); + assert(ib[2] == 0); + assert(ib[3] == 1); + + r = std::rotate_copy(InIter(ia), InIter(ia + 3), InIter(ia + 4), OutIter(ib)); + assert(base(r) == ib + 4); + assert(ib[0] == 3); + assert(ib[1] == 0); + assert(ib[2] == 1); + assert(ib[3] == 2); + + r = std::rotate_copy(InIter(ia), InIter(ia + 4), InIter(ia + 4), OutIter(ib)); + assert(base(r) == ib + 4); + assert(ib[0] == 0); + assert(ib[1] == 1); + assert(ib[2] == 2); + assert(ib[3] == 3); + + { + int ints[] = {1, 3, 5, 2, 5, 6}; + int const n_ints = sizeof(ints)/sizeof(int); + int zeros[n_ints] = {0}; + + const size_t N = 2; + const auto middle = std::begin(ints) + N; + auto it = std::rotate_copy(std::begin(ints), middle, std::end(ints), std::begin(zeros)); + assert(std::distance(std::begin(zeros), it) == n_ints); + assert(std::equal(std::begin(ints), middle, std::begin(zeros) + n_ints - N)); + assert(std::equal(middle, std::end(ints), std::begin(zeros))); + } +} + +TEST_CONSTEXPR_CXX20 bool all_tests() { + test, output_iterator >(); + test, forward_iterator >(); + test, bidirectional_iterator >(); + test, random_access_iterator >(); + test, int*>(); + + test, output_iterator >(); + test, forward_iterator >(); + test, bidirectional_iterator >(); + test, random_access_iterator >(); + test, int*>(); + + test >(); + test >(); + test >(); + test >(); + test(); + + return true; } -int main(int, char**) -{ - test, output_iterator >(); - test, forward_iterator >(); - test, bidirectional_iterator >(); - test, random_access_iterator >(); - test, int*>(); - - test, output_iterator >(); - test, forward_iterator >(); - test, bidirectional_iterator >(); - test, random_access_iterator >(); - test, int*>(); - - test >(); - test >(); - test >(); - test >(); - test(); - -// #if TEST_STD_VER > 17 -// static_assert(test_constexpr()); -// #endif +int main(int, char**) { + all_tests(); +#if TEST_STD_VER > 17 + static_assert(all_tests()); +#endif return 0; } diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.merge/merge.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.merge/merge.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.merge/merge.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.merge/merge.pass.cpp @@ -24,28 +24,26 @@ #include "test_macros.h" #include "test_iterators.h" - -// #if TEST_STD_VER > 17 -// TEST_CONSTEXPR bool test_constexpr() { -// int ia[] = {0, 1, 2, 3, 4}; -// int ib[] = {2, 4, 6, 8}; -// int ic[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -// const int expected[] = {0, 1, 2, 2, 3, 4, 4, 6, 8}; -// -// auto it = std::merge(std::begin(ia), std::end(ia), std::begin(ib), std::end(ib), std::begin(ic)); -// return std::distance(std::begin(ic), it) == (std::size(ia) + std::size(ib)) -// && *it == 0 -// && std::equal(std::begin(ic), it, std::begin(expected), std::end(expected)) -// ; -// } -// #endif +#if TEST_STD_VER > 17 +TEST_CONSTEXPR bool test_constexpr() { + int ia[] = {0, 1, 2, 3, 4}; + int ib[] = {2, 4, 6, 8}; + int ic[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + const int expected[] = {0, 1, 2, 2, 3, 4, 4, 6, 8}; + + auto it = std::merge(std::begin(ia), std::end(ia), std::begin(ib), + std::end(ib), std::begin(ic)); + assert(std::distance(std::begin(ic), it) == (std::size(ia) + std::size(ib))); + assert(*it == 0); + assert(std::equal(std::begin(ic), it, std::begin(expected), std::end(expected))); + return true; +} +#endif std::mt19937 randomness; template -void -test() -{ +void test() { { unsigned N = 100000; int* ia = new int[N]; @@ -242,9 +240,8 @@ test(); #if TEST_STD_VER > 17 -// Not yet - waiting on std::copy -// static_assert(test_constexpr()); + static_assert(test_constexpr()); #endif - return 0; + return 0; } diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.merge/merge_comp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.merge/merge_comp.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.merge/merge_comp.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.merge/merge_comp.pass.cpp @@ -28,22 +28,23 @@ #include "test_iterators.h" #include "counting_predicates.h" -// #if TEST_STD_VER > 17 -// TEST_CONSTEXPR bool test_constexpr() { -// int ia[] = {0, 1, 2, 3, 4}; -// int ib[] = {2, 4, 6, 8}; -// int ic[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -// const int expected[] = {0, 1, 2, 2, 3, 4, 4, 6, 8}; -// -// auto it = std::merge(std::begin(ia), std::end(ia), -// std::begin(ib), std::end(ib), -// std::begin(ic), [](int a, int b) {return a == b; }); -// return std::distance(std::begin(ic), it) == (std::size(ia) + std::size(ib)) -// && *it == 0 -// && std::equal(std::begin(ic), it, std::begin(expected), std::end(expected)) -// ; -// } -// #endif +#if TEST_STD_VER > 17 +TEST_CONSTEXPR bool test_constexpr() { + int ia[] = {0, 1, 2, 3, 4}; + int ib[] = {2, 4, 6, 8}; + int ic[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + const int expected[] = {0, 1, 2, 2, 3, 4, 4, 6, 8}; + + auto it = + std::merge(std::begin(ia), std::end(ia), std::begin(ib), std::end(ib), + std::begin(ic), [](int a, int b) { return a == b; }); + assert(std::distance(std::begin(ic), it) == (std::size(ia) + std::size(ib))); + assert(*it == 0); + assert( + std::equal(std::begin(ic), it, std::begin(expected), std::end(expected))); + return true; +} +#endif std::mt19937 randomness; @@ -253,8 +254,7 @@ test(); #if TEST_STD_VER > 17 -// Not yet - waiting on std::copy -// static_assert(test_constexpr()); + static_assert(test_constexpr()); #endif return 0; diff --git a/libcxx/www/cxx2a_status.html b/libcxx/www/cxx2a_status.html --- a/libcxx/www/cxx2a_status.html +++ b/libcxx/www/cxx2a_status.html @@ -261,7 +261,7 @@

The missing bits in P0600 are in [mem.res.class], [mem.poly.allocator.class], and [container.node.overview]

-

The missing bits in P0202 are in copy and copy_backwards (and the ones that call them: copy_n, rotate_copy, merge, set_union, set_difference, and set_symmetric_difference). This is because the first four algorithms have specializations that call memmove which is not constexpr. See Bug 25165

+

The missing bits in P0202 are in copy and copy_backwards (and the ones that call them: copy_n, set_union, set_difference, and set_symmetric_difference). This is because the first two algorithms have specializations that call memmove which is not constexpr. See Bug 25165

Library Working group Issues Status