// -*- C++ -*- //===-- set.pass.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14 #include "support/pstl_test_config.h" #include #include #include #include #include "support/utils.h" using namespace TestUtils; template struct Num { T val; Num() : val{} {} Num(const T& v) : val(v) {} //for "includes" checks template bool operator<(const Num& v1) const { return val < v1.val; } //The types Type1 and Type2 must be such that an object of type InputIt can be dereferenced and then implicitly converted to both of them template operator Num() const { return Num((T1)val); } friend bool operator==(const Num& v1, const Num& v2) { return v1.val == v2.val; } }; struct test_one_policy { template typename std::enable_if::value, void>::type operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp) { using T1 = typename std::iterator_traits::value_type; auto n1 = std::distance(first1, last1); auto n2 = std::distance(first2, last2); auto n = n1 + n2; Sequence expect(n); Sequence out(n); //1. set_union auto expect_res = std::set_union(first1, last1, first2, last2, expect.begin(), comp); auto res = std::set_union(exec, first1, last1, first2, last2, out.begin(), comp); EXPECT_TRUE(expect_res - expect.begin() == res - out.begin(), "wrong result for set_union"); EXPECT_EQ_N(expect.begin(), out.begin(), std::distance(out.begin(), res), "wrong set_union effect"); //2. set_intersection expect_res = std::set_intersection(first1, last1, first2, last2, expect.begin(), comp); res = std::set_intersection(exec, first1, last1, first2, last2, out.begin(), comp); EXPECT_TRUE(expect_res - expect.begin() == res - out.begin(), "wrong result for set_intersection"); EXPECT_EQ_N(expect.begin(), out.begin(), std::distance(out.begin(), res), "wrong set_intersection effect"); //3. set_difference expect_res = std::set_difference(first1, last1, first2, last2, expect.begin(), comp); res = std::set_difference(exec, first1, last1, first2, last2, out.begin(), comp); EXPECT_TRUE(expect_res - expect.begin() == res - out.begin(), "wrong result for set_difference"); EXPECT_EQ_N(expect.begin(), out.begin(), std::distance(out.begin(), res), "wrong set_difference effect"); //4. set_symmetric_difference expect_res = std::set_symmetric_difference(first1, last1, first2, last2, expect.begin(), comp); res = std::set_symmetric_difference(exec, first1, last1, first2, last2, out.begin(), comp); EXPECT_TRUE(expect_res - expect.begin() == res - out.begin(), "wrong result for set_symmetric_difference"); EXPECT_EQ_N(expect.begin(), out.begin(), std::distance(out.begin(), res), "wrong set_symmetric_difference effect"); } template typename std::enable_if::value, void>::type operator()(Policy&&, InputIterator1, InputIterator1, InputIterator2, InputIterator2, Compare) { } }; template void test_set(Compare compare) { const std::size_t n_max = 100000; // The rand()%(2*n+1) encourages generation of some duplicates. std::srand(4200); for (std::size_t n = 0; n < n_max; n = n <= 16 ? n + 1 : size_t(3.1415 * n)) { for (std::size_t m = 0; m < n_max; m = m <= 16 ? m + 1 : size_t(2.71828 * m)) { //prepare the input ranges Sequence in1(n, [](std::size_t k) { return rand() % (2 * k + 1); }); Sequence in2(m, [m](std::size_t k) { return (m % 2) * rand() + rand() % (k + 1); }); std::sort(in1.begin(), in1.end(), compare); std::sort(in2.begin(), in2.end(), compare); invoke_on_all_policies(test_one_policy(), in1.begin(), in1.end(), in2.cbegin(), in2.cend(), compare); } } } template struct test_non_const { template void operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter) { set_difference(exec, input_iter, input_iter, input_iter, input_iter, out_iter, non_const(std::less())); set_intersection(exec, input_iter, input_iter, input_iter, input_iter, out_iter, non_const(std::less())); set_symmetric_difference(exec, input_iter, input_iter, input_iter, input_iter, out_iter, non_const(std::less())); set_union(exec, input_iter, input_iter, input_iter, input_iter, out_iter, non_const(std::less())); } }; int32_t main() { test_set(__pstl::__internal::__pstl_less()); test_set, Num>([](const Num& x, const Num& y) { return x < y; }); test_algo_basic_double(run_for_rnd_fw>()); std::cout << done() << std::endl; return 0; }