[libcxx-commits] [libcxx] [libc++] Add missing iterator requirement checks in the PSTL (PR #88127)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Apr 9 08:00:36 PDT 2024
https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/88127
>From fedfb4f2e5fbca4611e11f3e2bcf416db7c78d24 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Fri, 5 Apr 2024 10:28:11 -0400
Subject: [PATCH 1/2] [libc++] Add missing iterator requirement checks in the
PSTL
Also add tests for those, and add a few missing requirements to
testing iterators in the test suite.
---
.../__algorithm/pstl_any_all_none_of.h | 6 +-
libcxx/include/__algorithm/pstl_copy.h | 13 ++
libcxx/include/__algorithm/pstl_count.h | 5 +
libcxx/include/__algorithm/pstl_equal.h | 9 +
libcxx/include/__algorithm/pstl_fill.h | 6 +-
libcxx/include/__algorithm/pstl_find.h | 6 +-
libcxx/include/__algorithm/pstl_for_each.h | 4 +-
libcxx/include/__algorithm/pstl_generate.h | 5 +-
.../include/__algorithm/pstl_is_partitioned.h | 2 +
libcxx/include/__algorithm/pstl_merge.h | 5 +
libcxx/include/__algorithm/pstl_move.h | 5 +
libcxx/include/__algorithm/pstl_replace.h | 13 ++
libcxx/include/__algorithm/pstl_rotate_copy.h | 5 +
libcxx/include/__algorithm/pstl_sort.h | 3 +
libcxx/include/__algorithm/pstl_stable_sort.h | 2 +
libcxx/include/__algorithm/pstl_transform.h | 16 +-
.../__iterator/cpp17_iterator_concepts.h | 38 ++--
libcxx/include/__numeric/pstl_reduce.h | 3 +
.../include/__numeric/pstl_transform_reduce.h | 6 +
.../cpp17_iterator_concepts.verify.cpp | 143 +++++++------
.../pstl.iterator-constraints.verify.cpp | 188 ++++++++++++++++++
libcxx/test/support/test_iterators.h | 18 +-
22 files changed, 399 insertions(+), 102 deletions(-)
create mode 100644 libcxx/test/std/algorithms/pstl.iterator-constraints.verify.cpp
diff --git a/libcxx/include/__algorithm/pstl_any_all_none_of.h b/libcxx/include/__algorithm/pstl_any_all_none_of.h
index 4b1e0e61b54218..911a7e42b3fa3f 100644
--- a/libcxx/include/__algorithm/pstl_any_all_none_of.h
+++ b/libcxx/include/__algorithm/pstl_any_all_none_of.h
@@ -60,7 +60,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "any_of requires a ForwardIterator");
auto __res = std::__any_of(__policy, std::move(__first), std::move(__last), std::move(__pred));
if (!__res)
std::__throw_bad_alloc();
@@ -99,7 +99,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "all_of requires a ForwardIterator");
auto __res = std::__all_of(__policy, std::move(__first), std::move(__last), std::move(__pred));
if (!__res)
std::__throw_bad_alloc();
@@ -136,7 +136,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "none_of requires a ForwardIterator");
auto __res = std::__none_of(__policy, std::move(__first), std::move(__last), std::move(__pred));
if (!__res)
std::__throw_bad_alloc();
diff --git a/libcxx/include/__algorithm/pstl_copy.h b/libcxx/include/__algorithm/pstl_copy.h
index 1069dcec0e117a..f35bb9713ef140 100644
--- a/libcxx/include/__algorithm/pstl_copy.h
+++ b/libcxx/include/__algorithm/pstl_copy.h
@@ -16,6 +16,7 @@
#include <__config>
#include <__functional/identity.h>
#include <__iterator/concepts.h>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_constant_evaluated.h>
#include <__type_traits/is_execution_policy.h>
@@ -67,6 +68,12 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
+ _ForwardIterator, "copy(first, last, result) requires [first, last) to be ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
+ _ForwardOutIterator, "copy(first, last, result) requires result to be a ForwardIterator");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
+ _ForwardOutIterator, decltype(*__first), "copy(first, last, result) requires result to be an OutputIterator");
auto __res = std::__copy(__policy, std::move(__first), std::move(__last), std::move(__result));
if (!__res)
std::__throw_bad_alloc();
@@ -106,6 +113,12 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __result) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
+ _ForwardIterator, "copy_n(first, n, result) requires first to be a ForwardIterator");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
+ _ForwardOutIterator, "copy_n(first, n, result) requires result to be a ForwardIterator");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
+ _ForwardOutIterator, decltype(*__first), "copy_n(first, n, result) requires result to be an OutputIterator");
auto __res = std::__copy_n(__policy, std::move(__first), std::move(__n), std::move(__result));
if (!__res)
std::__throw_bad_alloc();
diff --git a/libcxx/include/__algorithm/pstl_count.h b/libcxx/include/__algorithm/pstl_count.h
index 2781f6bfd3c9e0..6ff57cac334eb0 100644
--- a/libcxx/include/__algorithm/pstl_count.h
+++ b/libcxx/include/__algorithm/pstl_count.h
@@ -17,6 +17,7 @@
#include <__atomic/atomic.h>
#include <__config>
#include <__functional/operations.h>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__numeric/pstl_transform_reduce.h>
#include <__type_traits/enable_if.h>
@@ -70,6 +71,8 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
+ _ForwardIterator, "count_if(first, last, pred) requires [first, last) to be ForwardIterators");
auto __res = std::__count_if(__policy, std::move(__first), std::move(__last), std::move(__pred));
if (!__res)
std::__throw_bad_alloc();
@@ -106,6 +109,8 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
+ _ForwardIterator, "count(first, last, val) requires [first, last) to be ForwardIterators");
auto __res = std::__count(__policy, std::move(__first), std::move(__last), __value);
if (!__res)
std::__throw_bad_alloc();
diff --git a/libcxx/include/__algorithm/pstl_equal.h b/libcxx/include/__algorithm/pstl_equal.h
index d235c0f4f41972..0b38197d7f63df 100644
--- a/libcxx/include/__algorithm/pstl_equal.h
+++ b/libcxx/include/__algorithm/pstl_equal.h
@@ -13,6 +13,7 @@
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__functional/operations.h>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__numeric/pstl_transform_reduce.h>
#include <__utility/move.h>
@@ -74,6 +75,8 @@ equal(_ExecutionPolicy&& __policy,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_Pred __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
auto __res = std::__equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__pred));
if (!__res)
std::__throw_bad_alloc();
@@ -86,6 +89,8 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
_LIBCPP_HIDE_FROM_ABI bool
equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
return std::equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::equal_to{});
}
@@ -145,6 +150,8 @@ equal(_ExecutionPolicy&& __policy,
_ForwardIterator2 __first2,
_ForwardIterator2 __last2,
_Pred __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
auto __res = std::__equal(
__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__pred));
if (!__res)
@@ -162,6 +169,8 @@ equal(_ExecutionPolicy&& __policy,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_ForwardIterator2 __last2) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
return std::equal(
__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::equal_to{});
}
diff --git a/libcxx/include/__algorithm/pstl_fill.h b/libcxx/include/__algorithm/pstl_fill.h
index 488b49a0feec96..fd248506bc4b96 100644
--- a/libcxx/include/__algorithm/pstl_fill.h
+++ b/libcxx/include/__algorithm/pstl_fill.h
@@ -43,7 +43,6 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI optional<__empty>
__fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) noexcept {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill, _RawPolicy),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
@@ -63,7 +62,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "fill requires ForwardIterators");
if (!std::__fill(__policy, std::move(__first), std::move(__last), __value))
std::__throw_bad_alloc();
}
@@ -79,7 +78,6 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
__fill_n(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _SizeT&& __n, const _Tp& __value) noexcept {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n, _RawPolicy),
[&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) {
@@ -102,7 +100,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const _Tp& __value) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "fill_n requires ForwardIterators");
if (!std::__fill_n(__policy, std::move(__first), std::move(__n), __value))
std::__throw_bad_alloc();
}
diff --git a/libcxx/include/__algorithm/pstl_find.h b/libcxx/include/__algorithm/pstl_find.h
index 5b694db68aead4..3b30a7bc9b456f 100644
--- a/libcxx/include/__algorithm/pstl_find.h
+++ b/libcxx/include/__algorithm/pstl_find.h
@@ -50,7 +50,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
find_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if requires ForwardIterators");
auto __res = std::__find_if(__policy, std::move(__first), std::move(__last), std::move(__pred));
if (!__res)
std::__throw_bad_alloc();
@@ -88,7 +88,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if_not requires ForwardIterators");
auto __res = std::__find_if_not(__policy, std::move(__first), std::move(__last), std::move(__pred));
if (!__res)
std::__throw_bad_alloc();
@@ -125,7 +125,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find requires ForwardIterators");
auto __res = std::__find(__policy, std::move(__first), std::move(__last), __value);
if (!__res)
std::__throw_bad_alloc();
diff --git a/libcxx/include/__algorithm/pstl_for_each.h b/libcxx/include/__algorithm/pstl_for_each.h
index bb7b5a61a6dc0d..a9ebed74a62fd4 100644
--- a/libcxx/include/__algorithm/pstl_for_each.h
+++ b/libcxx/include/__algorithm/pstl_for_each.h
@@ -53,7 +53,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
for_each(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Function __func) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "for_each requires ForwardIterators");
if (!std::__for_each(__policy, std::move(__first), std::move(__last), std::move(__func)))
std::__throw_bad_alloc();
}
@@ -93,7 +93,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "for_each_n requires a ForwardIterator");
auto __res = std::__for_each_n(__policy, std::move(__first), std::move(__size), std::move(__func));
if (!__res)
std::__throw_bad_alloc();
diff --git a/libcxx/include/__algorithm/pstl_generate.h b/libcxx/include/__algorithm/pstl_generate.h
index 7133c6f4f4c621..886af290d7f25a 100644
--- a/libcxx/include/__algorithm/pstl_generate.h
+++ b/libcxx/include/__algorithm/pstl_generate.h
@@ -42,7 +42,6 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
__generate(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Generator&& __gen) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate, _RawPolicy),
[&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Generator __g_gen) {
@@ -63,7 +62,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "generate requires ForwardIterators");
if (!std::__generate(__policy, std::move(__first), std::move(__last), std::move(__gen)))
std::__throw_bad_alloc();
}
@@ -100,7 +99,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "generate_n requires a ForwardIterator");
if (!std::__generate_n(__policy, std::move(__first), std::move(__n), std::move(__gen)))
std::__throw_bad_alloc();
}
diff --git a/libcxx/include/__algorithm/pstl_is_partitioned.h b/libcxx/include/__algorithm/pstl_is_partitioned.h
index b6543021220727..108bb1e4325260 100644
--- a/libcxx/include/__algorithm/pstl_is_partitioned.h
+++ b/libcxx/include/__algorithm/pstl_is_partitioned.h
@@ -14,6 +14,7 @@
#include <__algorithm/pstl_find.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
@@ -62,6 +63,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "is_partitioned requires ForwardIterators");
auto __res = std::__is_partitioned(__policy, std::move(__first), std::move(__last), std::move(__pred));
if (!__res)
std::__throw_bad_alloc();
diff --git a/libcxx/include/__algorithm/pstl_merge.h b/libcxx/include/__algorithm/pstl_merge.h
index 3d262db6bc0c15..d03cd8c7fbd580 100644
--- a/libcxx/include/__algorithm/pstl_merge.h
+++ b/libcxx/include/__algorithm/pstl_merge.h
@@ -12,6 +12,7 @@
#include <__algorithm/pstl_backend.h>
#include <__config>
#include <__functional/operations.h>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
@@ -70,6 +71,10 @@ merge(_ExecutionPolicy&& __policy,
_ForwardIterator2 __last2,
_ForwardOutIterator __result,
_Comp __comp = {}) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "merge requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "merge requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1), "merge requires an OutputIterator");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2), "merge requires an OutputIterator");
auto __res = std::__merge(
__policy,
std::move(__first1),
diff --git a/libcxx/include/__algorithm/pstl_move.h b/libcxx/include/__algorithm/pstl_move.h
index d8441f1a6c2e16..f4c8c1fbb2e876 100644
--- a/libcxx/include/__algorithm/pstl_move.h
+++ b/libcxx/include/__algorithm/pstl_move.h
@@ -15,6 +15,7 @@
#include <__algorithm/pstl_transform.h>
#include <__config>
#include <__functional/identity.h>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_constant_evaluated.h>
@@ -69,6 +70,10 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
move(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "move requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "move requires an OutputIterator");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
+ _ForwardOutIterator, decltype(std::move(*__first)), "move requires an OutputIterator");
auto __res = std::__move(__policy, std::move(__first), std::move(__last), std::move(__result));
if (!__res)
std::__throw_bad_alloc();
diff --git a/libcxx/include/__algorithm/pstl_replace.h b/libcxx/include/__algorithm/pstl_replace.h
index b1caf3fd4ac0a1..73ac11cda26a9f 100644
--- a/libcxx/include/__algorithm/pstl_replace.h
+++ b/libcxx/include/__algorithm/pstl_replace.h
@@ -14,6 +14,7 @@
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__algorithm/pstl_transform.h>
#include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/remove_cvref.h>
@@ -74,6 +75,7 @@ replace_if(_ExecutionPolicy&& __policy,
_ForwardIterator __last,
_Pred __pred,
const _Tp& __new_value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_if requires ForwardIterators");
auto __res = std::__replace_if(__policy, std::move(__first), std::move(__last), std::move(__pred), __new_value);
if (!__res)
std::__throw_bad_alloc();
@@ -121,6 +123,7 @@ replace(_ExecutionPolicy&& __policy,
_ForwardIterator __last,
const _Tp& __old_value,
const _Tp& __new_value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace requires ForwardIterators");
if (!std::__replace(__policy, std::move(__first), std::move(__last), __old_value, __new_value))
std::__throw_bad_alloc();
}
@@ -177,6 +180,11 @@ _LIBCPP_HIDE_FROM_ABI void replace_copy_if(
_ForwardOutIterator __result,
_Pred __pred,
const _Tp& __new_value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_copy_if requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "replace_copy_if requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
+ _ForwardOutIterator, decltype(*__first), "replace_copy_if requires an OutputIterator");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, const _Tp&, "replace_copy requires an OutputIterator");
if (!std::__replace_copy_if(
__policy, std::move(__first), std::move(__last), std::move(__result), std::move(__pred), __new_value))
std::__throw_bad_alloc();
@@ -233,6 +241,11 @@ _LIBCPP_HIDE_FROM_ABI void replace_copy(
_ForwardOutIterator __result,
const _Tp& __old_value,
const _Tp& __new_value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_copy requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "replace_copy requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
+ _ForwardOutIterator, decltype(*__first), "replace_copy requires an OutputIterator");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, const _Tp&, "replace_copy requires an OutputIterator");
if (!std::__replace_copy(
__policy, std::move(__first), std::move(__last), std::move(__result), __old_value, __new_value))
std::__throw_bad_alloc();
diff --git a/libcxx/include/__algorithm/pstl_rotate_copy.h b/libcxx/include/__algorithm/pstl_rotate_copy.h
index 346aab1d4a55c0..adab3958fe3112 100644
--- a/libcxx/include/__algorithm/pstl_rotate_copy.h
+++ b/libcxx/include/__algorithm/pstl_rotate_copy.h
@@ -12,6 +12,7 @@
#include <__algorithm/pstl_backend.h>
#include <__algorithm/pstl_copy.h>
#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__type_traits/is_execution_policy.h>
#include <optional>
@@ -69,6 +70,10 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator rotate_copy(
_ForwardIterator __middle,
_ForwardIterator __last,
_ForwardOutIterator __result) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "rotate_copy requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "rotate_copy requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
+ _ForwardOutIterator, decltype(*__first), "rotate_copy requires an OutputIterator");
auto __res =
std::__rotate_copy(__policy, std::move(__first), std::move(__middle), std::move(__last), std::move(__result));
if (!__res)
diff --git a/libcxx/include/__algorithm/pstl_sort.h b/libcxx/include/__algorithm/pstl_sort.h
index a931f768111a23..65bc794ca6f4c8 100644
--- a/libcxx/include/__algorithm/pstl_sort.h
+++ b/libcxx/include/__algorithm/pstl_sort.h
@@ -14,6 +14,7 @@
#include <__algorithm/pstl_stable_sort.h>
#include <__config>
#include <__functional/operations.h>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/empty.h>
@@ -60,6 +61,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "sort requires RandomAccessIterators");
if (!std::__sort(__policy, std::move(__first), std::move(__last), std::move(__comp)))
std::__throw_bad_alloc();
}
@@ -70,6 +72,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "sort requires RandomAccessIterators");
std::sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
}
diff --git a/libcxx/include/__algorithm/pstl_stable_sort.h b/libcxx/include/__algorithm/pstl_stable_sort.h
index 8ea0bb3f9a8d59..79b94557e3dc3a 100644
--- a/libcxx/include/__algorithm/pstl_stable_sort.h
+++ b/libcxx/include/__algorithm/pstl_stable_sort.h
@@ -12,6 +12,7 @@
#include <__algorithm/pstl_backend.h>
#include <__config>
#include <__functional/operations.h>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
@@ -48,6 +49,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void stable_sort(
_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp = {}) {
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "stable_sort requires RandomAccessIterators");
if (!std::__stable_sort(__policy, std::move(__first), std::move(__last), std::move(__comp)))
std::__throw_bad_alloc();
}
diff --git a/libcxx/include/__algorithm/pstl_transform.h b/libcxx/include/__algorithm/pstl_transform.h
index f95938782fc3bd..a01a64a43cf1a3 100644
--- a/libcxx/include/__algorithm/pstl_transform.h
+++ b/libcxx/include/__algorithm/pstl_transform.h
@@ -58,9 +58,10 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
_ForwardIterator __last,
_ForwardOutIterator __result,
_UnaryOperation __op) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first)));
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "transform requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "transform requires an OutputIterator");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
+ _ForwardOutIterator, decltype(__op(*__first)), "transform requires an OutputIterator");
auto __res = std::__transform(__policy, std::move(__first), std::move(__last), std::move(__result), std::move(__op));
if (!__res)
std::__throw_bad_alloc();
@@ -100,10 +101,11 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
_ForwardIterator2 __first2,
_ForwardOutIterator __result,
_BinaryOperation __op) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first1, *__first2)));
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "transform requires an OutputIterator");
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
+ _ForwardOutIterator, decltype(__op(*__first1, *__first2)), "transform requires an OutputIterator");
auto __res = std::__transform(
__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__result), std::move(__op));
if (!__res)
diff --git a/libcxx/include/__iterator/cpp17_iterator_concepts.h b/libcxx/include/__iterator/cpp17_iterator_concepts.h
index cdb561e68452af..9d5a392582da42 100644
--- a/libcxx/include/__iterator/cpp17_iterator_concepts.h
+++ b/libcxx/include/__iterator/cpp17_iterator_concepts.h
@@ -157,29 +157,31 @@ concept __cpp17_random_access_iterator =
_LIBCPP_END_NAMESPACE_STD
# ifndef _LIBCPP_DISABLE_ITERATOR_CHECKS
-# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t) static_assert(::std::__cpp17_input_iterator<iter_t>);
-# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t) \
- static_assert(::std::__cpp17_output_iterator<iter_t, write_t>);
-# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t) static_assert(::std::__cpp17_forward_iterator<iter_t>);
-# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t) \
- static_assert(::std::__cpp17_bidirectional_iterator<iter_t>);
-# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t) \
- static_assert(::std::__cpp17_random_access_iterator<iter_t>);
+# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t, message) \
+ static_assert(::std::__cpp17_input_iterator<iter_t>, message)
+# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t, message) \
+ static_assert(::std::__cpp17_output_iterator<iter_t, write_t>, message)
+# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t, message) \
+ static_assert(::std::__cpp17_forward_iterator<iter_t>, message)
+# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t, message) \
+ static_assert(::std::__cpp17_bidirectional_iterator<iter_t>, message)
+# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t, message) \
+ static_assert(::std::__cpp17_random_access_iterator<iter_t>, message)
# else
-# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t)
-# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t)
-# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t)
-# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t)
-# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t)
+# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t, message) static_assert(true)
+# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t, message) static_assert(true)
+# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t, message) static_assert(true)
+# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t, message) static_assert(true)
+# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t, message) static_assert(true)
# endif
#else // _LIBCPP_STD_VER >= 20
-# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t)
-# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t)
-# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t)
-# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t)
-# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t)
+# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t, message) static_assert(true)
+# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t, message) static_assert(true)
+# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t, message) static_assert(true)
+# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t, message) static_assert(true)
+# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t, message) static_assert(true)
#endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__numeric/pstl_reduce.h b/libcxx/include/__numeric/pstl_reduce.h
index f9f666c2bb38b8..d678b9480070b0 100644
--- a/libcxx/include/__numeric/pstl_reduce.h
+++ b/libcxx/include/__numeric/pstl_reduce.h
@@ -12,6 +12,7 @@
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__functional/identity.h>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__numeric/pstl_transform_reduce.h>
#include <__type_traits/is_execution_policy.h>
@@ -66,6 +67,7 @@ reduce(_ExecutionPolicy&& __policy,
_ForwardIterator __last,
_Tp __init,
_BinaryOperation __op = {}) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "reduce requires ForwardIterators");
auto __res = std::__reduce(__policy, std::move(__first), std::move(__last), std::move(__init), std::move(__op));
if (!__res)
std::__throw_bad_alloc();
@@ -94,6 +96,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI __iter_value_type<_ForwardIterator>
reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "reduce requires ForwardIterators");
auto __res = std::__reduce(__policy, std::move(__first), std::move(__last));
if (!__res)
std::__throw_bad_alloc();
diff --git a/libcxx/include/__numeric/pstl_transform_reduce.h b/libcxx/include/__numeric/pstl_transform_reduce.h
index 07ecf0d9956bb0..2d2621dc8dadb1 100644
--- a/libcxx/include/__numeric/pstl_transform_reduce.h
+++ b/libcxx/include/__numeric/pstl_transform_reduce.h
@@ -13,6 +13,7 @@
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__functional/operations.h>
+#include <__iterator/cpp17_iterator_concepts.h>
#include <__numeric/transform_reduce.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/move.h>
@@ -72,6 +73,8 @@ _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
_Tp __init,
_BinaryOperation1 __reduce,
_BinaryOperation2 __transform) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform_reduce requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform_reduce requires ForwardIterators");
auto __res = std::__transform_reduce(
__policy,
std::move(__first1),
@@ -99,6 +102,8 @@ _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_Tp __init) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform_reduce requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform_reduce requires ForwardIterators");
return std::transform_reduce(__policy, __first1, __last1, __first2, __init, plus{}, multiplies{});
}
@@ -140,6 +145,7 @@ _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
_Tp __init,
_BinaryOperation __reduce,
_UnaryOperation __transform) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "transform_reduce requires ForwardIterators");
auto __res = std::__transform_reduce(
__policy, std::move(__first), std::move(__last), std::move(__init), std::move(__reduce), std::move(__transform));
if (!__res)
diff --git a/libcxx/test/libcxx/algorithms/cpp17_iterator_concepts.verify.cpp b/libcxx/test/libcxx/algorithms/cpp17_iterator_concepts.verify.cpp
index 344543d5f19ffe..78cc2f96d3273f 100644
--- a/libcxx/test/libcxx/algorithms/cpp17_iterator_concepts.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/cpp17_iterator_concepts.verify.cpp
@@ -16,29 +16,29 @@
#include <cstddef>
struct missing_deref {
- using difference_type = std::ptrdiff_t;
+ using difference_type = std::ptrdiff_t;
using iterator_category = std::input_iterator_tag;
- using value_type = int;
- using reference = int&;
+ using value_type = int;
+ using reference = int&;
missing_deref& operator++();
};
struct missing_preincrement {
- using difference_type = std::ptrdiff_t;
+ using difference_type = std::ptrdiff_t;
using iterator_category = std::input_iterator_tag;
- using value_type = int;
- using reference = int&;
+ using value_type = int;
+ using reference = int&;
int& operator*();
};
template <class Derived>
struct valid_iterator {
- using difference_type = std::ptrdiff_t;
+ using difference_type = std::ptrdiff_t;
using iterator_category = std::input_iterator_tag;
- using value_type = int;
- using reference = int&;
+ using value_type = int;
+ using reference = int&;
int& operator*() const;
Derived& operator++();
@@ -51,30 +51,30 @@ struct valid_iterator {
};
struct not_move_constructible : valid_iterator<not_move_constructible> {
- not_move_constructible(const not_move_constructible&) = default;
- not_move_constructible(not_move_constructible&&) = delete;
- not_move_constructible& operator=(not_move_constructible&&) = default;
+ not_move_constructible(const not_move_constructible&) = default;
+ not_move_constructible(not_move_constructible&&) = delete;
+ not_move_constructible& operator=(not_move_constructible&&) = default;
not_move_constructible& operator=(const not_move_constructible&) = default;
};
struct not_copy_constructible : valid_iterator<not_copy_constructible> {
- not_copy_constructible(const not_copy_constructible&) = delete;
- not_copy_constructible(not_copy_constructible&&) = default;
- not_copy_constructible& operator=(not_copy_constructible&&) = default;
+ not_copy_constructible(const not_copy_constructible&) = delete;
+ not_copy_constructible(not_copy_constructible&&) = default;
+ not_copy_constructible& operator=(not_copy_constructible&&) = default;
not_copy_constructible& operator=(const not_copy_constructible&) = default;
};
struct not_move_assignable : valid_iterator<not_move_assignable> {
- not_move_assignable(const not_move_assignable&) = default;
- not_move_assignable(not_move_assignable&&) = default;
- not_move_assignable& operator=(not_move_assignable&&) = delete;
+ not_move_assignable(const not_move_assignable&) = default;
+ not_move_assignable(not_move_assignable&&) = default;
+ not_move_assignable& operator=(not_move_assignable&&) = delete;
not_move_assignable& operator=(const not_move_assignable&) = default;
};
struct not_copy_assignable : valid_iterator<not_copy_assignable> {
- not_copy_assignable(const not_copy_assignable&) = default;
- not_copy_assignable(not_copy_assignable&&) = default;
- not_copy_assignable& operator=(not_copy_assignable&&) = default;
+ not_copy_assignable(const not_copy_assignable&) = default;
+ not_copy_assignable(not_copy_assignable&&) = default;
+ not_copy_assignable& operator=(not_copy_assignable&&) = default;
not_copy_assignable& operator=(const not_copy_assignable&) = delete;
};
@@ -89,7 +89,6 @@ void check_iterator_requirements() {
static_assert(std::__cpp17_iterator<missing_preincrement>); // expected-error {{static assertion failed}}
// expected-note@*:* {{cannot increment value of type 'missing_preincrement'}}
-
static_assert(std::__cpp17_iterator<not_move_constructible>); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'not_move_constructible' does not satisfy '__cpp17_move_constructible'}}
@@ -115,10 +114,10 @@ bool operator==(not_unequality_comparable, not_unequality_comparable);
bool operator!=(not_unequality_comparable, not_unequality_comparable) = delete;
void check_input_iterator_requirements() {
- _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(not_equality_comparable); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(not_equality_comparable, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{'__lhs == __rhs' would be invalid: overload resolution selected deleted operator '=='}}
- _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(not_unequality_comparable); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(not_unequality_comparable, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{'__lhs != __rhs' would be invalid: overload resolution selected deleted operator '!='}}
}
@@ -138,9 +137,9 @@ struct postincrement_not_ref : valid_iterator<postincrement_not_ref> {};
bool operator==(postincrement_not_ref, postincrement_not_ref);
void check_forward_iterator_requirements() {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(not_default_constructible); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(not_default_constructible, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'not_default_constructible' does not satisfy '__cpp17_default_constructible'}}
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(postincrement_not_ref); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(postincrement_not_ref, ""); // expected-error {{static assertion failed}}
#ifndef _AIX
// expected-note@*:* {{because type constraint 'convertible_to<valid_iterator<postincrement_not_ref>::Proxy, const postincrement_not_ref &>' was not satisfied}}
#endif
@@ -155,7 +154,6 @@ struct missing_postdecrement : valid_forward_iterator<missing_postdecrement> {
};
struct not_returning_iter_reference : valid_forward_iterator<not_returning_iter_reference> {
-
struct Proxy {
operator const not_returning_iter_reference&();
@@ -167,11 +165,12 @@ struct not_returning_iter_reference : valid_forward_iterator<not_returning_iter_
};
void check_bidirectional_iterator_requirements() {
- _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(missing_predecrement); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(missing_predecrement, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{cannot decrement value of type 'missing_predecrement'}}
- _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(missing_postdecrement); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(missing_postdecrement, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{cannot decrement value of type 'missing_postdecrement'}}
- _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(not_returning_iter_reference); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(
+ not_returning_iter_reference, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because type constraint 'same_as<int, __iter_reference<not_returning_iter_reference> >' was not satisfied}}
}
@@ -246,7 +245,8 @@ struct missing_minus_const_iter_const_iter : valid_random_access_iterator<missin
friend difference_type operator-(missing_minus_const_iter_const_iter&, missing_minus_const_iter_const_iter&);
friend difference_type operator-(const missing_minus_const_iter_const_iter&, missing_minus_const_iter_const_iter&);
friend difference_type operator-(missing_minus_const_iter_const_iter&, const missing_minus_const_iter_const_iter&);
- friend difference_type operator-(const missing_minus_const_iter_const_iter&, const missing_minus_const_iter_const_iter&) = delete;
+ friend difference_type
+ operator-(const missing_minus_const_iter_const_iter&, const missing_minus_const_iter_const_iter&) = delete;
};
struct missing_subscript_operator : valid_random_access_iterator<missing_subscript_operator> {
@@ -359,62 +359,85 @@ struct missing_const_const_greater_eq : valid_random_access_iterator<missing_con
};
void check_random_access_iterator() {
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_equals); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_equals, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter += __n' would be invalid: overload resolution selected deleted operator '+='}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_equals); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_equals, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter -= __n' would be invalid: overload resolution selected deleted operator '-='}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_iter_diff); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_plus_iter_diff, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter + __n' would be invalid: overload resolution selected deleted operator '+'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_diff_iter); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_plus_diff_iter, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__n + __iter' would be invalid: overload resolution selected deleted operator '+'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_iter_diff_const_mut); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_plus_iter_diff_const_mut, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) + __n' would be invalid: overload resolution selected deleted operator '+'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_iter_diff_mut_const); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_plus_iter_diff_mut_const, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__n + std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '+'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_iter_diff_const); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_minus_iter_diff_const, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) - __n' would be invalid: overload resolution selected deleted operator '-'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_iter_iter); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_minus_iter_iter, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter - __iter' would be invalid: overload resolution selected deleted operator '-'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_const_iter_iter); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_minus_const_iter_iter, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) - __iter' would be invalid: overload resolution selected deleted operator '-'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_iter_const_iter); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_minus_iter_const_iter, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter - std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '-'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_const_iter_const_iter); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_minus_const_iter_const_iter, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) - std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '-'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_subscript_operator); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_subscript_operator, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter[__n]' would be invalid: overload resolution selected deleted operator '[]'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_subscript_operator); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_const_subscript_operator, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter)[__n]' would be invalid: overload resolution selected deleted operator '[]'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_less); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_less, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter < __iter' would be invalid: overload resolution selected deleted operator '<'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_less); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_const_mut_less, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) < __iter' would be invalid: overload resolution selected deleted operator '<'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_less); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_mut_const_less, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter < std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_less); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_const_const_less, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) < std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_greater); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_greater, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter > __iter' would be invalid: overload resolution selected deleted operator '>'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_greater); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_const_mut_greater, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) > __iter' would be invalid: overload resolution selected deleted operator '>'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_greater); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_mut_const_greater, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter > std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_greater); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_const_const_greater, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) > std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>'}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_less_eq); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_less_eq, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter <= __iter' would be invalid: overload resolution selected deleted operator '<='}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_less_eq); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_const_mut_less_eq, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) <= __iter' would be invalid: overload resolution selected deleted operator '<='}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_less_eq); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_mut_const_less_eq, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter <= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<='}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_less_eq); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_const_const_less_eq, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) <= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<='}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_greater_eq); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_greater_eq, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter >= __iter' would be invalid: overload resolution selected deleted operator '>='}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_greater_eq); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_const_mut_greater_eq, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) >= __iter' would be invalid: overload resolution selected deleted operator '>='}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_greater_eq); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_mut_const_greater_eq, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because '__iter >= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>='}}
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_greater_eq); // expected-error {{static assertion failed}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(
+ missing_const_const_greater_eq, ""); // expected-error {{static assertion failed}}
// expected-note@*:* {{because 'std::as_const(__iter) >= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>='}}
}
diff --git a/libcxx/test/std/algorithms/pstl.iterator-constraints.verify.cpp b/libcxx/test/std/algorithms/pstl.iterator-constraints.verify.cpp
new file mode 100644
index 00000000000000..fa4f8d478a190c
--- /dev/null
+++ b/libcxx/test/std/algorithms/pstl.iterator-constraints.verify.cpp
@@ -0,0 +1,188 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: stdlib=libc++
+
+// <algorithm>
+// <numeric>
+
+// Make sure that all PSTL algorithms contain checks for iterator requirements.
+// This is not a requirement from the Standard, but we strive to catch misuse in
+// the PSTL both because we can, and because iterator category mistakes in the
+// PSTL can lead to subtle bugs.
+
+// Ignore spurious errors after the initial static_assert failure.
+// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error
+
+#include <algorithm>
+#include <cstddef>
+#include <numeric>
+
+#include "test_iterators.h"
+
+using non_forward_iterator = cpp17_input_iterator<int*>;
+struct non_output_iterator : forward_iterator<int*> {
+ constexpr int const& operator*() const; // prevent it from being an output iterator
+};
+
+void f(non_forward_iterator non_fwd, non_output_iterator non_output, std::execution::sequenced_policy pol) {
+ auto pred = [](auto&&...) -> bool { return true; };
+ auto func = [](auto&&...) -> int { return 1; };
+ int* it = nullptr;
+ int* out = nullptr;
+ std::size_t n = 0;
+ int val = 0;
+
+ {
+ (void)std::any_of(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: any_of}}
+ (void)std::all_of(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: all_of}}
+ (void)std::none_of(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: none_of}}
+ }
+
+ {
+ (void)std::copy(pol, non_fwd, non_fwd, it); // expected-error@*:* {{static assertion failed: copy}}
+ (void)std::copy(pol, it, it, non_fwd); // expected-error@*:* {{static assertion failed: copy}}
+ (void)std::copy(pol, it, it, non_output); // expected-error@*:* {{static assertion failed: copy}}
+ }
+ {
+ (void)std::copy_n(pol, non_fwd, n, it); // expected-error@*:* {{static assertion failed: copy_n}}
+ (void)std::copy_n(pol, it, n, non_fwd); // expected-error@*:* {{static assertion failed: copy_n}}
+ (void)std::copy_n(pol, it, n, non_output); // expected-error@*:* {{static assertion failed: copy_n}}
+ }
+
+ {
+ (void)std::count(pol, non_fwd, non_fwd, val); // expected-error@*:* {{static assertion failed: count}}
+ (void)std::count_if(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: count_if}}
+ }
+
+ {
+ (void)std::equal(pol, non_fwd, non_fwd, it); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, it, it, non_fwd); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, non_fwd, non_fwd, it, pred); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, it, it, non_fwd, pred); // expected-error@*:* {{static assertion failed: equal}}
+
+ (void)std::equal(pol, non_fwd, non_fwd, it, it); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, it, it, non_fwd, non_fwd); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, non_fwd, non_fwd, it, it, pred); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, it, it, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: equal}}
+ }
+
+ {
+ (void)std::fill(pol, non_fwd, non_fwd, val); // expected-error@*:* {{static assertion failed: fill}}
+ (void)std::fill_n(pol, non_fwd, n, val); // expected-error@*:* {{static assertion failed: fill_n}}
+ }
+
+ {
+ (void)std::find(pol, non_fwd, non_fwd, val); // expected-error@*:* {{static assertion failed: find}}
+ (void)std::find_if(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: find_if}}
+ (void)std::find_if_not(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: find_if_not}}
+ }
+
+ {
+ (void)std::for_each(pol, non_fwd, non_fwd, func); // expected-error@*:* {{static assertion failed: for_each}}
+ (void)std::for_each_n(pol, non_fwd, n, func); // expected-error@*:* {{static assertion failed: for_each_n}}
+ }
+
+ {
+ (void)std::generate(pol, non_fwd, non_fwd, func); // expected-error@*:* {{static assertion failed: generate}}
+ (void)std::generate_n(pol, non_fwd, n, func); // expected-error@*:* {{static assertion failed: generate_n}}
+ }
+
+ {
+ (void)std::is_partitioned(
+ pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: is_partitioned}}
+ }
+
+ {
+ (void)std::merge(pol, non_fwd, non_fwd, it, it, out); // expected-error@*:* {{static assertion failed: merge}}
+ (void)std::merge(pol, it, it, non_fwd, non_fwd, out); // expected-error@*:* {{static assertion failed: merge}}
+ (void)std::merge(pol, it, it, it, it, non_output); // expected-error@*:* {{static assertion failed: merge}}
+
+ (void)std::merge(pol, non_fwd, non_fwd, it, it, out, pred); // expected-error@*:* {{static assertion failed: merge}}
+ (void)std::merge(pol, it, it, non_fwd, non_fwd, out, pred); // expected-error@*:* {{static assertion failed: merge}}
+ (void)std::merge(pol, it, it, it, it, non_output, pred); // expected-error@*:* {{static assertion failed: merge}}
+ }
+
+ {
+ (void)std::move(pol, non_fwd, non_fwd, out); // expected-error@*:* {{static assertion failed: move}}
+ (void)std::move(pol, it, it, non_fwd); // expected-error@*:* {{static assertion failed: move}}
+ (void)std::move(pol, it, it, non_output); // expected-error@*:* {{static assertion failed: move}}
+ }
+
+ {
+ (void)std::replace_if(
+ pol, non_fwd, non_fwd, pred, val); // expected-error@*:* {{static assertion failed: replace_if}}
+ (void)std::replace(pol, non_fwd, non_fwd, val, val); // expected-error@*:* {{static assertion failed: replace}}
+
+ (void)std::replace_copy_if(
+ pol, non_fwd, non_fwd, out, pred, val); // expected-error@*:* {{static assertion failed: replace_copy_if}}
+ (void)std::replace_copy_if(
+ pol, it, it, non_fwd, pred, val); // expected-error@*:* {{static assertion failed: replace_copy_if}}
+ (void)std::replace_copy_if(
+ pol, it, it, non_output, pred, val); // expected-error@*:* {{static assertion failed: replace_copy_if}}
+
+ (void)std::replace_copy(
+ pol, non_fwd, non_fwd, out, val, val); // expected-error@*:* {{static assertion failed: replace_copy}}
+ (void)std::replace_copy(
+ pol, it, it, non_fwd, val, val); // expected-error@*:* {{static assertion failed: replace_copy}}
+ (void)std::replace_copy(
+ pol, it, it, non_output, val, val); // expected-error@*:* {{static assertion failed: replace_copy}}
+ }
+
+ {
+ (void)std::rotate_copy(
+ pol, non_fwd, non_fwd, non_fwd, out); // expected-error@*:* {{static assertion failed: rotate_copy}}
+ (void)std::rotate_copy(pol, it, it, it, non_fwd); // expected-error@*:* {{static assertion failed: rotate_copy}}
+ (void)std::rotate_copy(pol, it, it, it, non_output); // expected-error@*:* {{static assertion failed: rotate_copy}}
+ }
+
+ {
+ (void)std::sort(pol, non_fwd, non_fwd); // expected-error@*:* {{static assertion failed: sort}}
+ (void)std::sort(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: sort}}
+ }
+
+ {
+ (void)std::stable_sort(pol, non_fwd, non_fwd); // expected-error@*:* {{static assertion failed: stable_sort}}
+ (void)std::stable_sort(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: stable_sort}}
+ }
+
+ {
+ (void)std::transform(pol, non_fwd, non_fwd, out, func); // expected-error@*:* {{static assertion failed: transform}}
+ (void)std::transform(pol, it, it, non_fwd, func); // expected-error@*:* {{static assertion failed: transform}}
+ (void)std::transform(pol, it, it, non_output, func); // expected-error@*:* {{static assertion failed: transform}}
+
+ (void)std::transform(
+ pol, non_fwd, non_fwd, it, out, func); // expected-error@*:* {{static assertion failed: transform}}
+ (void)std::transform(pol, it, it, non_fwd, out, func); // expected-error@*:* {{static assertion failed: transform}}
+ (void)std::transform(pol, it, it, it, non_fwd, func); // expected-error@*:* {{static assertion failed: transform}}
+ (void)std::transform(
+ pol, it, it, it, non_output, func); // expected-error@*:* {{static assertion failed: transform}}
+ }
+
+ {
+ (void)std::reduce(pol, non_fwd, non_fwd); // expected-error@*:* {{static assertion failed: reduce}}
+ (void)std::reduce(pol, non_fwd, non_fwd, val); // expected-error@*:* {{static assertion failed: reduce}}
+ (void)std::reduce(pol, non_fwd, non_fwd, val, func); // expected-error@*:* {{static assertion failed: reduce}}
+ }
+
+ {
+ (void)std::transform_reduce(
+ pol, non_fwd, non_fwd, it, val); // expected-error@*:* {{static assertion failed: transform_reduce}}
+ (void)std::transform_reduce(
+ pol, it, it, non_fwd, val); // expected-error@*:* {{static assertion failed: transform_reduce}}
+
+ (void)std::transform_reduce(
+ pol, non_fwd, non_fwd, it, val, func, func); // expected-error@*:* {{static assertion failed: transform_reduce}}
+ (void)std::transform_reduce(
+ pol, it, it, non_fwd, val, func, func); // expected-error@*:* {{static assertion failed: transform_reduce}}
+
+ (void)std::transform_reduce(
+ pol, non_fwd, non_fwd, val, func, func); // expected-error@*:* {{static assertion failed: transform_reduce}}
+ }
+}
diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
index 7ffb74990fa4dd..e2a3c2cdae41ec 100644
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -1484,9 +1484,14 @@ class iterator_wrapper {
return tmp;
}
- iterator_wrapper& operator+=(difference_type i) {
+ Derived& operator+=(difference_type i) {
iter_ += i;
- return *this;
+ return static_cast<Derived&>(*this);
+ }
+
+ Derived& operator-=(difference_type i) {
+ iter_ -= i;
+ return static_cast<Derived&>(*this);
}
friend decltype(iter_ - iter_) operator-(const iterator_wrapper& lhs, const iterator_wrapper& rhs) {
@@ -1503,8 +1508,17 @@ class iterator_wrapper {
return iter;
}
+ friend Derived operator+(difference_type i, Derived iter) {
+ return iter + i;
+ }
+
friend bool operator==(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ == rhs.iter_; }
friend bool operator!=(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ != rhs.iter_; }
+
+ friend bool operator>(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ > rhs.iter_; }
+ friend bool operator<(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ < rhs.iter_; }
+ friend bool operator<=(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ <= rhs.iter_; }
+ friend bool operator>=(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ >= rhs.iter_; }
};
class iterator_error : std::runtime_error {
>From 642340731880b2bea0b4b22cf15ccde4e9c3d1ac Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Tue, 9 Apr 2024 11:00:24 -0400
Subject: [PATCH 2/2] Clang-format
---
libcxx/test/support/test_iterators.h | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
index e2a3c2cdae41ec..aa819ecd4733bd 100644
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -1508,9 +1508,7 @@ class iterator_wrapper {
return iter;
}
- friend Derived operator+(difference_type i, Derived iter) {
- return iter + i;
- }
+ friend Derived operator+(difference_type i, Derived iter) { return iter + i; }
friend bool operator==(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ == rhs.iter_; }
friend bool operator!=(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ != rhs.iter_; }
More information about the libcxx-commits
mailing list