// -*- C++ -*- //===-- replace.pass.cpp --------------------------------------------------===// // // 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++98, c++03, c++11, c++14 #include "support/pstl_test_config.h" #include #include #include "support/utils.h" using namespace TestUtils; // This class is needed to check the self-copying struct copy_int { int32_t value; int32_t copied_times = 0; constexpr explicit copy_int(int32_t val = 0) : value(val) {} constexpr copy_int& operator=(const copy_int& other) { if (&other == this) copied_times++; else { value = other.value; copied_times = other.copied_times; } return *this; } constexpr bool operator==(const copy_int& other) const { return (value == other.value); } }; template struct test_one_policy { std::size_t len; Iterator data_b; Iterator data_e; test_one_policy(Iterator data_, std::size_t len_) { len = len_; data_b = data_; data_e = std::next(data_b, len); } template void operator()(ExecutionPolicy&& exec, Iterator1 expected_b, Iterator1 expected_e, Iterator2 actual_b, Iterator2 actual_e, Predicate pred, const T& value, const T& old_value) { using namespace std; copy(data_b, data_e, expected_b); copy(data_b, data_e, actual_b); replace(expected_b, expected_e, old_value, value); replace(exec, actual_b, actual_e, old_value, value); EXPECT_TRUE((check(actual_b, actual_e)), "wrong result of self assignment check"); EXPECT_TRUE(equal(expected_b, expected_e, actual_b), "wrong result of replace"); copy(data_b, data_e, expected_b); copy(data_b, data_e, actual_b); replace_if(expected_b, expected_e, pred, value); replace_if(exec, actual_b, actual_e, pred, value); EXPECT_TRUE(equal(expected_b, expected_e, actual_b), "wrong result of replace_if"); } template bool check(Iterator1, Iterator1) { return true; } template typename std::enable_if::value, bool>::type_t check(Iterator1 b, Iterator1 e) { return std::all_of(b, e, [](const copy_int& elem) { return elem.copied_times == 0; }); } }; template void test(Pred pred) { typedef typename Sequence::iterator iterator_type; const std::size_t max_len = 100000; static constexpr T1 value = T1(0); static constexpr T1 new_value = T1(666); Sequence expected(max_len); Sequence actual(max_len); Sequence data(max_len, [](std::size_t i) { if (i % 3 == 2) { return T1(i); } else { return value; } }); for (std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::size_t(3.1415 * len)) { test_one_policy temp(data.begin(), len); invoke_on_all_policies(temp, expected.begin(), expected.begin() + len, actual.begin(), actual.begin() + len, pred, new_value, value); } } template struct test_non_const { template void operator()(Policy&& exec, Iterator iter) { auto is_even = [&](float64_t v) { uint32_t i = (uint32_t)v; return i % 2 == 0; }; invoke_if(exec, [&]() { replace_if(exec, iter, iter, non_const(is_even), T(0)); }); } }; int main() { test(__pstl::__internal::__equal_value(666)); test([](const uint16_t& elem) { return elem % 3 < 2; }); test([](const float64_t& elem) { return elem * elem - 3.5 * elem > 10; }); test([](const copy_int& val) { return val.value / 5 > 2; }); test_algo_basic_single(run_for_rnd_fw>()); std::cout << done() << std::endl; return 0; }