[libcxx-commits] [libcxx] b552a30 - [libc++] Finish implementing P0202R3
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Sep 14 14:03:25 PDT 2020
Author: Nicholas-Baron
Date: 2020-09-14T16:58:49-04:00
New Revision: b552a30283cea1e9d3f90aef3cdd2ac24c366062
URL: https://github.com/llvm/llvm-project/commit/b552a30283cea1e9d3f90aef3cdd2ac24c366062
DIFF: https://github.com/llvm/llvm-project/commit/b552a30283cea1e9d3f90aef3cdd2ac24c366062.diff
LOG: [libc++] Finish implementing P0202R3
cppreference lists the support for this paper as partial.
I found 4 functions which the paper marks as `constexpr`,
but did not use the appropriate macro.
Differential Revision: https://reviews.llvm.org/D84275
Added:
Modified:
libcxx/include/algorithm
libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/rotate_copy.pass.cpp
libcxx/test/std/algorithms/alg.sorting/alg.merge/merge.pass.cpp
libcxx/test/std/algorithms/alg.sorting/alg.merge/merge_comp.pass.cpp
libcxx/www/cxx2a_status.html
Removed:
################################################################################
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index 37f2b4dd7626..5d09b6c3c015 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -2529,7 +2529,7 @@ rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __l
// rotate_copy
template <class _ForwardIterator, class _OutputIterator>
-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 @@ binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
// merge
template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
_OutputIterator
__merge(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
@@ -4417,7 +4418,7 @@ __merge(_InputIterator1 __first1, _InputIterator1 __last1,
}
template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
-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 @@ merge(_InputIterator1 __first1, _InputIterator1 __last1,
}
template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
-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
index d66bf8caad6e..8acb1a129e38 100644
--- 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 <class InIter, class OutIter>
-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<bidirectional_iterator<const int*>, output_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*>, 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*, forward_iterator<int*> >();
+ test<const int*, bidirectional_iterator<int*> >();
+ test<const int*, random_access_iterator<int*> >();
+ test<const int*, int*>();
+
+ return true;
}
-int main(int, char**)
-{
- test<bidirectional_iterator<const int*>, output_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*>, 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*, 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
+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
index 6c6f0c46d446..167da9aa2ddd 100644
--- 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 <class InIter1, class InIter2, class OutIter>
-void
-test()
-{
+void test() {
{
unsigned N = 100000;
int* ia = new int[N];
@@ -242,9 +240,8 @@ int main(int, char**)
test<const int*, const int*, int*>();
#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
index afa7073581e5..8d2dbb726858 100644
--- 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 @@ int main(int, char**)
test<const int*, const int*, int*>();
#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
index c6ccd9681d75..88df02bcb117 100644
--- a/libcxx/www/cxx2a_status.html
+++ b/libcxx/www/cxx2a_status.html
@@ -261,7 +261,7 @@ <h3>Paper Status</h3>
<p>The missing bits in P0600 are in [mem.res.class], [mem.poly.allocator.class], and [container.node.overview]</p>
-<p>The missing bits in P0202 are in <tt>copy</tt> and <tt>copy_backwards</tt> (and the ones that call them: <tt>copy_n</tt>, <tt>rotate_copy</tt>, <tt>merge</tt>, <tt>set_union</tt>, <tt>set_
diff erence</tt>, and <tt>set_symmetric_
diff erence</tt>). This is because the first four algorithms have specializations that call <tt>memmove</tt> which is not constexpr. See <a href="https://bugs.llvm.org/show_bug.cgi?id=25165">Bug 25165</a></p>
+<p>The missing bits in P0202 are in <tt>copy</tt> and <tt>copy_backwards</tt> (and the ones that call them: <tt>copy_n</tt>, <tt>set_union</tt>, <tt>set_
diff erence</tt>, and <tt>set_symmetric_
diff erence</tt>). This is because the first two algorithms have specializations that call <tt>memmove</tt> which is not constexpr. See <a href="https://bugs.llvm.org/show_bug.cgi?id=25165">Bug 25165</a></p>
<h3>Library Working group Issues Status</h3>
More information about the libcxx-commits
mailing list