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