13b62047bSLouis Dionne // -*- C++ -*-
23b62047bSLouis Dionne //===-- merge.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 #include "support/pstl_test_config.h"
133b62047bSLouis Dionne
143b62047bSLouis Dionne #include <execution>
153b62047bSLouis Dionne #include <algorithm>
164d88b17bSLouis Dionne #include <functional>
173b62047bSLouis Dionne
183b62047bSLouis Dionne #include "support/utils.h"
193b62047bSLouis Dionne
203b62047bSLouis Dionne using namespace TestUtils;
213b62047bSLouis Dionne
223b62047bSLouis Dionne struct test_merge
233b62047bSLouis Dionne {
243b62047bSLouis Dionne template <typename Policy, typename InputIterator1, typename InputIterator2, typename OutputIterator,
253b62047bSLouis Dionne typename Compare>
263b62047bSLouis Dionne void
operator ()test_merge273b62047bSLouis Dionne operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
283b62047bSLouis Dionne OutputIterator out_first, OutputIterator out_last, Compare comp)
293b62047bSLouis Dionne {
303b62047bSLouis Dionne using namespace std;
313b62047bSLouis Dionne {
323b62047bSLouis Dionne const auto res = merge(exec, first1, last1, first2, last2, out_first, comp);
333b62047bSLouis Dionne EXPECT_TRUE(res == out_last, "wrong return result from merge with predicate");
343b62047bSLouis Dionne EXPECT_TRUE(is_sorted(out_first, res, comp), "wrong result from merge with predicate");
353b62047bSLouis Dionne EXPECT_TRUE(includes(out_first, res, first1, last1, comp), "first sequence is not a part of result");
363b62047bSLouis Dionne EXPECT_TRUE(includes(out_first, res, first2, last2, comp), "second sequence is not a part of result");
373b62047bSLouis Dionne }
383b62047bSLouis Dionne {
393b62047bSLouis Dionne const auto res = merge(exec, first1, last1, first2, last2, out_first);
403b62047bSLouis Dionne EXPECT_TRUE(res == out_last, "wrong return result from merge");
413b62047bSLouis Dionne EXPECT_TRUE(is_sorted(out_first, res), "wrong result from merge");
423b62047bSLouis Dionne }
433b62047bSLouis Dionne }
443b62047bSLouis Dionne
453b62047bSLouis Dionne // for reverse iterators
463b62047bSLouis Dionne template <typename Policy, typename InputIterator1, typename InputIterator2, typename OutputIterator,
473b62047bSLouis Dionne typename Compare>
483b62047bSLouis Dionne void
operator ()test_merge493b62047bSLouis Dionne operator()(Policy&& exec, std::reverse_iterator<InputIterator1> first1, std::reverse_iterator<InputIterator1> last1,
503b62047bSLouis Dionne std::reverse_iterator<InputIterator2> first2, std::reverse_iterator<InputIterator2> last2,
5101963cecSLouis Dionne std::reverse_iterator<OutputIterator> out_first, std::reverse_iterator<OutputIterator> out_last, Compare)
523b62047bSLouis Dionne {
533b62047bSLouis Dionne using namespace std;
543b62047bSLouis Dionne typedef typename std::iterator_traits<std::reverse_iterator<InputIterator1>>::value_type T;
553b62047bSLouis Dionne const auto res = merge(exec, first1, last1, first2, last2, out_first, std::greater<T>());
563b62047bSLouis Dionne
573b62047bSLouis Dionne EXPECT_TRUE(res == out_last, "wrong return result from merge with predicate");
583b62047bSLouis Dionne EXPECT_TRUE(is_sorted(out_first, res, std::greater<T>()), "wrong result from merge with predicate");
593b62047bSLouis Dionne EXPECT_TRUE(includes(out_first, res, first1, last1, std::greater<T>()),
603b62047bSLouis Dionne "first sequence is not a part of result");
613b62047bSLouis Dionne EXPECT_TRUE(includes(out_first, res, first2, last2, std::greater<T>()),
623b62047bSLouis Dionne "second sequence is not a part of result");
633b62047bSLouis Dionne }
643b62047bSLouis Dionne };
653b62047bSLouis Dionne
663b62047bSLouis Dionne template <typename T, typename Generator1, typename Generator2>
673b62047bSLouis Dionne void
test_merge_by_type(Generator1 generator1,Generator2 generator2)683b62047bSLouis Dionne test_merge_by_type(Generator1 generator1, Generator2 generator2)
693b62047bSLouis Dionne {
703b62047bSLouis Dionne using namespace std;
713b62047bSLouis Dionne size_t max_size = 100000;
723b62047bSLouis Dionne Sequence<T> in1(max_size, generator1);
733b62047bSLouis Dionne Sequence<T> in2(max_size / 2, generator2);
743b62047bSLouis Dionne Sequence<T> out(in1.size() + in2.size());
753b62047bSLouis Dionne std::sort(in1.begin(), in1.end());
763b62047bSLouis Dionne std::sort(in2.begin(), in2.end());
773b62047bSLouis Dionne
783b62047bSLouis Dionne for (size_t size = 0; size <= max_size; size = size <= 16 ? size + 1 : size_t(3.1415 * size))
793b62047bSLouis Dionne {
803b62047bSLouis Dionne invoke_on_all_policies(test_merge(), in1.cbegin(), in1.cbegin() + size, in2.data(), in2.data() + size / 2,
813b62047bSLouis Dionne out.begin(), out.begin() + 1.5 * size, std::less<T>());
823b62047bSLouis Dionne invoke_on_all_policies(test_merge(), in1.data(), in1.data() + size, in2.cbegin(), in2.cbegin() + size / 2,
833b62047bSLouis Dionne out.begin(), out.begin() + 3 * size / 2, std::less<T>());
843b62047bSLouis Dionne }
853b62047bSLouis Dionne }
863b62047bSLouis Dionne
873b62047bSLouis Dionne template <typename T>
883b62047bSLouis Dionne struct test_non_const
893b62047bSLouis Dionne {
903b62047bSLouis Dionne template <typename Policy, typename InputIterator, typename OutputIterator>
913b62047bSLouis Dionne void
operator ()test_non_const923b62047bSLouis Dionne operator()(Policy&& exec, InputIterator input_iter, OutputIterator out_iter)
933b62047bSLouis Dionne {
943b62047bSLouis Dionne merge(exec, input_iter, input_iter, input_iter, input_iter, out_iter, non_const(std::less<T>()));
953b62047bSLouis Dionne }
963b62047bSLouis Dionne };
973b62047bSLouis Dionne
98249c1c74SLouis Dionne int
main()993b62047bSLouis Dionne main()
1003b62047bSLouis Dionne {
1013b62047bSLouis Dionne test_merge_by_type<int32_t>([](size_t v) { return (v % 2 == 0 ? v : -v) * 3; }, [](size_t v) { return v * 2; });
1023b62047bSLouis Dionne test_merge_by_type<float64_t>([](size_t v) { return float64_t(v); }, [](size_t v) { return float64_t(v - 100); });
1033b62047bSLouis Dionne
104*3b9a1bb1SLouis Dionne #if !defined(_PSTL_ICC_16_17_TEST_64_TIMEOUT)
1053b62047bSLouis Dionne test_merge_by_type<Wrapper<int16_t>>([](size_t v) { return Wrapper<int16_t>(v % 100); },
1063b62047bSLouis Dionne [](size_t v) { return Wrapper<int16_t>(v % 10); });
1073b62047bSLouis Dionne #endif
1083b62047bSLouis Dionne
1093b62047bSLouis Dionne test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
1103b62047bSLouis Dionne
1113b62047bSLouis Dionne std::cout << done() << std::endl;
1123b62047bSLouis Dionne return 0;
1133b62047bSLouis Dionne }
114