diff --git a/libcxx/include/__algorithm/pstl_copy.h b/libcxx/include/__algorithm/pstl_copy.h index f35bb9713ef14..5f071bd69229b 100644 --- a/libcxx/include/__algorithm/pstl_copy.h +++ b/libcxx/include/__algorithm/pstl_copy.h @@ -95,10 +95,12 @@ template 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 6ff57cac334eb..cc00d2a5a2194 100644 --- a/libcxx/include/__algorithm/pstl_count.h +++ b/libcxx/include/__algorithm/pstl_count.h @@ -87,8 +87,8 @@ template , enable_if_t, 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 , enable_if_t, 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 3b30a7bc9b456..af106a455bd1f 100644 --- a/libcxx/include/__algorithm/pstl_find.h +++ b/libcxx/include/__algorithm/pstl_find.h @@ -65,8 +65,8 @@ template , enable_if_t, 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 , enable_if_t, 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 886af290d7f25..869985e517df0 100644 --- a/libcxx/include/__algorithm/pstl_generate.h +++ b/libcxx/include/__algorithm/pstl_generate.h @@ -40,8 +40,8 @@ template , enable_if_t, 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 , enable_if_t, 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 108bb1e432526..60a2ea568f293 100644 --- a/libcxx/include/__algorithm/pstl_is_partitioned.h +++ b/libcxx/include/__algorithm/pstl_is_partitioned.h @@ -41,7 +41,7 @@ template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional __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 d03cd8c7fbd58..46af80eb36660 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 @@ -34,26 +35,26 @@ template , + class _Comp, class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, enable_if_t, 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 , 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 , enable_if_t, 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 (__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 - -#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 - -#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 - -#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 - -#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 - -#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 - -#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 - -#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 - -#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 - -#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 - -#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 - -#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 - -#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 - -#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 - -#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 - -#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 + +// +// +// +// Check that PSTL algorithms terminate on user-thrown exceptions. + +#include +#include + +#include "check_assertion.h" +#include "test_execution_policies.h" +#include "test_iterators.h" + +template +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 +struct on_scope_exit { + explicit on_scope_exit(Func func) : func_(func) {} + ~on_scope_exit() { func_(); } + +private: + Func func_; +}; +template +on_scope_exit(Func) -> on_scope_exit; + +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 -// +// // template // typename iterator_traits::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 -// +// // template 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 -// +// // template