summaryrefslogtreecommitdiffstats
path: root/pstl/test/test_rotate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pstl/test/test_rotate.cpp')
-rw-r--r--pstl/test/test_rotate.cpp172
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;
+}
OpenPOWER on IntegriCloud