[libcxx-commits] [libcxx] bd3f5a4 - [libc++][pstl] Improve exception handling (#88998)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed May 22 12:39:26 PDT 2024
Author: Louis Dionne
Date: 2024-05-22T12:39:21-07:00
New Revision: bd3f5a4bd3d9d7ee8ae801c24c5081073b20abd4
URL: https://github.com/llvm/llvm-project/commit/bd3f5a4bd3d9d7ee8ae801c24c5081073b20abd4
DIFF: https://github.com/llvm/llvm-project/commit/bd3f5a4bd3d9d7ee8ae801c24c5081073b20abd4.diff
LOG: [libc++][pstl] Improve exception handling (#88998)
There were various places where we incorrectly handled exceptions in the
PSTL. Typical issues were missing `noexcept` and taking iterators by
value instead of by reference.
This patch fixes those inconsistent and incorrect instances, and adds
proper tests for all of those. Note that the previous tests were often
incorrectly turned into no-ops by the compiler due to copy ellision,
which doesn't happen with these new tests.
Added:
libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
libcxx/test/std/numerics/numeric.ops/reduce/pstl.reduce.pass.cpp
libcxx/test/std/numerics/numeric.ops/transform.reduce/pstl.transform_reduce.binary.pass.cpp
libcxx/test/std/numerics/numeric.ops/transform.reduce/pstl.transform_reduce.unary.pass.cpp
Modified:
libcxx/include/__algorithm/pstl_copy.h
libcxx/include/__algorithm/pstl_count.h
libcxx/include/__algorithm/pstl_equal.h
libcxx/include/__algorithm/pstl_fill.h
libcxx/include/__algorithm/pstl_find.h
libcxx/include/__algorithm/pstl_generate.h
libcxx/include/__algorithm/pstl_is_partitioned.h
libcxx/include/__algorithm/pstl_merge.h
libcxx/include/__algorithm/pstl_replace.h
libcxx/include/__algorithm/pstl_sort.h
Removed:
libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.modifying.operations/alg.move/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.modifying.operations/alg.transform/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.nonmodifying/alg.equal/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.nonmodifying/alg.find/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.sorting/alg.merge/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/numeric.ops/reduce/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/numeric.ops/reduce/pstl.reduce.pass.cpp
libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.exception_handling.pass.cpp
libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.transform_reduce.binary.pass.cpp
libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.transform_reduce.unary.pass.cpp
################################################################################
diff --git a/libcxx/include/__algorithm/pstl_copy.h b/libcxx/include/__algorithm/pstl_copy.h
index 0fcea33c3919f..66381b9a186b0 100644
--- a/libcxx/include/__algorithm/pstl_copy.h
+++ b/libcxx/include/__algorithm/pstl_copy.h
@@ -95,10 +95,12 @@ template <class _ExecutionPolicy,
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_copy_n, _RawPolicy),
[&__policy](
_ForwardIterator __g_first, _Size __g_n, _ForwardOutIterator __g_result) -> optional<_ForwardIterator> {
- if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value)
+ if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
return std::__copy(__policy, std::move(__g_first), std::move(__g_first + __g_n), std::move(__g_result));
- else
+ } else {
+ (void)__policy;
return std::copy_n(__g_first, __g_n, __g_result);
+ }
},
std::move(__first),
std::move(__n),
diff --git a/libcxx/include/__algorithm/pstl_count.h b/libcxx/include/__algorithm/pstl_count.h
index 64c84d855e4f6..65c96b2f06de9 100644
--- a/libcxx/include/__algorithm/pstl_count.h
+++ b/libcxx/include/__algorithm/pstl_count.h
@@ -87,8 +87,8 @@ template <class _ExecutionPolicy,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_
diff _t<_ForwardIterator>>
-__count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_
diff _t<_ForwardIterator>> __count(
+ _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, const _Tp& __value) noexcept {
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count, _RawPolicy),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value)
@@ -97,8 +97,8 @@ __count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator
return __v == __g_value;
});
},
- std::move(__first),
- std::move(__last),
+ std::forward<_ForwardIterator>(__first),
+ std::forward<_ForwardIterator>(__last),
__value);
}
diff --git a/libcxx/include/__algorithm/pstl_equal.h b/libcxx/include/__algorithm/pstl_equal.h
index 0b38197d7f63d..47333daaac88e 100644
--- a/libcxx/include/__algorithm/pstl_equal.h
+++ b/libcxx/include/__algorithm/pstl_equal.h
@@ -91,7 +91,10 @@ _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{});
+ auto __res = std::__equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::equal_to{});
+ if (!__res)
+ std::__throw_bad_alloc();
+ return *__res;
}
template <class _ExecutionPolicy,
@@ -171,8 +174,11 @@ equal(_ExecutionPolicy&& __policy,
_ForwardIterator2 __last2) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
- return std::equal(
+ auto __res = std::__equal(
__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::equal_to{});
+ if (!__res)
+ std::__throw_bad_alloc();
+ return *__res;
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_fill.h b/libcxx/include/__algorithm/pstl_fill.h
index fd248506bc4b9..1032d77af8a0d 100644
--- a/libcxx/include/__algorithm/pstl_fill.h
+++ b/libcxx/include/__algorithm/pstl_fill.h
@@ -41,8 +41,8 @@ template <class _ExecutionPolicy,
class _Tp,
class _RawPolicy = __remove_cvref_t<_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_HIDE_FROM_ABI optional<__empty> __fill(
+ _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, const _Tp& __value) noexcept {
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill, _RawPolicy),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
@@ -50,8 +50,8 @@ __fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator _
__element = __g_value;
});
},
- std::move(__first),
- std::move(__last),
+ std::forward<_ForwardIterator>(__first),
+ std::forward<_ForwardIterator>(__last),
__value);
}
diff --git a/libcxx/include/__algorithm/pstl_find.h b/libcxx/include/__algorithm/pstl_find.h
index b4c4dfb2ffb6f..998db70fd6445 100644
--- a/libcxx/include/__algorithm/pstl_find.h
+++ b/libcxx/include/__algorithm/pstl_find.h
@@ -65,8 +65,8 @@ template <class _ExecutionPolicy,
class _Predicate,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardIterator>>
-__find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardIterator>> __find_if_not(
+ _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) noexcept {
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find_if_not, _RawPolicy),
[&](_ForwardIterator&& __g_first, _ForwardIterator&& __g_last, _Predicate&& __g_pred)
@@ -76,9 +76,9 @@ __find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardI
return !__g_pred(__value);
});
},
- std::move(__first),
- std::move(__last),
- std::move(__pred));
+ std::forward<_ForwardIterator>(__first),
+ std::forward<_ForwardIterator>(__last),
+ std::forward<_Predicate>(__pred));
}
template <class _ExecutionPolicy,
@@ -103,8 +103,8 @@ template <class _ExecutionPolicy,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardIterator>>
-__find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardIterator>> __find(
+ _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, const _Tp& __value) noexcept {
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find, _RawPolicy),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) -> optional<_ForwardIterator> {
@@ -113,8 +113,8 @@ __find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator _
return __element == __g_value;
});
},
- std::move(__first),
- std::move(__last),
+ std::forward<_ForwardIterator>(__first),
+ std::forward<_ForwardIterator>(__last),
__value);
}
diff --git a/libcxx/include/__algorithm/pstl_generate.h b/libcxx/include/__algorithm/pstl_generate.h
index 350c0e4798be6..78e4dd81e644c 100644
--- a/libcxx/include/__algorithm/pstl_generate.h
+++ b/libcxx/include/__algorithm/pstl_generate.h
@@ -40,8 +40,8 @@ template <class _ExecutionPolicy,
class _Generator,
class _RawPolicy = __remove_cvref_t<_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) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __generate(
+ _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Generator&& __gen) noexcept {
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate, _RawPolicy),
[&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Generator __g_gen) {
@@ -77,7 +77,7 @@ template <class _ExecutionPolicy,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
-__generate_n(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _Size&& __n, _Generator&& __gen) {
+__generate_n(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _Size&& __n, _Generator&& __gen) noexcept {
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate_n, _RawPolicy),
[&__policy](_ForwardIterator __g_first, _Size __g_n, _Generator __g_gen) {
diff --git a/libcxx/include/__algorithm/pstl_is_partitioned.h b/libcxx/include/__algorithm/pstl_is_partitioned.h
index 2dd5cf3ca2a21..068502e7ed118 100644
--- a/libcxx/include/__algorithm/pstl_is_partitioned.h
+++ b/libcxx/include/__algorithm/pstl_is_partitioned.h
@@ -41,7 +41,7 @@ template <class _ExecutionPolicy,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool> __is_partitioned(
- _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) {
+ _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) noexcept {
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_is_partitioned, _RawPolicy),
[&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
diff --git a/libcxx/include/__algorithm/pstl_merge.h b/libcxx/include/__algorithm/pstl_merge.h
index 87f634a67f588..f76a281f4c450 100644
--- a/libcxx/include/__algorithm/pstl_merge.h
+++ b/libcxx/include/__algorithm/pstl_merge.h
@@ -16,6 +16,7 @@
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
#include <optional>
@@ -34,26 +35,26 @@ template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
class _ForwardOutIterator,
- class _Comp = std::less<>,
+ class _Comp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
__merge(_ExecutionPolicy&&,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardIterator2 __last2,
- _ForwardOutIterator __result,
- _Comp __comp = {}) noexcept {
+ _ForwardIterator1&& __first1,
+ _ForwardIterator1&& __last1,
+ _ForwardIterator2&& __first2,
+ _ForwardIterator2&& __last2,
+ _ForwardOutIterator&& __result,
+ _Comp&& __comp) noexcept {
using _Backend = typename __select_backend<_RawPolicy>::type;
return std::__pstl_merge<_RawPolicy>(
_Backend{},
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__last2),
- std::move(__result),
- std::move(__comp));
+ std::forward<_ForwardIterator1>(__first1),
+ std::forward<_ForwardIterator1>(__last1),
+ std::forward<_ForwardIterator2>(__first2),
+ std::forward<_ForwardIterator2>(__last2),
+ std::forward<_ForwardOutIterator>(__result),
+ std::forward<_Comp>(__comp));
}
template <class _ExecutionPolicy,
diff --git a/libcxx/include/__algorithm/pstl_replace.h b/libcxx/include/__algorithm/pstl_replace.h
index b2ded54dfe25f..456df216b19db 100644
--- a/libcxx/include/__algorithm/pstl_replace.h
+++ b/libcxx/include/__algorithm/pstl_replace.h
@@ -91,8 +91,8 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
__replace(_ExecutionPolicy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
+ _ForwardIterator&& __first,
+ _ForwardIterator&& __last,
const _Tp& __old_value,
const _Tp& __new_value) noexcept {
return std::__pstl_frontend_dispatch(
@@ -106,8 +106,8 @@ __replace(_ExecutionPolicy&& __policy,
[&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
__g_new_value);
},
- std::move(__first),
- std::move(__last),
+ std::forward<_ForwardIterator>(__first),
+ std::forward<_ForwardIterator>(__last),
__old_value,
__new_value);
}
@@ -144,7 +144,7 @@ template <class _ExecutionPolicy,
_ForwardIterator&& __last,
_ForwardOutIterator&& __result,
_Pred&& __pred,
- const _Tp& __new_value) {
+ const _Tp& __new_value) noexcept {
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy_if, _RawPolicy),
[&__policy](_ForwardIterator __g_first,
diff --git a/libcxx/include/__algorithm/pstl_sort.h b/libcxx/include/__algorithm/pstl_sort.h
index 769dd81af77e0..1b978b2272762 100644
--- a/libcxx/include/__algorithm/pstl_sort.h
+++ b/libcxx/include/__algorithm/pstl_sort.h
@@ -41,17 +41,20 @@ template <class _ExecutionPolicy,
class _Comp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __sort(
- _ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+__sort(_ExecutionPolicy&& __policy,
+ _RandomAccessIterator&& __first,
+ _RandomAccessIterator&& __last,
+ _Comp&& __comp) noexcept {
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_sort, _RawPolicy),
[&__policy](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
std::stable_sort(__policy, std::move(__g_first), std::move(__g_last), std::move(__g_comp));
return optional<__empty>{__empty{}};
},
- std::move(__first),
- std::move(__last),
- std::move(__comp));
+ std::forward<_RandomAccessIterator>(__first),
+ std::forward<_RandomAccessIterator>(__last),
+ std::forward<_Comp>(__comp));
}
template <class _ExecutionPolicy,
@@ -73,7 +76,8 @@ template <class _ExecutionPolicy,
_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{});
+ if (!std::__sort(__policy, std::move(__first), std::move(__last), less{}))
+ std::__throw_bad_alloc();
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.exception_handling.pass.cpp
deleted file mode 100644
index dda642be85bc0..0000000000000
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::fill(ExecutionPolicy) and std::fill_n(ExecutionPolicy) terminate on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-#ifndef TEST_HAS_NO_EXCEPTIONS
-struct ThrowOnCopy {
- ThrowOnCopy& operator=(const ThrowOnCopy&) { throw int{}; }
-};
-#endif
-
-int main(int, char**) {
- ThrowOnCopy a[2]{};
- int b[2]{};
-
- test_execution_policies([&](auto&& policy) {
- // std::fill
- EXPECT_STD_TERMINATE([&] { (void)std::fill(policy, std::begin(a), std::end(a), ThrowOnCopy{}); });
- EXPECT_STD_TERMINATE([&] {
- try {
- (void)std::fill(
- policy, util::throw_on_move_iterator(std::begin(b), 1), util::throw_on_move_iterator(std::end(b), 1), 0);
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
-
- // std::fill_n
- EXPECT_STD_TERMINATE([&] { (void)std::fill_n(policy, std::begin(a), std::size(a), ThrowOnCopy{}); });
- EXPECT_STD_TERMINATE([&] {
- try {
- (void)std::fill_n(policy, util::throw_on_move_iterator(std::begin(b), 1), std::size(b), 0);
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/pstl.exception_handling.pass.cpp
deleted file mode 100644
index bb8ab42172226..0000000000000
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::move(ExecutionPolicy) terminates on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([](auto&& policy) {
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- int b[] = {1, 2};
- (void)std::move(policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(b), 1));
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.exception_handling.pass.cpp
deleted file mode 100644
index c02496bef4212..0000000000000
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::replace(ExecutionPolicy), std::replace_if(ExecutionPolicy), std::replace_copy(ExecutionPolicy)
-// and std::replace_copy_if(ExecutionPolicy) terminate on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-struct ThrowOnCompare {};
-
-#ifndef TEST_HAS_NO_EXCEPTIONS
-bool operator==(ThrowOnCompare, ThrowOnCompare) { throw int{}; }
-#endif
-
-int main(int, char**) {
- test_execution_policies([&](auto&& policy) {
- // std::replace
- EXPECT_STD_TERMINATE([&] {
- ThrowOnCompare a[2]{};
- (void)std::replace(policy, std::begin(a), std::end(a), ThrowOnCompare{}, ThrowOnCompare{});
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::replace(
- policy, util::throw_on_move_iterator(std::begin(a), 1), util::throw_on_move_iterator(std::end(a), 1), 1, 2);
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
-
- // std::replace_if
- EXPECT_STD_TERMINATE([&] {
- ThrowOnCompare a[2]{};
- (void)std::replace_if(
- policy, std::begin(a), std::end(a), [](ThrowOnCompare&) -> bool { throw int{}; }, ThrowOnCompare{});
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::replace_if(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- [](int) { return true; },
- 2);
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
-
- // std::replace_copy
- EXPECT_STD_TERMINATE([&] {
- ThrowOnCompare a[2]{};
- (void)std::replace_copy(policy, std::begin(a), std::end(a), std::begin(a), ThrowOnCompare{}, ThrowOnCompare{});
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::replace_copy(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(a), 1),
- 1,
- 2);
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
-
- // std::replace_copy_if
- EXPECT_STD_TERMINATE([&] {
- ThrowOnCompare a[2]{};
- (void)std::replace_copy_if(
- policy,
- std::begin(a),
- std::end(a),
- std::begin(a),
- [](ThrowOnCompare& i) { return i == i; },
- ThrowOnCompare{});
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::replace_copy_if(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(a), 1),
- [](int) { return true; },
- 2);
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/pstl.exception_handling.pass.cpp
deleted file mode 100644
index 88d177a6e39f4..0000000000000
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::find(ExecutionPolicy), std::find_if(ExecutionPolicy) and std::find_if_not(ExecutionPolicy) terminate
-// on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([](auto&& policy) {
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- int b[] = {1, 2};
- (void)std::rotate_copy(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(b), 1));
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.transform/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.transform/pstl.exception_handling.pass.cpp
deleted file mode 100644
index 439204060e189..0000000000000
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.transform/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::transform(ExecutionPolicy) terminates on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([&](auto&& policy) {
- EXPECT_STD_TERMINATE([&] {
- int a[2]{};
- int b[2]{};
- int c[2]{};
- (void)std::transform(
- policy, std::begin(a), std::end(a), std::begin(b), std::begin(c), [](auto v, auto) -> decltype(v) {
- throw int{};
- });
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::transform(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(a), 1),
- [](int i) { return i; });
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
-
- EXPECT_STD_TERMINATE([&] {
- int a[2]{};
- int b[2]{};
- (void)std::transform(policy, std::begin(a), std::end(a), std::begin(b), [](auto v) -> decltype(v) {
- throw int{};
- });
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::transform(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::begin(a), 1),
- std::plus{});
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/pstl.exception_handling.pass.cpp
deleted file mode 100644
index d1c031bdd97a2..0000000000000
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::all_of(ExecutionPolicy) terminates on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([](auto&& policy) {
- EXPECT_STD_TERMINATE([&] {
- int a[] = {1, 2};
- (void)std::all_of(policy, std::begin(a), std::end(a), [](int i) -> bool { throw i; });
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::all_of(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- [](int) { return true; });
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/pstl.exception_handling.pass.cpp
deleted file mode 100644
index 58fe79b34c008..0000000000000
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::any_of(ExecutionPolicy) terminates on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([](auto&& policy) {
- EXPECT_STD_TERMINATE([&] {
- int a[] = {1, 2};
- (void)std::any_of(policy, std::begin(a), std::end(a), [](int i) -> bool { throw i; });
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::any_of(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- [](int) { return true; });
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.equal/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.equal/pstl.exception_handling.pass.cpp
deleted file mode 100644
index 1bcd858f3c02d..0000000000000
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.equal/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::equal(ExecutionPolicy) terminates on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([](auto&& policy) {
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- int b[] = {1, 2};
- (void)std::equal(policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(b), 1));
- } catch (const util::iterator_error&) {
- assert(false);
- }
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- int b[] = {1, 2};
- (void)std::equal(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(b), 1),
- util::throw_on_move_iterator(std::end(b), 1));
- } catch (const util::iterator_error&) {
- assert(false);
- }
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/pstl.exception_handling.pass.cpp
deleted file mode 100644
index b0ee4f8d062ef..0000000000000
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::find(ExecutionPolicy), std::find_if(ExecutionPolicy) and std::find_if_not(ExecutionPolicy) terminate
-// on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-struct ThrowOnCompare {};
-
-#ifndef TEST_HAS_NO_EXCEPTIONS
-bool operator==(ThrowOnCompare, ThrowOnCompare) { throw int{}; }
-#endif
-
-int main(int, char**) {
- test_execution_policies([](auto&& policy) {
- // std::find
- EXPECT_STD_TERMINATE([&] {
- ThrowOnCompare a[2] = {};
- (void)std::find(policy, std::begin(a), std::end(a), ThrowOnCompare{});
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::find(
- policy, util::throw_on_move_iterator(std::begin(a), 1), util::throw_on_move_iterator(std::end(a), 1), 0);
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
-
- // std::find_if
- EXPECT_STD_TERMINATE([&] {
- int a[] = {1, 2};
- (void)std::find_if(policy, std::begin(a), std::end(a), [](int) -> bool { throw int{}; });
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::find_if(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- [](int) { return true; });
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
-
- // std::find_if_not
- EXPECT_STD_TERMINATE([&] {
- int a[] = {1, 2};
- (void)std::find_if_not(policy, std::begin(a), std::end(a), [](int) -> bool { throw int{}; });
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::find_if_not(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- [](int) { return true; });
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/pstl.exception_handling.pass.cpp
deleted file mode 100644
index a63276f1e025d..0000000000000
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::for_each(ExecutionPolicy) and std::for_each_n(ExecutionPolicy) terminate on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([](auto&& policy) {
- int a[] = {1, 2};
- // std::for_each
- EXPECT_STD_TERMINATE([&] { std::for_each(policy, std::begin(a), std::end(a), [](int) { throw int{}; }); });
- EXPECT_STD_TERMINATE([&] {
- try {
- (void)std::for_each(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- [](int) {});
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
-
- // std::for_each_n
- EXPECT_STD_TERMINATE([&] { std::for_each_n(policy, std::data(a), std::size(a), [](int) { throw int{}; }); });
- EXPECT_STD_TERMINATE([&] {
- try {
- (void)std::for_each_n(policy, util::throw_on_move_iterator(std::begin(a), 1), std::size(a), [](int) {});
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/pstl.exception_handling.pass.cpp
deleted file mode 100644
index 26e6fea5904fe..0000000000000
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::none_of(ExecutionPolicy) terminates on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([](auto&& policy) {
- EXPECT_STD_TERMINATE([&] {
- int a[] = {1, 2};
- (void)std::none_of(policy, std::begin(a), std::end(a), [](int i) -> bool { throw i; });
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::none_of(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- [](int) { return true; });
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.merge/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.merge/pstl.exception_handling.pass.cpp
deleted file mode 100644
index b48a5a9fa2b7d..0000000000000
--- a/libcxx/test/std/algorithms/alg.sorting/alg.merge/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::merge(ExecutionPolicy) terminates on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([](auto&& policy) {
- EXPECT_STD_TERMINATE([&] {
- int a[] = {1, 2};
- std::merge(policy, std::begin(a), std::end(a), std::begin(a), std::end(a), std::begin(a), [](int, int) -> bool {
- throw int{};
- });
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::merge(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(a), 1),
- std::less{});
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-
- return 0;
-}
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/pstl.exception_handling.pass.cpp
deleted file mode 100644
index 1dc603cfaa554..0000000000000
--- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::stable_sort(ExecutionPolicy) terminates on user-thrown exceptions
-
-#include <algorithm>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([](auto&& policy) {
- EXPECT_STD_TERMINATE([&] {
- int a[] = {1, 2};
- std::stable_sort(policy, std::begin(a), std::end(a), [](int, int) -> bool { throw int{}; });
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::stable_sort(
- policy, util::throw_on_move_iterator(std::begin(a), 1), util::throw_on_move_iterator(std::end(a), 1));
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/numeric.ops/reduce/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/numeric.ops/reduce/pstl.exception_handling.pass.cpp
deleted file mode 100644
index d52889b1be147..0000000000000
--- a/libcxx/test/std/algorithms/numeric.ops/reduce/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::reduce(ExecutionPolicy) terminates on user-thrown exceptions
-
-#include <numeric>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([&](auto&& policy) {
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::reduce(
- policy, util::throw_on_move_iterator(std::begin(a), 1), util::throw_on_move_iterator(std::end(a), 1));
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
-
- EXPECT_STD_TERMINATE([&] {
- int a[2]{};
- (void)std::reduce(policy, std::begin(a), std::end(a), 1, [](int, int) -> int { throw 1; });
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::reduce(
- policy, util::throw_on_move_iterator(std::begin(a), 1), util::throw_on_move_iterator(std::end(a), 1), 1);
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.exception_handling.pass.cpp
deleted file mode 100644
index 5ac04334f0005..0000000000000
--- a/libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.exception_handling.pass.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// UNSUPPORTED: no-exceptions
-// `check_assertion.h` requires Unix headers and regex support.
-// UNSUPPORTED: !has-unix-headers, no-localization
-
-// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-
-// check that std::reduce(ExecutionPolicy) terminates on user-thrown exceptions
-
-#include <numeric>
-
-#include "check_assertion.h"
-#include "test_execution_policies.h"
-#include "test_iterators.h"
-
-int main(int, char**) {
- test_execution_policies([&](auto&& policy) {
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::transform_reduce(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(a), 1),
- 1);
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
-
- EXPECT_STD_TERMINATE([&] {
- int a[2]{};
- (void)std::transform_reduce(
- policy, std::begin(a), std::end(a), 1, [](int, int) -> int { throw 1; }, [](int) -> int { return 0; });
- });
- EXPECT_STD_TERMINATE([&] {
- try {
- int a[] = {1, 2};
- (void)std::transform_reduce(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- 1,
- std::plus{},
- [](int) -> int { return 0; });
- } catch (const util::iterator_error&) {
- assert(false);
- }
- std::terminate(); // make the test pass in case the algorithm didn't move the iterator
- });
- });
-}
diff --git a/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
new file mode 100644
index 0000000000000..bedb2258d1fd5
--- /dev/null
+++ b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
@@ -0,0 +1,339 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: no-exceptions
+// `check_assertion.h` requires Unix headers and regex support.
+// UNSUPPORTED: !has-unix-headers, no-localization
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// <algorithm>
+// <numeric>
+//
+// Check that PSTL algorithms terminate on user-thrown exceptions.
+
+#include <algorithm>
+#include <numeric>
+
+#include "check_assertion.h"
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+
+template <class F>
+void assert_non_throwing(F f) {
+ // We wrap this whole test in EXPECT_STD_TERMINATE because if f() terminates, we want the test to pass,
+ // since this signals proper handling of user exceptions in the PSTL.
+ EXPECT_STD_TERMINATE([&] {
+ bool threw = false;
+ try {
+ f();
+ } catch (...) {
+ threw = true;
+ }
+ // If nothing was thrown, call std::terminate() to pass the EXPECT_STD_TERMINATE assertion.
+ // Otherwise, don't call std::terminate() to fail the assertion.
+ if (!threw)
+ std::terminate();
+ });
+}
+
+struct ThrowToken {
+ void activate() { active_ = true; }
+ void deactivate() { active_ = false; }
+ bool active() const { return active_; }
+
+private:
+ bool active_{false};
+};
+
+template <class Func>
+struct on_scope_exit {
+ explicit on_scope_exit(Func func) : func_(func) {}
+ ~on_scope_exit() { func_(); }
+
+private:
+ Func func_;
+};
+template <class Func>
+on_scope_exit(Func) -> on_scope_exit<Func>;
+
+int main(int, char**) {
+ test_execution_policies([&](auto&& policy) {
+ int a[] = {1, 2, 3, 4};
+ int b[] = {1, 2, 3};
+ int n = 2;
+ int storage[999];
+ int val = 99;
+ int init = 1;
+
+ // We generate a certain number of "tokens" and we activate exactly one on each iteration. We then
+ // throw in a given operation only when that token is active. That way we check that each argument
+ // of the algorithm is handled properly.
+ ThrowToken tokens[7];
+ for (ThrowToken& t : tokens) {
+ t.activate();
+ on_scope_exit _([&] { t.deactivate(); });
+
+ auto first1 = util::throw_on_move_iterator(std::begin(a), tokens[0].active() ? 1 : -1);
+ auto last1 = util::throw_on_move_iterator(std::end(a), tokens[1].active() ? 1 : -1);
+ auto first2 = util::throw_on_move_iterator(std::begin(b), tokens[2].active() ? 1 : -1);
+ auto last2 = util::throw_on_move_iterator(std::end(b), tokens[3].active() ? 1 : -1);
+ auto dest = util::throw_on_move_iterator(std::end(storage), tokens[4].active() ? 1 : -1);
+ auto maybe_throw = [](ThrowToken const& token, auto f) {
+ return [&token, f](auto... args) {
+ if (token.active())
+ throw 1;
+ return f(args...);
+ };
+ };
+
+ {
+ auto pred = maybe_throw(tokens[5], [](int x) -> bool { return x % 2 == 0; });
+
+ // all_of(first, last, pred)
+ assert_non_throwing([=, &policy] { (void)std::all_of(policy, std::move(first1), std::move(last1), pred); });
+
+ // any_of(first, last, pred)
+ assert_non_throwing([=, &policy] { (void)std::any_of(policy, std::move(first1), std::move(last1), pred); });
+
+ // none_of(first, last, pred)
+ assert_non_throwing([=, &policy] { (void)std::none_of(policy, std::move(first1), std::move(last1), pred); });
+ }
+
+ {
+ // copy(first, last, dest)
+ assert_non_throwing([=, &policy] {
+ (void)std::copy(policy, std::move(first1), std::move(last1), std::move(dest));
+ });
+
+ // copy_n(first, n, dest)
+ assert_non_throwing([=, &policy] { (void)std::copy_n(policy, std::move(first1), n, std::move(dest)); });
+ }
+
+ {
+ auto pred = maybe_throw(tokens[5], [](int x) -> bool { return x % 2 == 0; });
+
+ // count(first, last, val)
+ assert_non_throwing([=, &policy] { (void)std::count(policy, std::move(first1), std::move(last1), val); });
+
+ // count_if(first, last, pred)
+ assert_non_throwing([=, &policy] { (void)std::count_if(policy, std::move(first1), std::move(last1), pred); });
+ }
+
+ {
+ auto binary_pred = maybe_throw(tokens[5], [](int x, int y) -> bool { return x == y; });
+
+ // equal(first1, last1, first2)
+ assert_non_throwing([=, &policy] {
+ (void)std::equal(policy, std::move(first1), std::move(last1), std::move(first2));
+ });
+
+ // equal(first1, last1, first2, binary_pred)
+ assert_non_throwing([=, &policy] {
+ (void)std::equal(policy, std::move(first1), std::move(last1), std::move(first2), binary_pred);
+ });
+
+ // equal(first1, last1, first2, last2)
+ assert_non_throwing([=, &policy] {
+ (void)std::equal(policy, std::move(first1), std::move(last1), std::move(first2), std::move(last2));
+ });
+
+ // equal(first1, last1, first2, last2, binary_pred)
+ assert_non_throwing([=, &policy] {
+ (void)std::equal(
+ policy, std::move(first1), std::move(last1), std::move(first2), std::move(last2), binary_pred);
+ });
+ }
+
+ {
+ // fill(first, last, val)
+ assert_non_throwing([=, &policy] { (void)std::fill(policy, std::move(first1), std::move(last1), val); });
+
+ // fill_n(first, n, val)
+ assert_non_throwing([=, &policy] { (void)std::fill_n(policy, std::move(first1), n, val); });
+ }
+
+ {
+ auto pred = maybe_throw(tokens[5], [](int x) -> bool { return x % 2 == 0; });
+
+ // find(first, last, val)
+ assert_non_throwing([=, &policy] { (void)std::find(policy, std::move(first1), std::move(last1), val); });
+
+ // find_if(first, last, pred)
+ assert_non_throwing([=, &policy] { (void)std::find_if(policy, std::move(first1), std::move(last1), pred); });
+
+ // find_if_not(first, last, pred)
+ assert_non_throwing([=, &policy] {
+ (void)std::find_if_not(policy, std::move(first1), std::move(last1), pred);
+ });
+ }
+
+ {
+ auto func = maybe_throw(tokens[5], [](int) {});
+
+ // for_each(first, last, func)
+ assert_non_throwing([=, &policy] { (void)std::for_each(policy, std::move(first1), std::move(last1), func); });
+
+ // for_each_n(first, n, func)
+ assert_non_throwing([=, &policy] { (void)std::for_each_n(policy, std::move(first1), n, func); });
+ }
+
+ {
+ auto gen = maybe_throw(tokens[5], []() -> int { return 42; });
+
+ // generate(first, last, func)
+ assert_non_throwing([=, &policy] { (void)std::generate(policy, std::move(first1), std::move(last1), gen); });
+
+ // generate_n(first, n, func)
+ assert_non_throwing([=, &policy] { (void)std::generate_n(policy, std::move(first1), n, gen); });
+ }
+
+ {
+ auto pred = maybe_throw(tokens[5], [](int x) -> bool { return x % 2 == 0; });
+
+ // is_partitioned(first, last, pred)
+ assert_non_throwing([=, &policy] {
+ (void)std::is_partitioned(policy, std::move(first1), std::move(last1), pred);
+ });
+ }
+
+ {
+ auto compare = maybe_throw(tokens[5], [](int x, int y) -> bool { return x < y; });
+
+ // merge(first1, last1, first2, last2, dest)
+ assert_non_throwing([=, &policy] {
+ (void)std::merge(
+ policy, std::move(first1), std::move(last1), std::move(first2), std::move(last2), std::move(dest));
+ });
+
+ // merge(first1, last1, first2, last2, dest, comp)
+ assert_non_throwing([=, &policy] {
+ (void)std::merge(
+ policy,
+ std::move(first1),
+ std::move(last1),
+ std::move(first2),
+ std::move(last2),
+ std::move(dest),
+ compare);
+ });
+ }
+
+ {
+ // move(first, last, dest)
+ assert_non_throwing([=, &policy] {
+ (void)std::move(policy, std::move(first1), std::move(last1), std::move(dest));
+ });
+ }
+
+ {
+ auto pred = maybe_throw(tokens[5], [](int x) -> bool { return x % 2 == 0; });
+
+ // replace_if(first, last, pred, val)
+ assert_non_throwing([=, &policy] {
+ (void)std::replace_if(policy, std::move(first1), std::move(last1), pred, val);
+ });
+
+ // replace(first, last, val1, val2)
+ assert_non_throwing([=, &policy] {
+ (void)std::replace(policy, std::move(first1), std::move(last1), val, val);
+ });
+
+ // replace_copy_if(first, last, dest, pred, val)
+ assert_non_throwing([=, &policy] {
+ (void)std::replace_copy_if(policy, std::move(first1), std::move(last1), std::move(dest), pred, val);
+ });
+
+ // replace_copy(first, last, dest, val1, val2)
+ assert_non_throwing([=, &policy] {
+ (void)std::replace_copy(policy, std::move(first1), std::move(last1), std::move(dest), val, val);
+ });
+ }
+
+ {
+ auto mid1 = util::throw_on_move_iterator(std::begin(a) + 2, tokens[5].active() ? 1 : -1);
+
+ // rotate_copy(first, mid, last, dest)
+ assert_non_throwing([=, &policy] {
+ (void)std::rotate_copy(policy, std::move(first1), std::move(mid1), std::move(last1), std::move(dest));
+ });
+ }
+
+ {
+ auto compare = maybe_throw(tokens[5], [](int x, int y) -> bool { return x < y; });
+
+ // sort(first, last)
+ assert_non_throwing([=, &policy] { (void)std::sort(policy, std::move(first1), std::move(last1)); });
+
+ // sort(first, last, comp)
+ assert_non_throwing([=, &policy] { (void)std::sort(policy, std::move(first1), std::move(last1), compare); });
+
+ // stable_sort(first, last)
+ assert_non_throwing([=, &policy] { (void)std::stable_sort(policy, std::move(first1), std::move(last1)); });
+
+ // stable_sort(first, last, comp)
+ assert_non_throwing([=, &policy] {
+ (void)std::stable_sort(policy, std::move(first1), std::move(last1), compare);
+ });
+ }
+
+ {
+ auto unary = maybe_throw(tokens[5], [](int x) -> int { return x * 2; });
+ auto binary = maybe_throw(tokens[5], [](int x, int y) -> int { return x * y; });
+
+ // transform(first, last, dest, func)
+ assert_non_throwing([=, &policy] {
+ (void)std::transform(policy, std::move(first1), std::move(last1), std::move(dest), unary);
+ });
+
+ // transform(first1, last1, first2, dest, func)
+ assert_non_throwing([=, &policy] {
+ (void)std::transform(policy, std::move(first1), std::move(last1), std::move(first2), std::move(dest), binary);
+ });
+ }
+
+ {
+ auto reduction = maybe_throw(tokens[5], [](int x, int y) -> int { return x + y; });
+ auto transform_unary = maybe_throw(tokens[6], [](int x) -> int { return x * 2; });
+ auto transform_binary = maybe_throw(tokens[6], [](int x, int y) -> int { return x * y; });
+
+ // transform_reduce(first1, last1, first2, init)
+ assert_non_throwing([=, &policy] {
+ (void)std::transform_reduce(policy, std::move(first1), std::move(last1), std::move(first2), init);
+ });
+
+ // transform_reduce(first1, last1, init, reduce, transform)
+ assert_non_throwing([=, &policy] {
+ (void)std::transform_reduce(policy, std::move(first1), std::move(last1), init, reduction, transform_unary);
+ });
+
+ // transform_reduce(first1, last1, first2, init, reduce, transform)
+ assert_non_throwing([=, &policy] {
+ (void)std::transform_reduce(
+ policy, std::move(first1), std::move(last1), std::move(first2), init, reduction, transform_binary);
+ });
+ }
+
+ {
+ auto reduction = maybe_throw(tokens[5], [](int x, int y) -> int { return x + y; });
+
+ // reduce(first, last)
+ assert_non_throwing([=, &policy] { (void)std::reduce(policy, std::move(first1), std::move(last1)); });
+
+ // reduce(first, last, init)
+ assert_non_throwing([=, &policy] { (void)std::reduce(policy, std::move(first1), std::move(last1), init); });
+
+ // reduce(first, last, init, binop)
+ assert_non_throwing([=, &policy] {
+ (void)std::reduce(policy, std::move(first1), std::move(last1), init, reduction);
+ });
+ }
+ }
+ });
+}
diff --git a/libcxx/test/std/algorithms/numeric.ops/reduce/pstl.reduce.pass.cpp b/libcxx/test/std/numerics/numeric.ops/reduce/pstl.reduce.pass.cpp
similarity index 99%
rename from libcxx/test/std/algorithms/numeric.ops/reduce/pstl.reduce.pass.cpp
rename to libcxx/test/std/numerics/numeric.ops/reduce/pstl.reduce.pass.cpp
index b083c4f80e0b1..f5748d7c823b7 100644
--- a/libcxx/test/std/algorithms/numeric.ops/reduce/pstl.reduce.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/reduce/pstl.reduce.pass.cpp
@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-// <algorithm>
+// <numeric>
// template<class ExecutionPolicy, class ForwardIterator>
// typename iterator_traits<ForwardIterator>::value_type
diff --git a/libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.transform_reduce.binary.pass.cpp b/libcxx/test/std/numerics/numeric.ops/transform.reduce/pstl.transform_reduce.binary.pass.cpp
similarity index 99%
rename from libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.transform_reduce.binary.pass.cpp
rename to libcxx/test/std/numerics/numeric.ops/transform.reduce/pstl.transform_reduce.binary.pass.cpp
index 18b56f237c3e6..6d8bb47ac7dc1 100644
--- a/libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.transform_reduce.binary.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/transform.reduce/pstl.transform_reduce.binary.pass.cpp
@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-// <algorithm>
+// <numeric>
// template<class ExecutionPolicy,
// class ForwardIterator1, class ForwardIterator2, class T>
diff --git a/libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.transform_reduce.unary.pass.cpp b/libcxx/test/std/numerics/numeric.ops/transform.reduce/pstl.transform_reduce.unary.pass.cpp
similarity index 99%
rename from libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.transform_reduce.unary.pass.cpp
rename to libcxx/test/std/numerics/numeric.ops/transform.reduce/pstl.transform_reduce.unary.pass.cpp
index a32a4f85f6334..4cea3d405aa02 100644
--- a/libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.transform_reduce.unary.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/transform.reduce/pstl.transform_reduce.unary.pass.cpp
@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-incomplete-pstl
-// <algorithm>
+// <numeric>
// template<class ExecutionPolicy,
// class ForwardIterator, class T,
More information about the libcxx-commits
mailing list