diff options
Diffstat (limited to 'pstl/test/test_rotate.cpp')
-rw-r--r-- | pstl/test/test_rotate.cpp | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/pstl/test/test_rotate.cpp b/pstl/test/test_rotate.cpp new file mode 100644 index 00000000000..b94bb8e8394 --- /dev/null +++ b/pstl/test/test_rotate.cpp @@ -0,0 +1,172 @@ +// -*- C++ -*- +//===-- test_rotate.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; + int move_count; + explicit wrapper(T t_) : t(t_), move_count(0) {} + wrapper& + operator=(const T& t_) + { + t = t_; + return *this; + } + + wrapper(const wrapper<T>& a) : move_count(0) { t = a.t; } + + wrapper<T>& + operator=(wrapper<T>& a) + { + t = a.t; + return *this; + } + + wrapper<T>& + operator=(wrapper<T>&& a) + { + t = a.t; + move_count += 1; + return *this; + } +}; + +template <typename T> +struct compare +{ + bool + operator()(const T& a, const T& b) + { + return a == b; + } +}; + +template <typename T> +struct compare<wrapper<T>> +{ + bool + operator()(const wrapper<T>& a, const wrapper<T>& b) + { + return a.t == b.t; + } +}; +#include <typeinfo> + +struct test_one_policy +{ + +#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \ + __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specializations to skip testing in case of broken configuration + template <typename Iterator, typename Size> + void + operator()(pstl::execution::unsequenced_policy, Iterator data_b, Iterator data_e, Iterator actual_b, + Iterator actual_e, Size shift) + { + } + template <typename Iterator, typename Size> + void + operator()(pstl::execution::parallel_unsequenced_policy, Iterator data_b, Iterator data_e, Iterator actual_b, + Iterator actual_e, Size shift) + { + } +#endif + + template <typename ExecutionPolicy, typename Iterator, typename Size> + void + operator()(ExecutionPolicy&& exec, Iterator data_b, Iterator data_e, Iterator actual_b, Iterator actual_e, + Size shift) + { + using namespace std; + using T = typename iterator_traits<Iterator>::value_type; + Iterator actual_m = std::next(actual_b, shift); + + copy(data_b, data_e, actual_b); + Iterator actual_return = rotate(exec, actual_b, actual_m, actual_e); + + EXPECT_TRUE(actual_return == std::next(actual_b, std::distance(actual_m, actual_e)), "wrong result of rotate"); + auto comparator = compare<T>(); + bool check = std::equal(actual_return, actual_e, data_b, comparator); + check = check && std::equal(actual_b, actual_return, std::next(data_b, shift), comparator); + + EXPECT_TRUE(check, "wrong effect of rotate"); + EXPECT_TRUE(check_move(exec, actual_b, actual_e, shift), "wrong move test of rotate"); + } + + template <typename ExecutionPolicy, typename Iterator, typename Size> + typename std::enable_if< + is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value && + !std::is_same<ExecutionPolicy, pstl::execution::sequenced_policy>::value && + std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value, + bool>::type + check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift) + { + bool result = all_of(b, e, [](wrapper<float32_t>& a) { + bool temp = a.move_count > 0; + a.move_count = 0; + return temp; + }); + return shift == 0 || result; + } + + template <typename ExecutionPolicy, typename Iterator, typename Size> + typename std::enable_if< + !(is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value && + !std::is_same<ExecutionPolicy, pstl::execution::sequenced_policy>::value && + std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value), + bool>::type + check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift) + { + return true; + } +}; + +template <typename T> +void +test() +{ + const int32_t max_len = 100000; + + Sequence<T> actual(max_len, [](std::size_t i) { return T(i); }); + Sequence<T> data(max_len, [](std::size_t i) { return T(i); }); + + for (int32_t len = 0; len < max_len; len = len <= 16 ? len + 1 : int32_t(3.1415 * len)) + { + int32_t shifts[] = {0, 1, 2, len / 3, (2 * len) / 3, len - 1}; + for (auto shift : shifts) + { + if (shift >= 0 && shift < len) + { + invoke_on_all_policies(test_one_policy(), data.begin(), data.begin() + len, actual.begin(), + actual.begin() + len, shift); + } + } + } +} + +int32_t +main() +{ + test<int32_t>(); + test<wrapper<float64_t>>(); + + std::cout << done() << std::endl; + return 0; +} |