13b62047bSLouis Dionne // -*- C++ -*-
23b62047bSLouis Dionne //===-- partition_copy.pass.cpp -------------------------------------------===//
33b62047bSLouis Dionne //
43b62047bSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
53b62047bSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
63b62047bSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73b62047bSLouis Dionne //
83b62047bSLouis Dionne //===----------------------------------------------------------------------===//
93b62047bSLouis Dionne
10b5e896c0SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14
116ab35c9dSLouis Dionne
123b62047bSLouis Dionne // Tests for stable_partition and partition_copy
133b62047bSLouis Dionne #include "support/pstl_test_config.h"
143b62047bSLouis Dionne
153b62047bSLouis Dionne #include <algorithm>
163b62047bSLouis Dionne #include <cstdlib>
17989cad24SLouis Dionne #include <execution>
18989cad24SLouis Dionne #include <functional>
193b62047bSLouis Dionne #include <iterator>
203b62047bSLouis Dionne
214d88b17bSLouis Dionne #include "support/utils.h"
224d88b17bSLouis Dionne
233b62047bSLouis Dionne using namespace TestUtils;
243b62047bSLouis Dionne
253b62047bSLouis Dionne struct test_partition_copy
263b62047bSLouis Dionne {
273b62047bSLouis Dionne template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2,
283b62047bSLouis Dionne typename UnaryOp>
293b62047bSLouis Dionne void
operator ()test_partition_copy30989cad24SLouis Dionne operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator true_first, OutputIterator,
31989cad24SLouis Dionne OutputIterator2 false_first, OutputIterator2, UnaryOp unary_op)
323b62047bSLouis Dionne {
333b62047bSLouis Dionne
343b62047bSLouis Dionne auto actual_ret = std::partition_copy(exec, first, last, true_first, false_first, unary_op);
353b62047bSLouis Dionne
363b62047bSLouis Dionne EXPECT_TRUE(std::distance(true_first, actual_ret.first) == std::count_if(first, last, unary_op),
373b62047bSLouis Dionne "partition_copy has wrong effect from true sequence");
38989cad24SLouis Dionne EXPECT_TRUE(std::distance(false_first, actual_ret.second) == std::count_if(first, last, std::not_fn(unary_op)),
393b62047bSLouis Dionne "partition_copy has wrong effect from false sequence");
403b62047bSLouis Dionne }
413b62047bSLouis Dionne
423b62047bSLouis Dionne //dummy specialization by iterator type and policy type, in case of broken configuration
43*3b9a1bb1SLouis Dionne #if defined(_PSTL_ICC_1800_TEST_MONOTONIC_RELEASE_64_BROKEN)
443b62047bSLouis Dionne template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename UnaryOp>
453b62047bSLouis Dionne void
operator ()test_partition_copy463b62047bSLouis Dionne operator()(pstl::execution::unsequenced_policy, std::reverse_iterator<InputIterator> first,
473b62047bSLouis Dionne std::reverse_iterator<InputIterator> last, std::reverse_iterator<OutputIterator> true_first,
483b62047bSLouis Dionne std::reverse_iterator<OutputIterator> true_last, std::reverse_iterator<OutputIterator2> false_first,
493b62047bSLouis Dionne OutputIterator2 false_last, UnaryOp unary_op)
503b62047bSLouis Dionne {
513b62047bSLouis Dionne }
523b62047bSLouis Dionne template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename UnaryOp>
533b62047bSLouis Dionne void
operator ()test_partition_copy543b62047bSLouis Dionne operator()(pstl::execution::parallel_unsequenced_policy, std::reverse_iterator<InputIterator> first,
553b62047bSLouis Dionne std::reverse_iterator<InputIterator> last, std::reverse_iterator<OutputIterator> true_first,
563b62047bSLouis Dionne std::reverse_iterator<OutputIterator> true_last, std::reverse_iterator<OutputIterator2> false_first,
573b62047bSLouis Dionne OutputIterator2 false_last, UnaryOp unary_op)
583b62047bSLouis Dionne {
593b62047bSLouis Dionne }
603b62047bSLouis Dionne #endif
613b62047bSLouis Dionne };
623b62047bSLouis Dionne
633b62047bSLouis Dionne template <typename T, typename UnaryPred>
643b62047bSLouis Dionne void
test(UnaryPred pred)653b62047bSLouis Dionne test(UnaryPred pred)
663b62047bSLouis Dionne {
673b62047bSLouis Dionne
683b62047bSLouis Dionne const std::size_t max_size = 100000;
693b62047bSLouis Dionne Sequence<T> in(max_size, [](std::size_t v) -> T { return T(v); });
703b62047bSLouis Dionne Sequence<T> actual_true(max_size);
713b62047bSLouis Dionne Sequence<T> actual_false(max_size);
723b62047bSLouis Dionne for (std::size_t n = 0; n <= max_size; n = n <= 16 ? n + 1 : std::size_t(3.1415 * n))
733b62047bSLouis Dionne {
743b62047bSLouis Dionne
753b62047bSLouis Dionne // for non-const input iterators
763b62047bSLouis Dionne invoke_on_all_policies(test_partition_copy(), in.begin(), in.begin() + n, actual_true.begin(),
773b62047bSLouis Dionne actual_true.begin() + n, actual_false.begin(), actual_false.begin() + n, pred);
783b62047bSLouis Dionne
793b62047bSLouis Dionne // for const input iterators
803b62047bSLouis Dionne invoke_on_all_policies(test_partition_copy(), in.cbegin(), in.cbegin() + n, actual_true.begin(),
813b62047bSLouis Dionne actual_true.begin() + n, actual_false.begin(), actual_false.begin() + n, pred);
823b62047bSLouis Dionne }
833b62047bSLouis Dionne }
843b62047bSLouis Dionne
853b62047bSLouis Dionne struct test_non_const
863b62047bSLouis Dionne {
873b62047bSLouis Dionne template <typename Policy, typename InputIterator, typename OutputInterator>
883b62047bSLouis Dionne void
operator ()test_non_const893b62047bSLouis Dionne operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
903b62047bSLouis Dionne {
913b62047bSLouis Dionne auto is_even = [&](float64_t v) {
923b62047bSLouis Dionne uint32_t i = (uint32_t)v;
933b62047bSLouis Dionne return i % 2 == 0;
943b62047bSLouis Dionne };
953b62047bSLouis Dionne
963b62047bSLouis Dionne partition_copy(exec, input_iter, input_iter, out_iter, out_iter, non_const(is_even));
973b62047bSLouis Dionne }
983b62047bSLouis Dionne };
993b62047bSLouis Dionne
100249c1c74SLouis Dionne int
main()1013b62047bSLouis Dionne main()
1023b62047bSLouis Dionne {
1033b62047bSLouis Dionne test<int32_t>([](const int32_t value) { return value % 2; });
1043b62047bSLouis Dionne
105*3b9a1bb1SLouis Dionne #if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN)
1063491119fSLouis Dionne test<int32_t>([](const int32_t) { return true; });
1073b62047bSLouis Dionne #endif
1083b62047bSLouis Dionne
1093b62047bSLouis Dionne test<float64_t>([](const float64_t value) { return value > 2 << 6; });
1103b62047bSLouis Dionne test<Wrapper<float64_t>>([](const Wrapper<float64_t>& value) -> bool { return value.get_my_field() != nullptr; });
1113b62047bSLouis Dionne
1123b62047bSLouis Dionne test_algo_basic_double<int32_t>(run_for_rnd_bi<test_non_const>());
1133b62047bSLouis Dionne
1143b62047bSLouis Dionne std::cout << done() << std::endl;
1153b62047bSLouis Dionne return 0;
1163b62047bSLouis Dionne }
117