// -*- 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 // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14 #include "support/pstl_test_config.h" #include <iterator> #include <execution> #include <algorithm> #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&) { 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); } } int main() { test<wrapper<uint16_t>>(); test<wrapper<float64_t>>(); test<int32_t>(); test<float32_t>(); std::cout << done() << std::endl; return 0; }