1 // -*- C++ -*- 2 //===-- swap_ranges.pass.cpp ----------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++98, c++03, c++11, c++14 11 12 #include "support/pstl_test_config.h" 13 14 #include <iterator> 15 #include <execution> 16 #include <algorithm> 17 18 #include "support/utils.h" 19 20 using namespace TestUtils; 21 22 template <typename T> 23 struct wrapper 24 { 25 T t; 26 std::size_t number_of_swaps = 0; 27 wrapper() {} 28 explicit wrapper(T t_) : t(t_) {} 29 template <typename U> 30 void 31 operator=(const U& b) 32 { 33 t = b; 34 } 35 bool 36 operator==(const wrapper<T>& a) const 37 { 38 return t == a.t; 39 } 40 }; 41 42 template <typename T> 43 void 44 swap(wrapper<T>& a, wrapper<T>& b) 45 { 46 std::swap(a.t, b.t); 47 a.number_of_swaps++; 48 b.number_of_swaps++; 49 } 50 51 template <typename T> 52 struct check_swap 53 { 54 bool 55 operator()(T&) 56 { 57 return true; 58 } 59 }; 60 61 template <typename T> 62 struct check_swap<wrapper<T>> 63 { 64 bool 65 operator()(wrapper<T>& a) 66 { 67 bool temp = (a.number_of_swaps == 1); 68 a.number_of_swaps = 0; 69 return temp; 70 } 71 }; 72 73 struct test_one_policy 74 { 75 template <typename ExecutionPolicy, typename Iterator1, typename Iterator2> 76 void 77 operator()(ExecutionPolicy&& exec, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b, Iterator2 actual_e) 78 { 79 using namespace std; 80 using T_ref = typename iterator_traits<Iterator1>::reference; 81 using T = typename iterator_traits<Iterator1>::value_type; 82 83 iota(data_b, data_e, 0); 84 iota(actual_b, actual_e, std::distance(data_b, data_e)); 85 86 Iterator2 actual_return = swap_ranges(exec, data_b, data_e, actual_b); 87 bool check_return = (actual_return == actual_e); 88 EXPECT_TRUE(check_return, "wrong result of swap_ranges"); 89 if (check_return) 90 { 91 std::size_t i = 0; 92 bool check = all_of(actual_b, actual_e, [&i](T_ref a) { return a == T(i++); }) && 93 all_of(data_b, data_e, [&i](T_ref a) { return a == T(i++); }); 94 95 EXPECT_TRUE(check, "wrong effect of swap_ranges"); 96 97 if (check) 98 { 99 bool swap_check = 100 all_of(data_b, data_e, check_swap<T>()) && all_of(actual_b, actual_e, check_swap<T>()); 101 EXPECT_TRUE(swap_check, "wrong effect of swap_ranges swap check"); 102 } 103 } 104 } 105 }; 106 107 template <typename T> 108 void 109 test() 110 { 111 const std::size_t max_len = 100000; 112 113 Sequence<T> data(max_len); 114 Sequence<T> actual(max_len); 115 116 for (std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::size_t(3.1415 * len)) 117 { 118 invoke_on_all_policies(test_one_policy(), data.begin(), data.begin() + len, actual.begin(), 119 actual.begin() + len); 120 } 121 } 122 123 int32_t 124 main() 125 { 126 test<wrapper<uint16_t>>(); 127 test<wrapper<float64_t>>(); 128 test<int32_t>(); 129 test<float32_t>(); 130 131 std::cout << done() << std::endl; 132 return 0; 133 } 134