Skip to content

Commit d57907d

Browse files
authored
[libc++] Add missing iterator requirement checks in the PSTL (#88127)
Also add tests for those, and add a few missing requirements to testing iterators in the test suite.
1 parent 631c5e8 commit d57907d

22 files changed

+383
-102
lines changed

libcxx/include/__algorithm/pstl_any_all_none_of.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ template <class _ExecutionPolicy,
6060
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
6161
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
6262
any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
63-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
63+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "any_of requires a ForwardIterator");
6464
auto __res = std::__any_of(__policy, std::move(__first), std::move(__last), std::move(__pred));
6565
if (!__res)
6666
std::__throw_bad_alloc();
@@ -99,7 +99,7 @@ template <class _ExecutionPolicy,
9999
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
100100
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
101101
all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
102-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
102+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "all_of requires a ForwardIterator");
103103
auto __res = std::__all_of(__policy, std::move(__first), std::move(__last), std::move(__pred));
104104
if (!__res)
105105
std::__throw_bad_alloc();
@@ -136,7 +136,7 @@ template <class _ExecutionPolicy,
136136
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
137137
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
138138
none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
139-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
139+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "none_of requires a ForwardIterator");
140140
auto __res = std::__none_of(__policy, std::move(__first), std::move(__last), std::move(__pred));
141141
if (!__res)
142142
std::__throw_bad_alloc();

libcxx/include/__algorithm/pstl_copy.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <__config>
1717
#include <__functional/identity.h>
1818
#include <__iterator/concepts.h>
19+
#include <__iterator/cpp17_iterator_concepts.h>
1920
#include <__type_traits/enable_if.h>
2021
#include <__type_traits/is_constant_evaluated.h>
2122
#include <__type_traits/is_execution_policy.h>
@@ -67,6 +68,12 @@ template <class _ExecutionPolicy,
6768
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
6869
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
6970
copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
71+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
72+
_ForwardIterator, "copy(first, last, result) requires [first, last) to be ForwardIterators");
73+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
74+
_ForwardOutIterator, "copy(first, last, result) requires result to be a ForwardIterator");
75+
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
76+
_ForwardOutIterator, decltype(*__first), "copy(first, last, result) requires result to be an OutputIterator");
7077
auto __res = std::__copy(__policy, std::move(__first), std::move(__last), std::move(__result));
7178
if (!__res)
7279
std::__throw_bad_alloc();
@@ -106,6 +113,12 @@ template <class _ExecutionPolicy,
106113
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
107114
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
108115
copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __result) {
116+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
117+
_ForwardIterator, "copy_n(first, n, result) requires first to be a ForwardIterator");
118+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
119+
_ForwardOutIterator, "copy_n(first, n, result) requires result to be a ForwardIterator");
120+
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
121+
_ForwardOutIterator, decltype(*__first), "copy_n(first, n, result) requires result to be an OutputIterator");
109122
auto __res = std::__copy_n(__policy, std::move(__first), std::move(__n), std::move(__result));
110123
if (!__res)
111124
std::__throw_bad_alloc();

libcxx/include/__algorithm/pstl_count.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <__atomic/atomic.h>
1818
#include <__config>
1919
#include <__functional/operations.h>
20+
#include <__iterator/cpp17_iterator_concepts.h>
2021
#include <__iterator/iterator_traits.h>
2122
#include <__numeric/pstl_transform_reduce.h>
2223
#include <__type_traits/enable_if.h>
@@ -70,6 +71,8 @@ template <class _ExecutionPolicy,
7071
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
7172
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
7273
count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
74+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
75+
_ForwardIterator, "count_if(first, last, pred) requires [first, last) to be ForwardIterators");
7376
auto __res = std::__count_if(__policy, std::move(__first), std::move(__last), std::move(__pred));
7477
if (!__res)
7578
std::__throw_bad_alloc();
@@ -106,6 +109,8 @@ template <class _ExecutionPolicy,
106109
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
107110
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
108111
count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
112+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
113+
_ForwardIterator, "count(first, last, val) requires [first, last) to be ForwardIterators");
109114
auto __res = std::__count(__policy, std::move(__first), std::move(__last), __value);
110115
if (!__res)
111116
std::__throw_bad_alloc();

libcxx/include/__algorithm/pstl_equal.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <__algorithm/pstl_frontend_dispatch.h>
1414
#include <__config>
1515
#include <__functional/operations.h>
16+
#include <__iterator/cpp17_iterator_concepts.h>
1617
#include <__iterator/iterator_traits.h>
1718
#include <__numeric/pstl_transform_reduce.h>
1819
#include <__utility/move.h>
@@ -74,6 +75,8 @@ equal(_ExecutionPolicy&& __policy,
7475
_ForwardIterator1 __last1,
7576
_ForwardIterator2 __first2,
7677
_Pred __pred) {
78+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
79+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
7780
auto __res = std::__equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__pred));
7881
if (!__res)
7982
std::__throw_bad_alloc();
@@ -86,6 +89,8 @@ template <class _ExecutionPolicy,
8689
enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
8790
_LIBCPP_HIDE_FROM_ABI bool
8891
equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
92+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
93+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
8994
return std::equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::equal_to{});
9095
}
9196

@@ -145,6 +150,8 @@ equal(_ExecutionPolicy&& __policy,
145150
_ForwardIterator2 __first2,
146151
_ForwardIterator2 __last2,
147152
_Pred __pred) {
153+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
154+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
148155
auto __res = std::__equal(
149156
__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__pred));
150157
if (!__res)
@@ -162,6 +169,8 @@ equal(_ExecutionPolicy&& __policy,
162169
_ForwardIterator1 __last1,
163170
_ForwardIterator2 __first2,
164171
_ForwardIterator2 __last2) {
172+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
173+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
165174
return std::equal(
166175
__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::equal_to{});
167176
}

libcxx/include/__algorithm/pstl_fill.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ template <class _ExecutionPolicy,
4343
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
4444
_LIBCPP_HIDE_FROM_ABI optional<__empty>
4545
__fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) noexcept {
46-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
4746
return std::__pstl_frontend_dispatch(
4847
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill, _RawPolicy),
4948
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
@@ -63,7 +62,7 @@ template <class _ExecutionPolicy,
6362
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
6463
_LIBCPP_HIDE_FROM_ABI void
6564
fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
66-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
65+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "fill requires ForwardIterators");
6766
if (!std::__fill(__policy, std::move(__first), std::move(__last), __value))
6867
std::__throw_bad_alloc();
6968
}
@@ -79,7 +78,6 @@ template <class _ExecutionPolicy,
7978
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
8079
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
8180
__fill_n(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _SizeT&& __n, const _Tp& __value) noexcept {
82-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
8381
return std::__pstl_frontend_dispatch(
8482
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n, _RawPolicy),
8583
[&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) {
@@ -102,7 +100,7 @@ template <class _ExecutionPolicy,
102100
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
103101
_LIBCPP_HIDE_FROM_ABI void
104102
fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const _Tp& __value) {
105-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
103+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "fill_n requires ForwardIterators");
106104
if (!std::__fill_n(__policy, std::move(__first), std::move(__n), __value))
107105
std::__throw_bad_alloc();
108106
}

libcxx/include/__algorithm/pstl_find.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ template <class _ExecutionPolicy,
5050
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
5151
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
5252
find_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
53-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
53+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if requires ForwardIterators");
5454
auto __res = std::__find_if(__policy, std::move(__first), std::move(__last), std::move(__pred));
5555
if (!__res)
5656
std::__throw_bad_alloc();
@@ -88,7 +88,7 @@ template <class _ExecutionPolicy,
8888
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
8989
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
9090
find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
91-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
91+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if_not requires ForwardIterators");
9292
auto __res = std::__find_if_not(__policy, std::move(__first), std::move(__last), std::move(__pred));
9393
if (!__res)
9494
std::__throw_bad_alloc();
@@ -125,7 +125,7 @@ template <class _ExecutionPolicy,
125125
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
126126
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
127127
find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
128-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
128+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find requires ForwardIterators");
129129
auto __res = std::__find(__policy, std::move(__first), std::move(__last), __value);
130130
if (!__res)
131131
std::__throw_bad_alloc();

libcxx/include/__algorithm/pstl_for_each.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ template <class _ExecutionPolicy,
5353
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
5454
_LIBCPP_HIDE_FROM_ABI void
5555
for_each(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Function __func) {
56-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
56+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "for_each requires ForwardIterators");
5757
if (!std::__for_each(__policy, std::move(__first), std::move(__last), std::move(__func)))
5858
std::__throw_bad_alloc();
5959
}
@@ -93,7 +93,7 @@ template <class _ExecutionPolicy,
9393
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
9494
_LIBCPP_HIDE_FROM_ABI void
9595
for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
96-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
96+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "for_each_n requires a ForwardIterator");
9797
auto __res = std::__for_each_n(__policy, std::move(__first), std::move(__size), std::move(__func));
9898
if (!__res)
9999
std::__throw_bad_alloc();

libcxx/include/__algorithm/pstl_generate.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ template <class _ExecutionPolicy,
4242
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
4343
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
4444
__generate(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Generator&& __gen) {
45-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
4645
return std::__pstl_frontend_dispatch(
4746
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate, _RawPolicy),
4847
[&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Generator __g_gen) {
@@ -63,7 +62,7 @@ template <class _ExecutionPolicy,
6362
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
6463
_LIBCPP_HIDE_FROM_ABI void
6564
generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
66-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
65+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "generate requires ForwardIterators");
6766
if (!std::__generate(__policy, std::move(__first), std::move(__last), std::move(__gen)))
6867
std::__throw_bad_alloc();
6968
}
@@ -100,7 +99,7 @@ template <class _ExecutionPolicy,
10099
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
101100
_LIBCPP_HIDE_FROM_ABI void
102101
generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) {
103-
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
102+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "generate_n requires a ForwardIterator");
104103
if (!std::__generate_n(__policy, std::move(__first), std::move(__n), std::move(__gen)))
105104
std::__throw_bad_alloc();
106105
}

libcxx/include/__algorithm/pstl_is_partitioned.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <__algorithm/pstl_find.h>
1515
#include <__algorithm/pstl_frontend_dispatch.h>
1616
#include <__config>
17+
#include <__iterator/cpp17_iterator_concepts.h>
1718
#include <__type_traits/enable_if.h>
1819
#include <__type_traits/is_execution_policy.h>
1920
#include <__type_traits/remove_cvref.h>
@@ -62,6 +63,7 @@ template <class _ExecutionPolicy,
6263
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
6364
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
6465
is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
66+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "is_partitioned requires ForwardIterators");
6567
auto __res = std::__is_partitioned(__policy, std::move(__first), std::move(__last), std::move(__pred));
6668
if (!__res)
6769
std::__throw_bad_alloc();

libcxx/include/__algorithm/pstl_merge.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <__algorithm/pstl_backend.h>
1313
#include <__config>
1414
#include <__functional/operations.h>
15+
#include <__iterator/cpp17_iterator_concepts.h>
1516
#include <__type_traits/enable_if.h>
1617
#include <__type_traits/is_execution_policy.h>
1718
#include <__type_traits/remove_cvref.h>
@@ -70,6 +71,10 @@ merge(_ExecutionPolicy&& __policy,
7071
_ForwardIterator2 __last2,
7172
_ForwardOutIterator __result,
7273
_Comp __comp = {}) {
74+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "merge requires ForwardIterators");
75+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "merge requires ForwardIterators");
76+
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1), "merge requires an OutputIterator");
77+
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2), "merge requires an OutputIterator");
7378
auto __res = std::__merge(
7479
__policy,
7580
std::move(__first1),

libcxx/include/__algorithm/pstl_move.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <__algorithm/pstl_transform.h>
1616
#include <__config>
1717
#include <__functional/identity.h>
18+
#include <__iterator/cpp17_iterator_concepts.h>
1819
#include <__iterator/iterator_traits.h>
1920
#include <__type_traits/enable_if.h>
2021
#include <__type_traits/is_constant_evaluated.h>
@@ -69,6 +70,10 @@ template <class _ExecutionPolicy,
6970
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
7071
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
7172
move(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
73+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "move requires ForwardIterators");
74+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "move requires an OutputIterator");
75+
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
76+
_ForwardOutIterator, decltype(std::move(*__first)), "move requires an OutputIterator");
7277
auto __res = std::__move(__policy, std::move(__first), std::move(__last), std::move(__result));
7378
if (!__res)
7479
std::__throw_bad_alloc();

libcxx/include/__algorithm/pstl_replace.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <__algorithm/pstl_frontend_dispatch.h>
1515
#include <__algorithm/pstl_transform.h>
1616
#include <__config>
17+
#include <__iterator/cpp17_iterator_concepts.h>
1718
#include <__iterator/iterator_traits.h>
1819
#include <__type_traits/enable_if.h>
1920
#include <__type_traits/remove_cvref.h>
@@ -74,6 +75,7 @@ replace_if(_ExecutionPolicy&& __policy,
7475
_ForwardIterator __last,
7576
_Pred __pred,
7677
const _Tp& __new_value) {
78+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_if requires ForwardIterators");
7779
auto __res = std::__replace_if(__policy, std::move(__first), std::move(__last), std::move(__pred), __new_value);
7880
if (!__res)
7981
std::__throw_bad_alloc();
@@ -121,6 +123,7 @@ replace(_ExecutionPolicy&& __policy,
121123
_ForwardIterator __last,
122124
const _Tp& __old_value,
123125
const _Tp& __new_value) {
126+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace requires ForwardIterators");
124127
if (!std::__replace(__policy, std::move(__first), std::move(__last), __old_value, __new_value))
125128
std::__throw_bad_alloc();
126129
}
@@ -177,6 +180,11 @@ _LIBCPP_HIDE_FROM_ABI void replace_copy_if(
177180
_ForwardOutIterator __result,
178181
_Pred __pred,
179182
const _Tp& __new_value) {
183+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_copy_if requires ForwardIterators");
184+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "replace_copy_if requires ForwardIterators");
185+
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
186+
_ForwardOutIterator, decltype(*__first), "replace_copy_if requires an OutputIterator");
187+
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, const _Tp&, "replace_copy requires an OutputIterator");
180188
if (!std::__replace_copy_if(
181189
__policy, std::move(__first), std::move(__last), std::move(__result), std::move(__pred), __new_value))
182190
std::__throw_bad_alloc();
@@ -233,6 +241,11 @@ _LIBCPP_HIDE_FROM_ABI void replace_copy(
233241
_ForwardOutIterator __result,
234242
const _Tp& __old_value,
235243
const _Tp& __new_value) {
244+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_copy requires ForwardIterators");
245+
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "replace_copy requires ForwardIterators");
246+
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
247+
_ForwardOutIterator, decltype(*__first), "replace_copy requires an OutputIterator");
248+
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, const _Tp&, "replace_copy requires an OutputIterator");
236249
if (!std::__replace_copy(
237250
__policy, std::move(__first), std::move(__last), std::move(__result), __old_value, __new_value))
238251
std::__throw_bad_alloc();

0 commit comments

Comments
 (0)