summaryrefslogtreecommitdiffstats
path: root/pstl/test/std/algorithms/alg.modifying.operations
diff options
context:
space:
mode:
authorLouis Dionne <ldionne@apple.com>2019-03-27 21:28:24 +0000
committerLouis Dionne <ldionne@apple.com>2019-03-27 21:28:24 +0000
commit3b62047b8b2209bed57d239f581bdbfc91a10b94 (patch)
treee321a0dea2d7355c3eca7c9cf9ae1f2b89823c1d /pstl/test/std/algorithms/alg.modifying.operations
parent4bc38cfe297746858a7159bd4a537261d628b47e (diff)
downloadbcm5719-llvm-3b62047b8b2209bed57d239f581bdbfc91a10b94.tar.gz
bcm5719-llvm-3b62047b8b2209bed57d239f581bdbfc91a10b94.zip
Restructure test suite to follow libc++ standard layout
Summary: Subsumes changes requested in https://reviews.llvm.org/D59110 Reviewers: EricWF, ldionne Subscribers: mgorny, krytarowski, jfb, jdoerfert, libcxx-commits Differential Revision: https://reviews.llvm.org/D59856 llvm-svn: 357124
Diffstat (limited to 'pstl/test/std/algorithms/alg.modifying.operations')
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp150
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/is_partitioned.pass.cpp104
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/partition.pass.cpp183
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/partition_copy.pass.cpp120
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/alg.reverse/reverse.pass.cpp108
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/alg.reverse/reverse_copy.pass.cpp137
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/copy_move.pass.cpp204
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/fill.pass.cpp104
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/generate.pass.cpp107
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/remove.pass.cpp157
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/remove_copy.pass.cpp94
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/replace.pass.cpp163
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/replace_copy.pass.cpp108
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/rotate.pass.cpp177
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/rotate_copy.pass.cpp150
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/swap_ranges.pass.cpp137
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/transform_binary.pass.cpp124
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/transform_unary.pass.cpp94
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/unique.pass.cpp160
-rw-r--r--pstl/test/std/algorithms/alg.modifying.operations/unique_copy_equal.pass.cpp138
20 files changed, 2719 insertions, 0 deletions
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp
new file mode 100644
index 00000000000..5e6ea34ed80
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp
@@ -0,0 +1,150 @@
+// -*- C++ -*-
+//===-- copy_if.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
+//
+//===----------------------------------------------------------------------===//
+
+// Tests for copy_if and remove_copy_if
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+struct run_copy_if
+{
+#if __PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN // dummy specializations to skip testing in case of broken configuration
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
+ typename Predicate, typename T>
+ void
+ operator()(pstl::execution::parallel_policy, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
+ Predicate pred, T trash)
+ {
+ }
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
+ typename Predicate, typename T>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
+ OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
+ OutputIterator2 expected_last, Size n, Predicate pred, T trash)
+ {
+ }
+#endif
+
+ template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
+ typename Predicate, typename T>
+ void
+ operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
+ Predicate pred, T trash)
+ {
+ // Cleaning
+ std::fill_n(expected_first, n, trash);
+ std::fill_n(out_first, n, trash);
+
+ // Run copy_if
+ auto i = copy_if(first, last, expected_first, pred);
+ auto k = copy_if(exec, first, last, out_first, pred);
+ EXPECT_EQ_N(expected_first, out_first, n, "wrong copy_if effect");
+ for (size_t j = 0; j < GuardSize; ++j)
+ {
+ ++k;
+ }
+ EXPECT_TRUE(out_last == k, "wrong return value from copy_if");
+
+ // Cleaning
+ std::fill_n(expected_first, n, trash);
+ std::fill_n(out_first, n, trash);
+ // Run remove_copy_if
+ i = remove_copy_if(first, last, expected_first, [=](const T& x) { return !pred(x); });
+ k = remove_copy_if(exec, first, last, out_first, [=](const T& x) { return !pred(x); });
+ EXPECT_EQ_N(expected_first, out_first, n, "wrong remove_copy_if effect");
+ for (size_t j = 0; j < GuardSize; ++j)
+ {
+ ++k;
+ }
+ EXPECT_TRUE(out_last == k, "wrong return value from remove_copy_if");
+ }
+};
+
+template <typename T, typename Predicate, typename Convert>
+void
+test(T trash, Predicate pred, Convert convert, bool check_weakness = true)
+{
+ // Try sequences of various lengths.
+ for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ // count is number of output elements, plus a handful
+ // more for sake of detecting buffer overruns.
+ size_t count = GuardSize;
+ Sequence<T> in(n, [&](size_t k) -> T {
+ T val = convert(n ^ k);
+ count += pred(val) ? 1 : 0;
+ return val;
+ });
+
+ Sequence<T> out(count, [=](size_t) { return trash; });
+ Sequence<T> expected(count, [=](size_t) { return trash; });
+ if (check_weakness)
+ {
+ auto expected_result = copy_if(in.cfbegin(), in.cfend(), expected.begin(), pred);
+ size_t m = expected_result - expected.begin();
+ EXPECT_TRUE(n / 4 <= m && m <= 3 * (n + 1) / 4, "weak test for copy_if");
+ }
+ invoke_on_all_policies(run_copy_if(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
+ expected.end(), count, pred, trash);
+ invoke_on_all_policies(run_copy_if(), in.cbegin(), in.cend(), out.begin(), out.end(), expected.begin(),
+ expected.end(), count, pred, trash);
+ }
+}
+
+struct test_non_const
+{
+ template <typename Policy, typename InputIterator, typename OutputInterator>
+ void
+ operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
+ {
+ auto is_even = [&](float64_t v) {
+ uint32_t i = (uint32_t)v;
+ return i % 2 == 0;
+ };
+ copy_if(exec, input_iter, input_iter, out_iter, non_const(is_even));
+
+ invoke_if(exec, [&]() { remove_copy_if(exec, input_iter, input_iter, out_iter, non_const(is_even)); });
+ }
+};
+
+int32_t
+main()
+{
+ test<float64_t>(-666.0, [](const float64_t& x) { return x * x <= 1024; },
+ [](size_t j) { return ((j + 1) % 7 & 2) != 0 ? float64_t(j % 32) : float64_t(j % 33 + 34); });
+
+ test<int32_t>(-666, [](const int32_t& x) { return x != 42; },
+ [](size_t j) { return ((j + 1) % 5 & 2) != 0 ? int32_t(j + 1) : 42; });
+
+#if !__PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
+ test<Number>(Number(42, OddTag()), IsMultiple(3, OddTag()), [](int32_t j) { return Number(j, OddTag()); });
+#endif
+
+#if !__PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
+ test<int32_t>(-666, [](const int32_t& x) { return true; }, [](size_t j) { return j; }, false);
+#endif
+
+ test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/is_partitioned.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/is_partitioned.pass.cpp
new file mode 100644
index 00000000000..5d665d25516
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/is_partitioned.pass.cpp
@@ -0,0 +1,104 @@
+// -*- C++ -*-
+//===-- is_partitioned.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+struct test_one_policy
+{
+ //dummy specialization by policy type, in case of broken configuration
+#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN
+
+ template <typename Iterator1, typename Predicate>
+ void
+ operator()(pstl::execution::unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred)
+ {
+ }
+ template <typename Iterator1, typename Predicate>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred)
+ {
+ }
+#endif
+
+ template <typename ExecutionPolicy, typename Iterator1, typename Predicate>
+ void
+ operator()(ExecutionPolicy&& exec, Iterator1 begin1, Iterator1 end1, Predicate pred)
+ {
+ const bool expected = std::is_partitioned(begin1, end1, pred);
+ const bool actual = std::is_partitioned(exec, begin1, end1, pred);
+ EXPECT_TRUE(actual == expected, "wrong return result from is_partitioned");
+ }
+};
+
+template <typename T, typename Predicate>
+void
+test(Predicate pred)
+{
+
+ const std::size_t max_n = 1000000;
+ Sequence<T> in(max_n, [](std::size_t k) { return T(k); });
+
+ for (std::size_t n1 = 0; n1 <= max_n; n1 = n1 <= 16 ? n1 + 1 : std::size_t(3.1415 * n1))
+ {
+ invoke_on_all_policies(test_one_policy(), in.begin(), in.begin() + n1, pred);
+ std::partition(in.begin(), in.begin() + n1, pred);
+ invoke_on_all_policies(test_one_policy(), in.cbegin(), in.cbegin() + n1, pred);
+ }
+}
+
+template <typename T>
+struct LocalWrapper
+{
+ explicit LocalWrapper(std::size_t k) : my_val(k) {}
+
+ private:
+ T my_val;
+};
+
+struct test_non_const
+{
+ template <typename Policy, typename Iterator>
+ 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, [&]() { is_partitioned(exec, iter, iter, non_const(is_even)); });
+ }
+};
+
+int32_t
+main()
+{
+ test<float64_t>([](const float64_t x) { return x < 0; });
+ test<int32_t>([](const int32_t x) { return x > 1000; });
+ test<uint16_t>([](const uint16_t x) { return x % 5 < 3; });
+#if !__PSTL_ICC_18_TEST_EARLY_EXIT_MONOTONIC_RELEASE_BROKEN && !__PSTL_ICC_19_TEST_IS_PARTITIONED_RELEASE_BROKEN
+ test<LocalWrapper<float64_t>>([](const LocalWrapper<float64_t>& x) { return true; });
+#endif
+
+ test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/partition.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/partition.pass.cpp
new file mode 100644
index 00000000000..b79a27a44a0
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/partition.pass.cpp
@@ -0,0 +1,183 @@
+// -*- C++ -*-
+//===-- partition.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
+//
+//===----------------------------------------------------------------------===//
+
+// Tests for stable_partition and partition
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+#include <iterator>
+#include <type_traits>
+
+using namespace TestUtils;
+
+template <typename T>
+struct DataType
+{
+ explicit DataType(int32_t k) : my_val(k) {}
+ DataType(DataType&& input) { my_val = std::move(input.my_val); }
+ DataType&
+ operator=(DataType&& input)
+ {
+ my_val = std::move(input.my_val);
+ return *this;
+ }
+ T
+ get_val() const
+ {
+ return my_val;
+ }
+
+ friend std::ostream&
+ operator<<(std::ostream& stream, const DataType<T>& input)
+ {
+ return stream << input.my_val;
+ }
+
+ private:
+ T my_val;
+};
+
+template <typename Iterator>
+typename std::enable_if<std::is_trivial<typename std::iterator_traits<Iterator>::value_type>::value, bool>::type
+is_equal(Iterator first, Iterator last, Iterator d_first)
+{
+ return std::equal(first, last, d_first);
+}
+
+template <typename Iterator>
+typename std::enable_if<!std::is_trivial<typename std::iterator_traits<Iterator>::value_type>::value, bool>::type
+is_equal(Iterator first, Iterator last, Iterator d_first)
+{
+ return true;
+}
+
+struct test_one_policy
+{
+#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
+ __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specializations to skip testing in case of broken configuration
+ template <typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
+ void
+ operator()(pstl::execution::unsequenced_policy, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last,
+ Size n, UnaryOp unary_op, Generator generator)
+ {
+ }
+
+ template <typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, BiDirIt first, BiDirIt last, BiDirIt exp_first,
+ BiDirIt exp_last, Size n, UnaryOp unary_op, Generator generator)
+ {
+ }
+#elif __PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN //dummy specializations to skip testing in case of broken configuration
+ template <typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
+ void
+ operator()(pstl::execution::parallel_policy, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last,
+ Size n, UnaryOp unary_op, Generator generator)
+ {
+ }
+
+ template <typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, BiDirIt first, BiDirIt last, BiDirIt exp_first,
+ BiDirIt exp_last, Size n, UnaryOp unary_op, Generator generator)
+ {
+ }
+#endif
+
+ template <typename Policy, typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
+ typename std::enable_if<!is_same_iterator_category<BiDirIt, std::forward_iterator_tag>::value, void>::type
+ operator()(Policy&& exec, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last, Size n,
+ UnaryOp unary_op, Generator generator)
+ {
+ // partition
+ {
+ fill_data(first, last, generator);
+ BiDirIt actual_ret = std::partition(exec, first, last, unary_op);
+ EXPECT_TRUE(std::all_of(first, actual_ret, unary_op) && !std::any_of(actual_ret, last, unary_op),
+ "wrong effect from partition");
+ }
+ // stable_partition
+ {
+ fill_data(exp_first, exp_last, generator);
+ BiDirIt exp_ret = std::stable_partition(exp_first, exp_last, unary_op);
+ fill_data(first, last, generator);
+ BiDirIt actual_ret = std::stable_partition(exec, first, last, unary_op);
+
+ EXPECT_TRUE(std::distance(first, actual_ret) == std::distance(exp_first, exp_ret),
+ "wrong result from stable_partition");
+ EXPECT_TRUE((is_equal<BiDirIt>(exp_first, exp_last, first)), "wrong effect from stable_partition");
+ }
+ }
+ template <typename Policy, typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
+ typename std::enable_if<is_same_iterator_category<BiDirIt, std::forward_iterator_tag>::value, void>::type
+ operator()(Policy&& exec, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last, Size n,
+ UnaryOp unary_op, Generator generator)
+ {
+ }
+};
+
+template <typename T, typename Generator, typename UnaryPred>
+void
+test_by_type(Generator generator, UnaryPred pred)
+{
+
+ using namespace std;
+ size_t max_size = 100000;
+ Sequence<T> in(max_size, [](size_t v) { return T(v); });
+ Sequence<T> exp(max_size, [](size_t v) { return T(v); });
+
+ for (size_t n = 0; n <= max_size; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ invoke_on_all_policies(test_one_policy(), in.begin(), in.begin() + n, exp.begin(), exp.begin() + n, n, pred,
+ generator);
+ }
+}
+
+struct test_non_const
+{
+ template <typename Policy, typename Iterator>
+ 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, [&]() {
+ partition(exec, iter, iter, non_const(is_even));
+ stable_partition(exec, iter, iter, non_const(is_even));
+ });
+ }
+};
+
+int32_t
+main()
+{
+#if !__PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
+ test_by_type<int32_t>([](int32_t i) { return i; }, [](int32_t) { return true; });
+#endif
+ test_by_type<float64_t>([](int32_t i) { return -i; }, [](const float64_t x) { return x < 0; });
+ test_by_type<int64_t>([](int32_t i) { return i + 1; }, [](int64_t x) { return x % 3 == 0; });
+ test_by_type<DataType<float32_t>>([](int32_t i) { return DataType<float32_t>(2 * i + 1); },
+ [](const DataType<float32_t>& x) { return x.get_val() < 0; });
+
+ test_algo_basic_single<int32_t>(run_for_rnd_bi<test_non_const>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/partition_copy.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/partition_copy.pass.cpp
new file mode 100644
index 00000000000..c27e51ca798
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/alg.partitions/partition_copy.pass.cpp
@@ -0,0 +1,120 @@
+// -*- C++ -*-
+//===-- partition_copy.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
+//
+//===----------------------------------------------------------------------===//
+
+// Tests for stable_partition and partition_copy
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+#include <cstdlib>
+#include <iterator>
+
+using namespace TestUtils;
+
+struct test_partition_copy
+{
+ template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2,
+ typename UnaryOp>
+ void
+ operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator true_first,
+ OutputIterator true_last, OutputIterator2 false_first, OutputIterator2 false_last, UnaryOp unary_op)
+ {
+
+ auto actual_ret = std::partition_copy(exec, first, last, true_first, false_first, unary_op);
+
+ EXPECT_TRUE(std::distance(true_first, actual_ret.first) == std::count_if(first, last, unary_op),
+ "partition_copy has wrong effect from true sequence");
+ EXPECT_TRUE(std::distance(false_first, actual_ret.second) ==
+ std::count_if(first, last, __pstl::internal::not_pred<UnaryOp>(unary_op)),
+ "partition_copy has wrong effect from false sequence");
+ }
+
+ //dummy specialization by iterator type and policy type, in case of broken configuration
+#if __PSTL_ICC_1800_TEST_MONOTONIC_RELEASE_64_BROKEN
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename UnaryOp>
+ void
+ operator()(pstl::execution::unsequenced_policy, std::reverse_iterator<InputIterator> first,
+ std::reverse_iterator<InputIterator> last, std::reverse_iterator<OutputIterator> true_first,
+ std::reverse_iterator<OutputIterator> true_last, std::reverse_iterator<OutputIterator2> false_first,
+ OutputIterator2 false_last, UnaryOp unary_op)
+ {
+ }
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename UnaryOp>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, std::reverse_iterator<InputIterator> first,
+ std::reverse_iterator<InputIterator> last, std::reverse_iterator<OutputIterator> true_first,
+ std::reverse_iterator<OutputIterator> true_last, std::reverse_iterator<OutputIterator2> false_first,
+ OutputIterator2 false_last, UnaryOp unary_op)
+ {
+ }
+#endif
+};
+
+template <typename T, typename UnaryPred>
+void
+test(UnaryPred pred)
+{
+
+ const std::size_t max_size = 100000;
+ Sequence<T> in(max_size, [](std::size_t v) -> T { return T(v); });
+ Sequence<T> actual_true(max_size);
+ Sequence<T> actual_false(max_size);
+ for (std::size_t n = 0; n <= max_size; n = n <= 16 ? n + 1 : std::size_t(3.1415 * n))
+ {
+
+ // for non-const input iterators
+ invoke_on_all_policies(test_partition_copy(), in.begin(), in.begin() + n, actual_true.begin(),
+ actual_true.begin() + n, actual_false.begin(), actual_false.begin() + n, pred);
+
+ // for const input iterators
+ invoke_on_all_policies(test_partition_copy(), in.cbegin(), in.cbegin() + n, actual_true.begin(),
+ actual_true.begin() + n, actual_false.begin(), actual_false.begin() + n, pred);
+ }
+}
+
+struct test_non_const
+{
+ template <typename Policy, typename InputIterator, typename OutputInterator>
+ void
+ operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
+ {
+ auto is_even = [&](float64_t v) {
+ uint32_t i = (uint32_t)v;
+ return i % 2 == 0;
+ };
+
+ partition_copy(exec, input_iter, input_iter, out_iter, out_iter, non_const(is_even));
+ }
+};
+
+int32_t
+main()
+{
+ test<int32_t>([](const int32_t value) { return value % 2; });
+
+#if !__PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
+ test<int32_t>([](const int32_t value) { return true; });
+#endif
+
+ test<float64_t>([](const float64_t value) { return value > 2 << 6; });
+ test<Wrapper<float64_t>>([](const Wrapper<float64_t>& value) -> bool { return value.get_my_field() != nullptr; });
+
+ test_algo_basic_double<int32_t>(run_for_rnd_bi<test_non_const>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/alg.reverse/reverse.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/alg.reverse/reverse.pass.cpp
new file mode 100644
index 00000000000..ad722df3a83
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/alg.reverse/reverse.pass.cpp
@@ -0,0 +1,108 @@
+// -*- C++ -*-
+//===-- reverse.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include <iterator>
+
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+struct test_one_policy
+{
+#if __PSTL_ICC_18_VC141_TEST_SIMD_LAMBDA_RELEASE_BROKEN || __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
+ __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
+ template <typename Iterator1, typename Iterator2>
+ typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
+ operator()(pstl::execution::unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
+ Iterator2 actual_e)
+ {
+ }
+ template <typename Iterator1, typename Iterator2>
+ typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
+ operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
+ Iterator2 actual_e)
+ {
+ }
+#endif
+
+ template <typename ExecutionPolicy, typename Iterator1, typename Iterator2>
+ typename std::enable_if<!is_same_iterator_category<Iterator1, std::forward_iterator_tag>::value>::type
+ operator()(ExecutionPolicy&& exec, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b, Iterator2 actual_e)
+ {
+ using namespace std;
+
+ copy(data_b, data_e, actual_b);
+
+ reverse(exec, actual_b, actual_e);
+
+ bool check = equal(data_b, data_e, reverse_iterator<Iterator2>(actual_e));
+
+ EXPECT_TRUE(check, "wrong result of reverse");
+ }
+
+ template <typename ExecutionPolicy, typename Iterator1, typename Iterator2>
+ typename std::enable_if<is_same_iterator_category<Iterator1, std::forward_iterator_tag>::value>::type
+ operator()(ExecutionPolicy&& exec, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b, Iterator2 actual_e)
+ {
+ }
+};
+
+template <typename T>
+void
+test()
+{
+ const std::size_t max_len = 100000;
+
+ Sequence<T> actual(max_len);
+
+ Sequence<T> data(max_len, [](std::size_t i) { return T(i); });
+
+ for (std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::size_t(3.1415 * len))
+ {
+ invoke_on_all_policies(test_one_policy(), data.begin(), data.begin() + len, actual.begin(),
+ actual.begin() + len);
+ }
+}
+
+template <typename T>
+struct wrapper
+{
+ T t;
+ wrapper() {}
+ explicit wrapper(T t_) : t(t_) {}
+ bool
+ operator==(const wrapper<T>& a) const
+ {
+ return t == a.t;
+ }
+};
+
+int32_t
+main()
+{
+ test<int32_t>();
+ test<uint16_t>();
+ test<float64_t>();
+#if !__PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
+ test<wrapper<float64_t>>();
+#endif
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/alg.reverse/reverse_copy.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/alg.reverse/reverse_copy.pass.cpp
new file mode 100644
index 00000000000..d26f41f175d
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/alg.reverse/reverse_copy.pass.cpp
@@ -0,0 +1,137 @@
+// -*- C++ -*-
+//===-- reverse_copy.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include <iterator>
+
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+template <typename T>
+struct wrapper
+{
+ T t;
+ wrapper() {}
+ explicit wrapper(T t_) : t(t_) {}
+ wrapper&
+ operator=(const T& t_)
+ {
+ t = t_;
+ return *this;
+ }
+ bool
+ operator==(const wrapper& t_) const
+ {
+ return t == t_.t;
+ }
+};
+
+template <typename T1, typename T2>
+bool
+eq(const wrapper<T1>& a, const wrapper<T2>& b)
+{
+ return a.t == b.t;
+}
+
+template <typename T1, typename T2>
+bool
+eq(const T1& a, const T2& b)
+{
+ return a == b;
+}
+
+// we need to save state here, because we need to test with different types of iterators
+// due to the caller invoke_on_all_policies does forcing modification passed iterator type to cover additional usage cases.
+template <typename Iterator>
+struct test_one_policy
+{
+ Iterator data_b;
+ Iterator data_e;
+ test_one_policy(Iterator b, Iterator e) : data_b(b), data_e(e) {}
+
+#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
+ __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
+ template <typename Iterator1>
+ typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
+ operator()(pstl::execution::unsequenced_policy, Iterator1 actual_b, Iterator1 actual_e)
+ {
+ }
+ template <typename Iterator1>
+ typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
+ operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 actual_b, Iterator1 actual_e)
+ {
+ }
+#endif
+
+ template <typename ExecutionPolicy, typename Iterator1>
+ void
+ operator()(ExecutionPolicy&& exec, Iterator1 actual_b, Iterator1 actual_e)
+ {
+ using namespace std;
+ using T = typename iterator_traits<Iterator1>::value_type;
+ using DifferenceType = typename iterator_traits<Iterator1>::difference_type;
+
+ fill(actual_b, actual_e, T(-123));
+ Iterator1 actual_return = reverse_copy(exec, data_b, data_e, actual_b);
+
+ EXPECT_TRUE(actual_return == actual_e, "wrong result of reverse_copy");
+
+ const auto n = std::distance(data_b, data_e);
+ Sequence<T> res(n);
+ std::copy(std::reverse_iterator<Iterator>(data_e), std::reverse_iterator<Iterator>(data_b), res.begin());
+
+ EXPECT_EQ_N(res.begin(), actual_b, n, "wrong effect of reverse_copy");
+ }
+};
+
+template <typename T1, typename T2>
+void
+test()
+{
+ typedef typename Sequence<T1>::iterator iterator_type;
+ typedef typename Sequence<T1>::const_bidirectional_iterator cbi_iterator_type;
+
+ const std::size_t max_len = 100000;
+
+ Sequence<T2> actual(max_len);
+
+ Sequence<T1> data(max_len, [](std::size_t i) { return T1(i); });
+
+ for (std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::size_t(3.1415 * len))
+ {
+ invoke_on_all_policies(test_one_policy<iterator_type>(data.begin(), data.begin() + len), actual.begin(),
+ actual.begin() + len);
+ invoke_on_all_policies(test_one_policy<cbi_iterator_type>(data.cbibegin(), std::next(data.cbibegin(), len)),
+ actual.begin(), actual.begin() + len);
+ }
+}
+
+int32_t
+main()
+{
+ // clang-3.8 fails to correctly auto vectorize the loop in some cases of different types of container's elements,
+ // for example: int32_t and int8_t. This issue isn't detected for clang-3.9 and newer versions.
+ test<int16_t, int8_t>();
+ test<uint16_t, float32_t>();
+ test<float64_t, int64_t>();
+ test<wrapper<float64_t>, wrapper<float64_t>>();
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/copy_move.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/copy_move.pass.cpp
new file mode 100644
index 00000000000..89de3f92c9e
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/copy_move.pass.cpp
@@ -0,0 +1,204 @@
+// -*- C++ -*-
+//===-- copy_move.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
+//
+//===----------------------------------------------------------------------===//
+
+// Tests for copy, move and copy_n
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+struct run_copy
+{
+
+#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
+ __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size, typename T>
+ void
+ operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
+ Size n, T trash)
+ {
+ }
+
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size, typename T>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
+ OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
+ OutputIterator2 expected_last, Size size, Size n, T trash)
+ {
+ }
+#endif
+
+ template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
+ typename T>
+ void
+ operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
+ Size n, T trash)
+ {
+ // Cleaning
+ std::fill_n(expected_first, size, trash);
+ std::fill_n(out_first, size, trash);
+
+ // Run copy
+ copy(first, last, expected_first);
+ auto k = copy(exec, first, last, out_first);
+ for (size_t j = 0; j < GuardSize; ++j)
+ ++k;
+ EXPECT_EQ_N(expected_first, out_first, size, "wrong effect from copy");
+ EXPECT_TRUE(out_last == k, "wrong return value from copy");
+
+ // Cleaning
+ std::fill_n(out_first, size, trash);
+ // Run copy_n
+ k = copy_n(exec, first, n, out_first);
+ for (size_t j = 0; j < GuardSize; ++j)
+ ++k;
+ EXPECT_EQ_N(expected_first, out_first, size, "wrong effect from copy_n");
+ EXPECT_TRUE(out_last == k, "wrong return value from copy_n");
+ }
+};
+
+template <typename T>
+struct run_move
+{
+
+#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
+ __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
+ void
+ operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
+ Size n, T trash)
+ {
+ }
+
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
+ OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
+ OutputIterator2 expected_last, Size size, Size n, T trash)
+ {
+ }
+#endif
+
+ template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
+ void
+ operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
+ Size n, T trash)
+ {
+ // Cleaning
+ std::fill_n(expected_first, size, trash);
+ std::fill_n(out_first, size, trash);
+
+ // Run move
+ move(first, last, expected_first);
+ auto k = move(exec, first, last, out_first);
+ for (size_t j = 0; j < GuardSize; ++j)
+ ++k;
+ EXPECT_EQ_N(expected_first, out_first, size, "wrong effect from move");
+ EXPECT_TRUE(out_last == k, "wrong return value from move");
+ }
+};
+
+template <typename T>
+struct run_move<Wrapper<T>>
+{
+
+#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
+ __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
+ void
+ operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
+ Size n, Wrapper<T> trash)
+ {
+ }
+
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
+ OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
+ OutputIterator2 expected_last, Size size, Size n, Wrapper<T> trash)
+ {
+ }
+#endif
+
+ template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
+ void
+ operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
+ Size n, Wrapper<T> trash)
+ {
+ // Cleaning
+ std::fill_n(out_first, size, trash);
+ Wrapper<T>::SetMoveCount(0);
+
+ // Run move
+ auto k = move(exec, first, last, out_first);
+ for (size_t j = 0; j < GuardSize; ++j)
+ ++k;
+ EXPECT_TRUE(Wrapper<T>::MoveCount() == size, "wrong effect from move");
+ EXPECT_TRUE(out_last == k, "wrong return value from move");
+ }
+};
+
+template <typename T, typename Convert>
+void
+test(T trash, Convert convert)
+{
+ // Try sequences of various lengths.
+ for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ // count is number of output elements, plus a handful
+ // more for sake of detecting buffer overruns.
+ Sequence<T> in(n, [&](size_t k) -> T {
+ T val = convert(n ^ k);
+ return val;
+ });
+
+ const size_t outN = n + GuardSize;
+ Sequence<T> out(outN, [=](size_t) { return trash; });
+ Sequence<T> expected(outN, [=](size_t) { return trash; });
+ invoke_on_all_policies(run_copy(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
+ expected.end(), outN, n, trash);
+ invoke_on_all_policies(run_copy(), in.cbegin(), in.cend(), out.begin(), out.end(), expected.begin(),
+ expected.end(), outN, n, trash);
+ invoke_on_all_policies(run_move<T>(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
+ expected.end(), n, n, trash);
+
+ // For this test const iterator isn't suitable
+ // because const rvalue-reference call copy assignment operator
+ }
+}
+
+int32_t
+main()
+{
+ test<int32_t>(-666, [](size_t j) { return int32_t(j); });
+ test<Wrapper<float64_t>>(Wrapper<float64_t>(-666.0), [](int32_t j) { return Wrapper<float64_t>(j); });
+
+#if !__PSTL_ICC_16_17_TEST_64_TIMEOUT
+ test<float64_t>(-666.0, [](size_t j) { return float64_t(j); });
+ test<Number>(Number(42, OddTag()), [](int32_t j) { return Number(j, OddTag()); });
+#endif
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/fill.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/fill.pass.cpp
new file mode 100644
index 00000000000..19bc150b31b
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/fill.pass.cpp
@@ -0,0 +1,104 @@
+// -*- C++ -*-
+//===-- fill.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+struct test_fill
+{
+ template <typename It, typename T>
+ bool
+ check(It first, It last, const T& value)
+ {
+ for (; first != last; ++first)
+ if (*first != value)
+ return false;
+ return true;
+ }
+
+ template <typename Policy, typename Iterator, typename T>
+ void
+ operator()(Policy&& exec, Iterator first, Iterator last, const T& value)
+ {
+ fill(first, last, T(value + 1)); // initialize memory with different value
+
+ fill(exec, first, last, value);
+ EXPECT_TRUE(check(first, last, value), "fill wrong result");
+ }
+};
+
+struct test_fill_n
+{
+ template <typename It, typename Size, typename T>
+ bool
+ check(It first, Size n, const T& value)
+ {
+ for (Size i = 0; i < n; ++i, ++first)
+ if (*first != value)
+ return false;
+ return true;
+ }
+
+ template <typename Policy, typename Iterator, typename Size, typename T>
+ void
+ operator()(Policy&& exec, Iterator first, Size n, const T& value)
+ {
+ fill_n(first, n, T(value + 1)); // initialize memory with different value
+
+ const Iterator one_past_last = fill_n(exec, first, n, value);
+ const Iterator expected_return = std::next(first, n);
+
+ EXPECT_TRUE(expected_return == one_past_last, "fill_n should return Iterator to one past the element assigned");
+ EXPECT_TRUE(check(first, n, value), "fill_n wrong result");
+
+ //n == -1
+ const Iterator res = fill_n(exec, first, -1, value);
+ EXPECT_TRUE(res == first, "fill_n wrong result for n == -1");
+ }
+};
+
+template <typename T>
+void
+test_fill_by_type(std::size_t n)
+{
+ Sequence<T> in(n, [](std::size_t v) -> T { return T(0); }); //fill with zeros
+ T value = -1;
+
+ invoke_on_all_policies(test_fill(), in.begin(), in.end(), value);
+ invoke_on_all_policies(test_fill_n(), in.begin(), n, value);
+}
+
+int32_t
+main()
+{
+
+ const std::size_t N = 100000;
+
+ for (std::size_t n = 0; n < N; n = n < 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ test_fill_by_type<int32_t>(n);
+ test_fill_by_type<float64_t>(n);
+ }
+
+ std::cout << done() << std::endl;
+
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/generate.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/generate.pass.cpp
new file mode 100644
index 00000000000..9862f14ba62
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/generate.pass.cpp
@@ -0,0 +1,107 @@
+// -*- C++ -*-
+//===-- generate.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include <atomic>
+
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+template <typename T>
+struct Generator_count
+{
+ const T def_val = T(-1);
+ T
+ operator()()
+ {
+ return def_val;
+ }
+ T
+ default_value() const
+ {
+ return def_val;
+ }
+};
+
+struct test_generate
+{
+ template <typename Policy, typename Iterator, typename Size>
+ void
+ operator()(Policy&& exec, Iterator first, Iterator last, Size n)
+ {
+ using namespace std;
+ typedef typename std::iterator_traits<Iterator>::value_type T;
+
+ // Try random-access iterator
+ {
+ Generator_count<T> g;
+ generate(exec, first, last, g);
+ EXPECT_TRUE(std::count(first, last, g.default_value()) == n, "generate wrong result for generate");
+ std::fill(first, last, T(0));
+ }
+
+ {
+ Generator_count<T> g;
+ const auto m = n / 2;
+ auto last = generate_n(exec, first, m, g);
+ EXPECT_TRUE(std::count(first, last, g.default_value()) == m && last == std::next(first, m),
+ "generate_n wrong result for generate_n");
+ std::fill(first, last, T(0));
+ }
+ }
+};
+
+template <typename T>
+void
+test_generate_by_type()
+{
+ for (size_t n = 0; n <= 100000; n = n < 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ Sequence<T> in(n, [](size_t v) -> T { return T(0); }); //fill by zero
+
+ invoke_on_all_policies(test_generate(), in.begin(), in.end(), in.size());
+ }
+}
+
+template <typename T>
+struct test_non_const
+{
+ template <typename Policy, typename Iterator>
+ void
+ operator()(Policy&& exec, Iterator iter)
+ {
+ auto gen = []() { return T(0); };
+
+ generate(exec, iter, iter, non_const(gen));
+ generate_n(exec, iter, 0, non_const(gen));
+ }
+};
+
+int32_t
+main()
+{
+
+ test_generate_by_type<int32_t>();
+ test_generate_by_type<float64_t>();
+
+ test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/remove.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/remove.pass.cpp
new file mode 100644
index 00000000000..82b986bcfbf
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/remove.pass.cpp
@@ -0,0 +1,157 @@
+// -*- C++ -*-
+//===-- remove.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
+//
+//===----------------------------------------------------------------------===//
+
+// Test for remove, remove_if
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+struct run_remove
+{
+#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
+ __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
+ template <typename InputIterator, typename OutputIterator, typename Size, typename T>
+ void
+ operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size n,
+ const T& value)
+ {
+ }
+ template <typename InputIterator, typename OutputIterator, typename Size, typename T>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
+ OutputIterator out_first, OutputIterator out_last, OutputIterator expected_first,
+ OutputIterator expected_last, Size n, const T& value)
+ {
+ }
+#endif
+
+ template <typename Policy, typename InputIterator, typename OutputIterator, typename Size, typename T>
+ void
+ operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size,
+ const T& value)
+ {
+ // Cleaning
+ std::copy(first, last, expected_first);
+ std::copy(first, last, out_first);
+
+ // Run remove
+ OutputIterator i = remove(expected_first, expected_last, value);
+ OutputIterator k = remove(exec, out_first, out_last, value);
+ EXPECT_TRUE(std::distance(expected_first, i) == std::distance(out_first, k), "wrong return value from remove");
+ EXPECT_EQ_N(expected_first, out_first, std::distance(expected_first, i), "wrong remove effect");
+ }
+};
+
+struct run_remove_if
+{
+#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
+ __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
+ template <typename InputIterator, typename OutputIterator, typename Size, typename Predicate>
+ void
+ operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size n,
+ Predicate pred)
+ {
+ }
+ template <typename InputIterator, typename OutputIterator, typename Size, typename Predicate>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
+ OutputIterator out_first, OutputIterator out_last, OutputIterator expected_first,
+ OutputIterator expected_last, Size n, Predicate pred)
+ {
+ }
+#endif
+
+ template <typename Policy, typename InputIterator, typename OutputIterator, typename Size, typename Predicate>
+ void
+ operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size,
+ Predicate pred)
+ {
+ // Cleaning
+ std::copy(first, last, expected_first);
+ std::copy(first, last, out_first);
+
+ // Run remove_if
+ OutputIterator i = remove_if(expected_first, expected_last, pred);
+ OutputIterator k = remove_if(exec, out_first, out_last, pred);
+ EXPECT_TRUE(std::distance(expected_first, i) == std::distance(out_first, k),
+ "wrong return value from remove_if");
+ EXPECT_EQ_N(expected_first, out_first, std::distance(expected_first, i), "wrong remove_if effect");
+ }
+};
+
+template <typename T, typename Predicate, typename Convert>
+void
+test(T trash, const T& value, Predicate pred, Convert convert)
+{
+ const std::size_t max_size = 100000;
+ Sequence<T> out(max_size, [trash](size_t) { return trash; });
+ Sequence<T> expected(max_size, [trash](size_t) { return trash; });
+
+ for (size_t n = 0; n <= max_size; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ Sequence<T> data(n, [&](size_t k) -> T { return convert(k); });
+
+ invoke_on_all_policies(run_remove(), data.begin(), data.end(), out.begin(), out.begin() + n, expected.begin(),
+ expected.begin() + n, n, value);
+ invoke_on_all_policies(run_remove_if(), data.begin(), data.end(), out.begin(), out.begin() + n,
+ expected.begin(), expected.begin() + n, n, pred);
+ }
+}
+
+struct test_non_const
+{
+ template <typename Policy, typename Iterator>
+ 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, [&]() { remove_if(exec, iter, iter, non_const(is_even)); });
+ }
+};
+
+int32_t
+main()
+{
+#if !__PSTL_ICC_18_TEST_EARLY_EXIT_MONOTONIC_RELEASE_BROKEN
+ test<int32_t>(666, 42, [](int32_t val) { return true; }, [](size_t j) { return j; });
+#endif
+
+ test<int32_t>(666, 2001, [](const int32_t& val) { return val != 2001; },
+ [](size_t j) { return ((j + 1) % 5 & 2) != 0 ? 2001 : -1 - int32_t(j); });
+ test<float64_t>(-666.0, 8.5, [](const float64_t& val) { return val != 8.5; },
+ [](size_t j) { return ((j + 1) % 7 & 2) != 0 ? 8.5 : float64_t(j % 32 + j); });
+
+#if !__PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
+ test<Number>(Number(-666, OddTag()), Number(42, OddTag()), IsMultiple(3, OddTag()),
+ [](int32_t j) { return Number(j, OddTag()); });
+#endif
+
+ test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/remove_copy.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/remove_copy.pass.cpp
new file mode 100644
index 00000000000..0437292af4f
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/remove_copy.pass.cpp
@@ -0,0 +1,94 @@
+// -*- C++ -*-
+//===-- remove_copy.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+struct run_remove_copy
+{
+ template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
+ typename T>
+ void
+ operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
+ const T& value, T trash)
+ {
+ // Cleaning
+ std::fill_n(expected_first, n, trash);
+ std::fill_n(out_first, n, trash);
+
+ // Run copy_if
+ auto i = remove_copy(first, last, expected_first, value);
+ auto k = remove_copy(exec, first, last, out_first, value);
+ EXPECT_EQ_N(expected_first, out_first, n, "wrong remove_copy effect");
+ for (size_t j = 0; j < GuardSize; ++j)
+ {
+ ++k;
+ }
+ EXPECT_TRUE(out_last == k, "wrong return value from remove_copy");
+ }
+};
+
+template <typename T, typename Convert>
+void
+test(T trash, const T& value, Convert convert, bool check_weakness = true)
+{
+ // Try sequences of various lengths.
+ for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ // count is number of output elements, plus a handful
+ // more for sake of detecting buffer overruns.
+ size_t count = GuardSize;
+ Sequence<T> in(n, [&](size_t k) -> T {
+ T x = convert(n ^ k);
+ count += !(x == value) ? 1 : 0;
+ return x;
+ });
+ using namespace std;
+
+ Sequence<T> out(count, [=](size_t) { return trash; });
+ Sequence<T> expected(count, [=](size_t) { return trash; });
+ if (check_weakness)
+ {
+ auto expected_result = remove_copy(in.cfbegin(), in.cfend(), expected.begin(), value);
+ size_t m = expected_result - expected.begin();
+ EXPECT_TRUE(n / 4 <= m && m <= 3 * (n + 1) / 4, "weak test for remove_copy");
+ }
+ invoke_on_all_policies(run_remove_copy(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
+ expected.end(), count, value, trash);
+ invoke_on_all_policies(run_remove_copy(), in.cbegin(), in.cend(), out.begin(), out.end(), expected.begin(),
+ expected.end(), count, value, trash);
+ }
+}
+
+int32_t
+main()
+{
+
+ test<float64_t>(-666.0, 8.5, [](size_t j) { return ((j + 1) % 7 & 2) != 0 ? 8.5 : float64_t(j % 32 + j); });
+
+ test<int32_t>(-666, 42, [](size_t j) { return ((j + 1) % 5 & 2) != 0 ? 42 : -1 - int32_t(j); });
+
+ test<Number>(Number(42, OddTag()), Number(2001, OddTag()),
+ [](int32_t j) { return ((j + 1) % 3 & 2) != 0 ? Number(2001, OddTag()) : Number(j, OddTag()); });
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/replace.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/replace.pass.cpp
new file mode 100644
index 00000000000..5aeaac88812
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/replace.pass.cpp
@@ -0,0 +1,163 @@
+// -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#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;
+ explicit copy_int(int32_t val = 0) { value = val; }
+
+ copy_int&
+ operator=(const copy_int& other)
+ {
+ if (&other == this)
+ copied_times++;
+ else
+ {
+ value = other.value;
+ copied_times = other.copied_times;
+ }
+ return *this;
+ }
+
+ bool
+ operator==(const copy_int& other) const
+ {
+ return (value == other.value);
+ }
+};
+
+template <typename Iterator>
+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 <typename ExecutionPolicy, typename Iterator1, typename Iterator2, typename T, typename Predicate>
+ 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<T, Iterator2>(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 <typename T, typename Iterator1>
+ bool
+ check(Iterator1 b, Iterator1 e)
+ {
+ return true;
+ }
+
+ template <typename T, typename Iterator1>
+ typename std::enable_if<std::is_same<T, copy_int>::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 <typename T1, typename T2, typename Pred>
+void
+test(Pred pred)
+{
+ typedef typename Sequence<T2>::iterator iterator_type;
+
+ const std::size_t max_len = 100000;
+
+ const T1 value = T1(0);
+ const T1 new_value = T1(666);
+
+ Sequence<T2> expected(max_len);
+ Sequence<T2> actual(max_len);
+
+ Sequence<T2> data(max_len, [&value](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<iterator_type> temp(data.begin(), len);
+
+ invoke_on_all_policies(temp, expected.begin(), expected.begin() + len, actual.begin(), actual.begin() + len,
+ pred, new_value, value);
+ }
+}
+
+template <typename T>
+struct test_non_const
+{
+ template <typename Policy, typename Iterator>
+ 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)); });
+ }
+};
+
+int32_t
+main()
+{
+ test<int32_t, float32_t>(__pstl::internal::equal_value<int32_t>(666));
+ test<uint16_t, uint8_t>([](const uint16_t& elem) { return elem % 3 < 2; });
+ test<float64_t, int64_t>([](const float64_t& elem) { return elem * elem - 3.5 * elem > 10; });
+ test<copy_int, copy_int>([](const copy_int& val) { return val.value / 5 > 2; });
+
+ test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/replace_copy.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/replace_copy.pass.cpp
new file mode 100644
index 00000000000..7ebbf4c0c7f
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/replace_copy.pass.cpp
@@ -0,0 +1,108 @@
+// -*- C++ -*-
+//===-- replace_copy.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
+//
+//===----------------------------------------------------------------------===//
+
+// Tests for replace_copy and replace_copy_if
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+struct test_replace_copy
+{
+ template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
+ typename Predicate, typename T>
+ void
+ operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
+ Predicate pred, const T& old_value, const T& new_value, T trash)
+ {
+ // Cleaning
+ std::fill_n(expected_first, n, trash);
+ std::fill_n(out_first, n, trash);
+ // Run replace_copy
+ auto i = std::replace_copy(first, last, expected_first, old_value, new_value);
+ auto k = std::replace_copy(exec, first, last, out_first, old_value, new_value);
+ EXPECT_EQ_N(expected_first, out_first, n, "wrong replace_copy effect");
+ EXPECT_TRUE(out_last == k, "wrong return value from replace_copy");
+
+ // Cleaning
+ std::fill_n(expected_first, n, trash);
+ std::fill_n(out_first, n, trash);
+ // Run replace_copy_if
+ i = replace_copy_if(first, last, expected_first, pred, new_value);
+ k = replace_copy_if(exec, first, last, out_first, pred, new_value);
+ EXPECT_EQ_N(expected_first, out_first, n, "wrong replace_copy_if effect");
+ EXPECT_TRUE(out_last == k, "wrong return value from replace_copy_if");
+ }
+};
+
+template <typename T, typename Convert, typename Predicate>
+void
+test(T trash, const T& old_value, const T& new_value, Predicate pred, Convert convert)
+{
+ // Try sequences of various lengths.
+ for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ Sequence<T> in(n, [&](size_t k) -> T { return convert(n ^ k); });
+ Sequence<T> out(n, [=](size_t) { return trash; });
+ Sequence<T> expected(n, [=](size_t) { return trash; });
+
+ invoke_on_all_policies(test_replace_copy(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
+ expected.end(), out.size(), pred, old_value, new_value, trash);
+ invoke_on_all_policies(test_replace_copy(), in.cbegin(), in.cend(), out.begin(), out.end(), expected.begin(),
+ expected.end(), out.size(), pred, old_value, new_value, trash);
+ }
+}
+
+template <typename T>
+struct test_non_const
+{
+ template <typename Policy, typename InputIterator, typename OutputInterator>
+ void
+ operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
+ {
+ auto is_even = [&](float64_t v) {
+ uint32_t i = (uint32_t)v;
+ return i % 2 == 0;
+ };
+
+ invoke_if(exec, [&]() { replace_copy_if(exec, input_iter, input_iter, out_iter, non_const(is_even), T(0)); });
+ }
+};
+
+int32_t
+main()
+{
+
+ test<float64_t>(-666.0, 8.5, 0.33, [](const float64_t& x) { return x * x <= 1024; },
+ [](size_t j) { return ((j + 1) % 7 & 2) != 0 ? 8.5 : float64_t(j % 32 + j); });
+
+ test<int32_t>(-666, 42, 99, [](const int32_t& x) { return x != 42; },
+ [](size_t j) { return ((j + 1) % 5 & 2) != 0 ? 42 : -1 - int32_t(j); });
+
+#if !__PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
+ test<Number>(Number(42, OddTag()), Number(2001, OddTag()), Number(2017, OddTag()), IsMultiple(3, OddTag()),
+ [](int32_t j) { return ((j + 1) % 3 & 2) != 0 ? Number(2001, OddTag()) : Number(j, OddTag()); });
+#endif
+
+ test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/rotate.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/rotate.pass.cpp
new file mode 100644
index 00000000000..2bebc4e57da
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/rotate.pass.cpp
@@ -0,0 +1,177 @@
+// -*- C++ -*-
+//===-- rotate.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include <iterator>
+
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+template <typename T>
+struct wrapper
+{
+ T t;
+ int move_count;
+ explicit wrapper(T t_) : t(t_), move_count(0) {}
+ wrapper&
+ operator=(const T& t_)
+ {
+ t = t_;
+ return *this;
+ }
+
+ wrapper(const wrapper<T>& a) : move_count(0) { t = a.t; }
+
+ wrapper<T>&
+ operator=(wrapper<T>& a)
+ {
+ t = a.t;
+ return *this;
+ }
+
+ wrapper<T>&
+ operator=(wrapper<T>&& a)
+ {
+ t = a.t;
+ move_count += 1;
+ return *this;
+ }
+};
+
+template <typename T>
+struct compare
+{
+ bool
+ operator()(const T& a, const T& b)
+ {
+ return a == b;
+ }
+};
+
+template <typename T>
+struct compare<wrapper<T>>
+{
+ bool
+ operator()(const wrapper<T>& a, const wrapper<T>& b)
+ {
+ return a.t == b.t;
+ }
+};
+#include <typeinfo>
+
+struct test_one_policy
+{
+
+#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
+ __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specializations to skip testing in case of broken configuration
+ template <typename Iterator, typename Size>
+ void
+ operator()(pstl::execution::unsequenced_policy, Iterator data_b, Iterator data_e, Iterator actual_b,
+ Iterator actual_e, Size shift)
+ {
+ }
+ template <typename Iterator, typename Size>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, Iterator data_b, Iterator data_e, Iterator actual_b,
+ Iterator actual_e, Size shift)
+ {
+ }
+#endif
+
+ template <typename ExecutionPolicy, typename Iterator, typename Size>
+ void
+ operator()(ExecutionPolicy&& exec, Iterator data_b, Iterator data_e, Iterator actual_b, Iterator actual_e,
+ Size shift)
+ {
+ using namespace std;
+ using T = typename iterator_traits<Iterator>::value_type;
+ Iterator actual_m = std::next(actual_b, shift);
+
+ copy(data_b, data_e, actual_b);
+ Iterator actual_return = rotate(exec, actual_b, actual_m, actual_e);
+
+ EXPECT_TRUE(actual_return == std::next(actual_b, std::distance(actual_m, actual_e)), "wrong result of rotate");
+ auto comparator = compare<T>();
+ bool check = std::equal(actual_return, actual_e, data_b, comparator);
+ check = check && std::equal(actual_b, actual_return, std::next(data_b, shift), comparator);
+
+ EXPECT_TRUE(check, "wrong effect of rotate");
+ EXPECT_TRUE(check_move(exec, actual_b, actual_e, shift), "wrong move test of rotate");
+ }
+
+ template <typename ExecutionPolicy, typename Iterator, typename Size>
+ typename std::enable_if<
+ is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value &&
+ !std::is_same<ExecutionPolicy, pstl::execution::sequenced_policy>::value &&
+ std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value,
+ bool>::type
+ check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift)
+ {
+ bool result = all_of(b, e, [](wrapper<float32_t>& a) {
+ bool temp = a.move_count > 0;
+ a.move_count = 0;
+ return temp;
+ });
+ return shift == 0 || result;
+ }
+
+ template <typename ExecutionPolicy, typename Iterator, typename Size>
+ typename std::enable_if<
+ !(is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value &&
+ !std::is_same<ExecutionPolicy, pstl::execution::sequenced_policy>::value &&
+ std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value),
+ bool>::type
+ check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift)
+ {
+ return true;
+ }
+};
+
+template <typename T>
+void
+test()
+{
+ const int32_t max_len = 100000;
+
+ Sequence<T> actual(max_len, [](std::size_t i) { return T(i); });
+ Sequence<T> data(max_len, [](std::size_t i) { return T(i); });
+
+ for (int32_t len = 0; len < max_len; len = len <= 16 ? len + 1 : int32_t(3.1415 * len))
+ {
+ int32_t shifts[] = {0, 1, 2, len / 3, (2 * len) / 3, len - 1};
+ for (auto shift : shifts)
+ {
+ if (shift >= 0 && shift < len)
+ {
+ invoke_on_all_policies(test_one_policy(), data.begin(), data.begin() + len, actual.begin(),
+ actual.begin() + len, shift);
+ }
+ }
+ }
+}
+
+int32_t
+main()
+{
+ test<int32_t>();
+ test<wrapper<float64_t>>();
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/rotate_copy.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/rotate_copy.pass.cpp
new file mode 100644
index 00000000000..7d0ec7ec450
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/rotate_copy.pass.cpp
@@ -0,0 +1,150 @@
+// -*- C++ -*-
+//===-- rotate_copy.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include <iterator>
+
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+template <typename T>
+struct wrapper;
+
+template <typename T>
+bool
+compare(const wrapper<T>& a, const wrapper<T>& b)
+{
+ return a.t == b.t;
+}
+
+template <typename T>
+bool
+compare(const T& a, const T& b)
+{
+ return a == b;
+}
+
+template <typename T>
+struct wrapper
+{
+ explicit wrapper(T t_) : t(t_) {}
+ wrapper&
+ operator=(const T& t_)
+ {
+ t = t_;
+ return *this;
+ }
+ friend bool
+ compare<T>(const wrapper<T>& a, const wrapper<T>& b);
+
+ private:
+ T t;
+};
+
+template <typename T, typename It1, typename It2>
+struct comparator
+{
+ using T1 = typename std::iterator_traits<It1>::value_type;
+ using T2 = typename std::iterator_traits<It2>::value_type;
+ bool
+ operator()(T1 a, T2 b)
+ {
+ T temp = a;
+ return compare(temp, b);
+ }
+};
+
+struct test_one_policy
+{
+
+#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
+ __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
+ template <typename Iterator1, typename Iterator2>
+ typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
+ operator()(pstl::execution::unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
+ Iterator2 actual_e, std::size_t shift)
+ {
+ }
+ template <typename Iterator1, typename Iterator2>
+ typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
+ operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
+ Iterator2 actual_e, std::size_t shift)
+ {
+ }
+#endif
+
+ template <typename ExecutionPolicy, typename Iterator1, typename Iterator2>
+ void
+ operator()(ExecutionPolicy&& exec, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b, Iterator2 actual_e,
+ std::size_t shift)
+ {
+ using namespace std;
+ using T = typename iterator_traits<Iterator2>::value_type;
+ Iterator1 data_m = std::next(data_b, shift);
+
+ fill(actual_b, actual_e, T(-123));
+ Iterator2 actual_return = rotate_copy(exec, data_b, data_m, data_e, actual_b);
+
+ EXPECT_TRUE(actual_return == actual_e, "wrong result of rotate_copy");
+ auto comparer = comparator<T, Iterator1, Iterator2>();
+ bool check = std::equal(data_m, data_e, actual_b, comparer);
+ check = check && std::equal(data_b, data_m, std::next(actual_b, std::distance(data_m, data_e)), comparer);
+
+ EXPECT_TRUE(check, "wrong effect of rotate_copy");
+ }
+};
+
+template <typename T1, typename T2>
+void
+test()
+{
+
+ const std::size_t max_len = 100000;
+
+ Sequence<T2> actual(max_len, [](std::size_t i) { return T1(i); });
+
+ Sequence<T1> data(max_len, [](std::size_t i) { return T1(i); });
+
+ for (std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::size_t(3.1415 * len))
+ {
+ std::size_t shifts[] = {0, 1, 2, len / 3, (2 * len) / 3, len - 1};
+ for (std::size_t shift : shifts)
+ {
+ if (shift > 0 && shift < len)
+ {
+ invoke_on_all_policies(test_one_policy(), data.begin(), data.begin() + len, actual.begin(),
+ actual.begin() + len, shift);
+ invoke_on_all_policies(test_one_policy(), data.cbegin(), data.cbegin() + len, actual.begin(),
+ actual.begin() + len, shift);
+ }
+ }
+ }
+}
+
+int32_t
+main()
+{
+ test<int32_t, int8_t>();
+ test<uint16_t, float32_t>();
+ test<float64_t, int64_t>();
+ test<wrapper<float64_t>, wrapper<float64_t>>();
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/swap_ranges.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/swap_ranges.pass.cpp
new file mode 100644
index 00000000000..b53003c4626
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/swap_ranges.pass.cpp
@@ -0,0 +1,137 @@
+// -*- C++ -*-
+//===-- swap_ranges.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include <iterator>
+
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+template <typename T>
+struct wrapper
+{
+ T t;
+ std::size_t number_of_swaps = 0;
+ wrapper() {}
+ explicit wrapper(T t_) : t(t_) {}
+ template <typename U>
+ void
+ operator=(const U& b)
+ {
+ t = b;
+ }
+ bool
+ operator==(const wrapper<T>& a) const
+ {
+ return t == a.t;
+ }
+};
+
+template <typename T>
+void
+swap(wrapper<T>& a, wrapper<T>& b)
+{
+ std::swap(a.t, b.t);
+ a.number_of_swaps++;
+ b.number_of_swaps++;
+}
+
+template <typename T>
+struct check_swap
+{
+ bool
+ operator()(T& a)
+ {
+ return true;
+ }
+};
+
+template <typename T>
+struct check_swap<wrapper<T>>
+{
+ bool
+ operator()(wrapper<T>& a)
+ {
+ bool temp = (a.number_of_swaps == 1);
+ a.number_of_swaps = 0;
+ return temp;
+ }
+};
+
+struct test_one_policy
+{
+ template <typename ExecutionPolicy, typename Iterator1, typename Iterator2>
+ void
+ operator()(ExecutionPolicy&& exec, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b, Iterator2 actual_e)
+ {
+ using namespace std;
+ using T_ref = typename iterator_traits<Iterator1>::reference;
+ using T = typename iterator_traits<Iterator1>::value_type;
+
+ iota(data_b, data_e, 0);
+ iota(actual_b, actual_e, std::distance(data_b, data_e));
+
+ Iterator2 actual_return = swap_ranges(exec, data_b, data_e, actual_b);
+ bool check_return = (actual_return == actual_e);
+ EXPECT_TRUE(check_return, "wrong result of swap_ranges");
+ if (check_return)
+ {
+ std::size_t i = 0;
+ bool check = all_of(actual_b, actual_e, [&i](T_ref a) { return a == T(i++); }) &&
+ all_of(data_b, data_e, [&i](T_ref a) { return a == T(i++); });
+
+ EXPECT_TRUE(check, "wrong effect of swap_ranges");
+
+ if (check)
+ {
+ bool swap_check =
+ all_of(data_b, data_e, check_swap<T>()) && all_of(actual_b, actual_e, check_swap<T>());
+ EXPECT_TRUE(swap_check, "wrong effect of swap_ranges swap check");
+ }
+ }
+ }
+};
+
+template <typename T>
+void
+test()
+{
+ const std::size_t max_len = 100000;
+
+ Sequence<T> data(max_len);
+ Sequence<T> actual(max_len);
+
+ for (std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::size_t(3.1415 * len))
+ {
+ invoke_on_all_policies(test_one_policy(), data.begin(), data.begin() + len, actual.begin(),
+ actual.begin() + len);
+ }
+}
+
+int32_t
+main()
+{
+ test<wrapper<uint16_t>>();
+ test<wrapper<float64_t>>();
+ test<int32_t>();
+ test<float32_t>();
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/transform_binary.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/transform_binary.pass.cpp
new file mode 100644
index 00000000000..2d680c369f2
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/transform_binary.pass.cpp
@@ -0,0 +1,124 @@
+// -*- C++ -*-
+//===-- transform_binary.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/algorithm"
+#include "pstl/execution"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+template <typename In1, typename In2, typename Out>
+class TheOperation
+{
+ Out val;
+
+ public:
+ TheOperation(Out v) : val(v) {}
+ Out
+ operator()(const In1& x, const In2& y) const
+ {
+ return Out(val + x - y);
+ }
+};
+
+template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
+void
+check_and_reset(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator out_first)
+{
+ typedef typename std::iterator_traits<OutputIterator>::value_type Out;
+ typename std::iterator_traits<OutputIterator>::difference_type k = 0;
+ for (; first1 != last1; ++first1, ++first2, ++out_first, ++k)
+ {
+ // check
+ Out expected = Out(1.5) + *first1 - *first2;
+ Out actual = *out_first;
+ if (std::is_floating_point<Out>::value)
+ {
+ EXPECT_TRUE((expected > actual ? expected - actual : actual - expected) < 1e7,
+ "wrong value in output sequence");
+ }
+ else
+ {
+ EXPECT_EQ(expected, actual, "wrong value in output sequence");
+ }
+ // reset
+ *out_first = k % 7 != 4 ? 7 * k - 5 : 0;
+ }
+}
+
+struct test_one_policy
+{
+ template <typename Policy, typename InputIterator1, typename InputIterator2, typename OutputIterator,
+ typename BinaryOp>
+ void
+ operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
+ OutputIterator out_first, OutputIterator out_last, BinaryOp op)
+ {
+ auto orrr = std::transform(exec, first1, last1, first2, out_first, op);
+ check_and_reset(first1, last1, first2, out_first);
+ }
+};
+
+template <typename In1, typename In2, typename Out, typename Predicate>
+void
+test(Predicate pred)
+{
+ for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ Sequence<In1> in1(n, [](size_t k) { return k % 5 != 1 ? 3 * k - 7 : 0; });
+ Sequence<In2> in2(n, [](size_t k) { return k % 7 != 2 ? 5 * k - 5 : 0; });
+
+ Sequence<Out> out(n, [](size_t k) { return -1; });
+
+ invoke_on_all_policies(test_one_policy(), in1.begin(), in1.end(), in2.begin(), in2.end(), out.begin(),
+ out.end(), pred);
+ invoke_on_all_policies(test_one_policy(), in1.cbegin(), in1.cend(), in2.cbegin(), in2.cend(), out.begin(),
+ out.end(), pred);
+ }
+}
+
+template <typename T>
+struct test_non_const
+{
+ template <typename Policy, typename InputIterator, typename OutputInterator>
+ void
+ operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
+ {
+ invoke_if(exec, [&]() {
+ InputIterator input_iter2 = input_iter;
+ transform(exec, input_iter, input_iter, input_iter2, out_iter, non_const(std::plus<T>()));
+ });
+ }
+};
+
+int32_t
+main()
+{
+ //const operator()
+ test<int32_t, int32_t, int32_t>(TheOperation<int32_t, int32_t, int32_t>(1));
+ test<float32_t, float32_t, float32_t>(TheOperation<float32_t, float32_t, float32_t>(1.5));
+ //non-const operator()
+ test<int32_t, float32_t, float32_t>(non_const(TheOperation<int32_t, float32_t, float32_t>(1.5)));
+ test<int64_t, float64_t, float32_t>(non_const(TheOperation<int64_t, float64_t, float32_t>(1.5)));
+ //lambda
+ test<int8_t, float64_t, int8_t>([](const int8_t& x, const float64_t& y) { return int8_t(int8_t(1.5) + x - y); });
+
+ test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/transform_unary.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/transform_unary.pass.cpp
new file mode 100644
index 00000000000..e198c6e2a8b
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/transform_unary.pass.cpp
@@ -0,0 +1,94 @@
+// -*- C++ -*-
+//===-- transform_unary.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/algorithm"
+#include "pstl/execution"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+template <typename InputIterator, typename OutputIterator>
+void
+check_and_reset(InputIterator first, InputIterator last, OutputIterator out_first)
+{
+ typedef typename std::iterator_traits<OutputIterator>::value_type Out;
+ typename std::iterator_traits<OutputIterator>::difference_type k = 0;
+ for (; first != last; ++first, ++out_first, ++k)
+ {
+ // check
+ Out expected = 1 - *first;
+ Out actual = *out_first;
+ EXPECT_EQ(expected, actual, "wrong value in output sequence");
+ // reset
+ *out_first = k % 7 != 4 ? 7 * k - 5 : 0;
+ }
+}
+
+struct test_one_policy
+{
+ template <typename Policy, typename InputIterator, typename OutputIterator, typename UnaryOp>
+ void
+ operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, UnaryOp op)
+ {
+ auto orr = std::transform(exec, first, last, out_first, op);
+ EXPECT_TRUE(out_last == orr, "transform returned wrong iterator");
+ check_and_reset(first, last, out_first);
+ }
+};
+
+template <typename Tin, typename Tout>
+void
+test()
+{
+ for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ Sequence<Tin> in(n, [](int32_t k) { return k % 5 != 1 ? 3 * k - 7 : 0; });
+
+ Sequence<Tout> out(n);
+
+ const auto flip = Complement<Tin, Tout>(1);
+ invoke_on_all_policies(test_one_policy(), in.begin(), in.end(), out.begin(), out.end(), flip);
+ invoke_on_all_policies(test_one_policy(), in.cbegin(), in.cend(), out.begin(), out.end(), flip);
+ }
+}
+
+template <typename T>
+struct test_non_const
+{
+ template <typename Policy, typename InputIterator, typename OutputInterator>
+ void
+ operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
+ {
+ invoke_if(exec, [&]() { transform(exec, input_iter, input_iter, out_iter, non_const(std::negate<T>())); });
+ }
+};
+
+int32_t
+main()
+{
+ test<int32_t, int32_t>();
+ test<int32_t, float32_t>();
+ test<uint16_t, float32_t>();
+ test<float32_t, float64_t>();
+ test<float64_t, float64_t>();
+
+ test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/unique.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/unique.pass.cpp
new file mode 100644
index 00000000000..06639ccf685
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/unique.pass.cpp
@@ -0,0 +1,160 @@
+// -*- C++ -*-
+//===-- unique.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
+//
+//===----------------------------------------------------------------------===//
+
+// Test for unique
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+struct run_unique
+{
+#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
+ __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
+ template <typename ForwardIt, typename Generator>
+ void
+ operator()(pstl::execution::unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
+ ForwardIt last2, Generator generator)
+ {
+ }
+
+ template <typename ForwardIt, typename Generator>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
+ ForwardIt last2, Generator generator)
+ {
+ }
+
+ template <typename ForwardIt, typename BinaryPred, typename Generator>
+ void
+ operator()(pstl::execution::unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
+ ForwardIt last2, BinaryPred pred, Generator generator)
+ {
+ }
+
+ template <typename ForwardIt, typename BinaryPred, typename Generator>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
+ ForwardIt last2, BinaryPred pred, Generator generator)
+ {
+ }
+#endif
+
+ template <typename Policy, typename ForwardIt, typename Generator>
+ void
+ operator()(Policy&& exec, ForwardIt first1, ForwardIt last1, ForwardIt first2, ForwardIt last2, Generator generator)
+ {
+ using namespace std;
+
+ // Preparation
+ fill_data(first1, last1, generator);
+ fill_data(first2, last2, generator);
+
+ ForwardIt i = unique(first1, last1);
+ ForwardIt k = unique(exec, first2, last2);
+
+ auto n = std::distance(first1, i);
+ EXPECT_TRUE(std::distance(first2, k) == n, "wrong return value from unique without predicate");
+ EXPECT_EQ_N(first1, first2, n, "wrong effect from unique without predicate");
+ }
+
+ template <typename Policy, typename ForwardIt, typename BinaryPred, typename Generator>
+ void
+ operator()(Policy&& exec, ForwardIt first1, ForwardIt last1, ForwardIt first2, ForwardIt last2, BinaryPred pred,
+ Generator generator)
+ {
+ using namespace std;
+
+ // Preparation
+ fill_data(first1, last1, generator);
+ fill_data(first2, last2, generator);
+
+ ForwardIt i = unique(first1, last1, pred);
+ ForwardIt k = unique(exec, first2, last2, pred);
+
+ auto n = std::distance(first1, i);
+ EXPECT_TRUE(std::distance(first2, k) == n, "wrong return value from unique with predicate");
+ EXPECT_EQ_N(first1, first2, n, "wrong effect from unique with predicate");
+ }
+};
+
+template <typename T, typename Generator, typename Predicate>
+void
+test(Generator generator, Predicate pred)
+{
+ const std::size_t max_size = 1000000;
+ Sequence<T> in(max_size, [](size_t v) { return T(v); });
+ Sequence<T> exp(max_size, [](size_t v) { return T(v); });
+
+ for (size_t n = 0; n <= max_size; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ invoke_on_all_policies(run_unique(), exp.begin(), exp.begin() + n, in.begin(), in.begin() + n, generator);
+ invoke_on_all_policies(run_unique(), exp.begin(), exp.begin() + n, in.begin(), in.begin() + n, pred, generator);
+ }
+}
+
+template <typename T>
+struct LocalWrapper
+{
+ T my_val;
+
+ explicit LocalWrapper(T k) : my_val(k) {}
+ LocalWrapper(LocalWrapper&& input) : my_val(std::move(input.my_val)) {}
+ LocalWrapper&
+ operator=(LocalWrapper&& input)
+ {
+ my_val = std::move(input.my_val);
+ return *this;
+ }
+ friend bool
+ operator==(const LocalWrapper<T>& x, const LocalWrapper<T>& y)
+ {
+ return x.my_val == y.my_val;
+ }
+};
+
+template <typename T>
+struct test_non_const
+{
+ template <typename Policy, typename Iterator>
+ void
+ operator()(Policy&& exec, Iterator iter)
+ {
+ invoke_if(exec, [&]() { unique(exec, iter, iter, non_const(std::equal_to<T>())); });
+ }
+};
+
+int32_t
+main()
+{
+#if !__PSTL_ICC_16_17_18_TEST_UNIQUE_MASK_RELEASE_BROKEN
+ test<int32_t>([](size_t j) { return j / 3; },
+ [](const int32_t& val1, const int32_t& val2) { return val1 * val1 == val2 * val2; });
+ test<float64_t>([](size_t) { return float64_t(1); },
+ [](const float64_t& val1, const float64_t& val2) { return val1 != val2; });
+#endif
+ test<LocalWrapper<uint32_t>>([](size_t j) { return LocalWrapper<uint32_t>(j); },
+ [](const LocalWrapper<uint32_t>& val1, const LocalWrapper<uint32_t>& val2) {
+ return val1.my_val != val2.my_val;
+ });
+
+ test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
diff --git a/pstl/test/std/algorithms/alg.modifying.operations/unique_copy_equal.pass.cpp b/pstl/test/std/algorithms/alg.modifying.operations/unique_copy_equal.pass.cpp
new file mode 100644
index 00000000000..c948e80d45a
--- /dev/null
+++ b/pstl/test/std/algorithms/alg.modifying.operations/unique_copy_equal.pass.cpp
@@ -0,0 +1,138 @@
+// -*- C++ -*-
+//===-- unique_copy_equal.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
+//
+//===----------------------------------------------------------------------===//
+
+// Tests for unique_copy
+#include "support/pstl_test_config.h"
+
+#ifdef PSTL_STANDALONE_TESTS
+#include "pstl/execution"
+#include "pstl/algorithm"
+#else
+#include <execution>
+#include <algorithm>
+#endif // PSTL_STANDALONE_TESTS
+
+#include "support/utils.h"
+
+using namespace TestUtils;
+
+struct run_unique_copy
+{
+#if __PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN // dummy specializations to skip testing in case of broken configuration
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
+ typename Predicate, typename T>
+ void
+ operator()(pstl::execution::parallel_policy, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
+ Predicate pred, T trash)
+ {
+ }
+
+ template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
+ typename Predicate, typename T>
+ void
+ operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
+ OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
+ OutputIterator2 expected_last, Size n, Predicate pred, T trash)
+ {
+ }
+#endif
+
+ template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
+ typename Predicate, typename T>
+ void
+ operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
+ OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
+ Predicate pred, T trash)
+ {
+ // Cleaning
+ std::fill_n(expected_first, n, trash);
+ std::fill_n(out_first, n, trash);
+
+ // Run unique_copy
+ auto i = unique_copy(first, last, expected_first);
+ auto k = unique_copy(exec, first, last, out_first);
+ EXPECT_EQ_N(expected_first, out_first, n, "wrong unique_copy effect");
+ for (size_t j = 0; j < GuardSize; ++j)
+ {
+ ++k;
+ }
+ EXPECT_TRUE(out_last == k, "wrong return value from unique_copy");
+
+ // Cleaning
+ std::fill_n(expected_first, n, trash);
+ std::fill_n(out_first, n, trash);
+ // Run unique_copy with predicate
+ i = unique_copy(first, last, expected_first, pred);
+ k = unique_copy(exec, first, last, out_first, pred);
+ EXPECT_EQ_N(expected_first, out_first, n, "wrong unique_copy with predicate effect");
+ for (size_t j = 0; j < GuardSize; ++j)
+ {
+ ++k;
+ }
+ EXPECT_TRUE(out_last == k, "wrong return value from unique_copy with predicate");
+ }
+};
+
+template <typename T, typename BinaryPredicate, typename Convert>
+void
+test(T trash, BinaryPredicate pred, Convert convert, bool check_weakness = true)
+{
+ // Try sequences of various lengths.
+ for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
+ {
+ // count is number of output elements, plus a handful
+ // more for sake of detecting buffer overruns.
+ Sequence<T> in(n, [&](size_t k) -> T { return convert(k ^ n); });
+ using namespace std;
+ size_t count = GuardSize;
+ for (size_t k = 0; k < in.size(); ++k)
+ count += k == 0 || !pred(in[k], in[k - 1]) ? 1 : 0;
+ Sequence<T> out(count, [=](size_t) { return trash; });
+ Sequence<T> expected(count, [=](size_t) { return trash; });
+ if (check_weakness)
+ {
+ auto expected_result = unique_copy(in.begin(), in.end(), expected.begin(), pred);
+ size_t m = expected_result - expected.begin();
+ EXPECT_TRUE(n / (n < 10000 ? 4 : 6) <= m && m <= (3 * n + 1) / 4, "weak test for unique_copy");
+ }
+ invoke_on_all_policies(run_unique_copy(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
+ expected.end(), count, pred, trash);
+ }
+}
+
+template <typename T>
+struct test_non_const
+{
+ template <typename Policy, typename InputIterator, typename OutputInterator>
+ void
+ operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
+ {
+ unique_copy(exec, input_iter, input_iter, out_iter, non_const(std::equal_to<T>()));
+ }
+};
+
+int32_t
+main(int32_t argc, char* argv[])
+{
+ test<Number>(Number(42, OddTag()), std::equal_to<Number>(),
+ [](int32_t j) { return Number(3 * j / 13 ^ (j & 8), OddTag()); });
+
+ test<float32_t>(float32_t(42), std::equal_to<float32_t>(),
+ [](int32_t j) { return float32_t(5 * j / 23 ^ (j / 7)); });
+#if !__PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
+ test<float32_t>(float32_t(42), [](float32_t x, float32_t y) { return false; },
+ [](int32_t j) { return float32_t(j); }, false);
+#endif
+
+ test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
+
+ std::cout << done() << std::endl;
+ return 0;
+}
OpenPOWER on IntegriCloud