diff options
Diffstat (limited to 'pstl/test/test_reverse_copy.cpp')
-rw-r--r-- | pstl/test/test_reverse_copy.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/pstl/test/test_reverse_copy.cpp b/pstl/test/test_reverse_copy.cpp new file mode 100644 index 00000000000..b532dba66ff --- /dev/null +++ b/pstl/test/test_reverse_copy.cpp @@ -0,0 +1,132 @@ +// -*- C++ -*- +//===-- test_reverse_copy.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; + wrapper() {} + explicit wrapper(T t_) : t(t_) {} + wrapper& + operator=(const T& t_) + { + t = t_; + return *this; + } + bool + operator==(const wrapper& t_) const + { + return t == t_.t; + } +}; + +template <typename T1, typename T2> +bool +eq(const wrapper<T1>& a, const wrapper<T2>& b) +{ + return a.t == b.t; +} + +template <typename T1, typename T2> +bool +eq(const T1& a, const T2& b) +{ + return a == b; +} + +// we need to save state here, because we need to test with different types of iterators +// due to the caller invoke_on_all_policies does forcing modification passed iterator type to cover additional usage cases. +template <typename Iterator> +struct test_one_policy +{ + Iterator data_b; + Iterator data_e; + test_one_policy(Iterator b, Iterator e) : data_b(b), data_e(e) {} + +#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \ + __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration + template <typename Iterator1> + typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type + operator()(pstl::execution::unsequenced_policy, Iterator1 actual_b, Iterator1 actual_e) + { + } + template <typename Iterator1> + typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type + operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 actual_b, Iterator1 actual_e) + { + } +#endif + + template <typename ExecutionPolicy, typename Iterator1> + void + operator()(ExecutionPolicy&& exec, Iterator1 actual_b, Iterator1 actual_e) + { + using namespace std; + using T = typename iterator_traits<Iterator1>::value_type; + using DifferenceType = typename iterator_traits<Iterator1>::difference_type; + + fill(actual_b, actual_e, T(-123)); + Iterator1 actual_return = reverse_copy(exec, data_b, data_e, actual_b); + + EXPECT_TRUE(actual_return == actual_e, "wrong result of reverse_copy"); + + const auto n = std::distance(data_b, data_e); + Sequence<T> res(n); + std::copy(std::reverse_iterator<Iterator>(data_e), std::reverse_iterator<Iterator>(data_b), res.begin()); + + EXPECT_EQ_N(res.begin(), actual_b, n, "wrong effect of reverse_copy"); + } +}; + +template <typename T1, typename T2> +void +test() +{ + typedef typename Sequence<T1>::iterator iterator_type; + typedef typename Sequence<T1>::const_bidirectional_iterator cbi_iterator_type; + + const std::size_t max_len = 100000; + + Sequence<T2> actual(max_len); + + Sequence<T1> data(max_len, [](std::size_t i) { return T1(i); }); + + 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<iterator_type>(data.begin(), data.begin() + len), actual.begin(), + actual.begin() + len); + invoke_on_all_policies(test_one_policy<cbi_iterator_type>(data.cbibegin(), std::next(data.cbibegin(), len)), + actual.begin(), actual.begin() + len); + } +} + +int32_t +main() +{ + // clang-3.8 fails to correctly auto vectorize the loop in some cases of different types of container's elements, + // for example: int32_t and int8_t. This issue isn't detected for clang-3.9 and newer versions. + test<int16_t, int8_t>(); + test<uint16_t, float32_t>(); + test<float64_t, int64_t>(); + test<wrapper<float64_t>, wrapper<float64_t>>(); + + std::cout << done() << std::endl; + return 0; +} |