1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14
10// UNSUPPORTED: no-exceptions
11// `check_assertion.h` requires Unix headers and regex support.
12// UNSUPPORTED: !has-unix-headers, no-localization
13
14// UNSUPPORTED: libcpp-has-no-incomplete-pstl
15
16// check that std::replace(ExecutionPolicy), std::replace_if(ExecutionPolicy), std::replace_copy(ExecutionPolicy)
17// and std::replace_copy_if(ExecutionPolicy) terminate on user-thrown exceptions
18
19#include <algorithm>
20
21#include "check_assertion.h"
22#include "test_execution_policies.h"
23#include "test_iterators.h"
24
25struct ThrowOnCompare {};
26
27#ifndef TEST_HAS_NO_EXCEPTIONS
28bool operator==(ThrowOnCompare, ThrowOnCompare) { throw int{}; }
29#endif
30
31int main(int, char**) {
32 test_execution_policies([&](auto&& policy) {
33 // std::replace
34 EXPECT_STD_TERMINATE([&] {
35 ThrowOnCompare a[2]{};
36 (void)std::replace(policy, std::begin(arr&: a), std::end(arr&: a), ThrowOnCompare{}, ThrowOnCompare{});
37 });
38 EXPECT_STD_TERMINATE([&] {
39 try {
40 int a[] = {1, 2};
41 (void)std::replace(
42 policy, util::throw_on_move_iterator(std::begin(a), 1), util::throw_on_move_iterator(std::end(a), 1), 1, 2);
43 } catch (const util::iterator_error&) {
44 assert(false);
45 }
46 std::terminate(); // make the test pass in case the algorithm didn't move the iterator
47 });
48
49 // std::replace_if
50 EXPECT_STD_TERMINATE([&] {
51 ThrowOnCompare a[2]{};
52 (void)std::replace_if(
53 policy, std::begin(arr&: a), std::end(arr&: a), [](ThrowOnCompare&) -> bool { throw int{}; }, ThrowOnCompare{});
54 });
55 EXPECT_STD_TERMINATE([&] {
56 try {
57 int a[] = {1, 2};
58 (void)std::replace_if(
59 policy,
60 util::throw_on_move_iterator(std::begin(a), 1),
61 util::throw_on_move_iterator(std::end(a), 1),
62 [](int) { return true; },
63 2);
64 } catch (const util::iterator_error&) {
65 assert(false);
66 }
67 std::terminate(); // make the test pass in case the algorithm didn't move the iterator
68 });
69
70 // std::replace_copy
71 EXPECT_STD_TERMINATE([&] {
72 ThrowOnCompare a[2]{};
73 (void)std::replace_copy(policy, std::begin(arr&: a), std::end(arr&: a), std::begin(arr&: a), ThrowOnCompare{}, ThrowOnCompare{});
74 });
75 EXPECT_STD_TERMINATE([&] {
76 try {
77 int a[] = {1, 2};
78 (void)std::replace_copy(
79 policy,
80 util::throw_on_move_iterator(std::begin(a), 1),
81 util::throw_on_move_iterator(std::end(a), 1),
82 util::throw_on_move_iterator(std::begin(a), 1),
83 1,
84 2);
85 } catch (const util::iterator_error&) {
86 assert(false);
87 }
88 std::terminate(); // make the test pass in case the algorithm didn't move the iterator
89 });
90
91 // std::replace_copy_if
92 EXPECT_STD_TERMINATE([&] {
93 ThrowOnCompare a[2]{};
94 (void)std::replace_copy_if(
95 policy,
96 std::begin(arr&: a),
97 std::end(arr&: a),
98 std::begin(arr&: a),
99 [](ThrowOnCompare& i) { return i == i; },
100 ThrowOnCompare{});
101 });
102 EXPECT_STD_TERMINATE([&] {
103 try {
104 int a[] = {1, 2};
105 (void)std::replace_copy_if(
106 policy,
107 util::throw_on_move_iterator(std::begin(a), 1),
108 util::throw_on_move_iterator(std::end(a), 1),
109 util::throw_on_move_iterator(std::begin(a), 1),
110 [](int) { return true; },
111 2);
112 } catch (const util::iterator_error&) {
113 assert(false);
114 }
115 std::terminate(); // make the test pass in case the algorithm didn't move the iterator
116 });
117 });
118}
119

source code of libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.exception_handling.pass.cpp