diff options
Diffstat (limited to 'pstl/test/test_swap_ranges.cpp')
-rw-r--r-- | pstl/test/test_swap_ranges.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/pstl/test/test_swap_ranges.cpp b/pstl/test/test_swap_ranges.cpp new file mode 100644 index 00000000000..d32aa3d6f74 --- /dev/null +++ b/pstl/test/test_swap_ranges.cpp @@ -0,0 +1,132 @@ +// -*- C++ -*- +//===-- test_swap_ranges.cpp ----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "pstl_test_config.h" + +#include <iterator> + +#include "pstl/execution" +#include "pstl/algorithm" +#include "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& a) + { + 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); + } +} + +int32_t +main() +{ + test<wrapper<uint16_t>>(); + test<wrapper<float64_t>>(); + test<int32_t>(); + test<float32_t>(); + + std::cout << done() << std::endl; + return 0; +} |