diff options
Diffstat (limited to 'pstl/test/test_is_heap.cpp')
-rw-r--r-- | pstl/test/test_is_heap.cpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/pstl/test/test_is_heap.cpp b/pstl/test/test_is_heap.cpp new file mode 100644 index 00000000000..42751f22fac --- /dev/null +++ b/pstl/test/test_is_heap.cpp @@ -0,0 +1,143 @@ +// -*- C++ -*- +//===-- test_is_heap.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. +// +//===----------------------------------------------------------------------===// + +// Tests for is_heap, is_heap_until +#include "pstl_test_config.h" + +#include "pstl/execution" +#include "pstl/algorithm" +#include "utils.h" +#include <iostream> + +using namespace TestUtils; + +struct WithCmpOp +{ + int32_t _first; + int32_t _second; + WithCmpOp() : _first(0), _second(0){}; + explicit WithCmpOp(int32_t x) : _first(x), _second(x){}; + bool + operator<(const WithCmpOp& rhs) const + { + return this->_first < rhs._first; + } +}; + +struct test_is_heap +{ +#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 Iterator, typename Predicate> + typename std::enable_if<is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value, void>::type + operator()(pstl::execution::unsequenced_policy, Iterator first, Iterator last, Predicate pred) + { + } + template <typename Iterator, typename Predicate> + typename std::enable_if<is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value, void>::type + operator()(pstl::execution::parallel_unsequenced_policy, Iterator first, Iterator last, Predicate pred) + { + } +#endif + + template <typename Policy, typename Iterator, typename Predicate> + typename std::enable_if<is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value, void>::type + operator()(Policy&& exec, Iterator first, Iterator last, Predicate pred) + { + using namespace std; + // is_heap + { + bool expected = is_heap(first, last); + bool actual = is_heap(exec, first, last); + EXPECT_TRUE(expected == actual, "wrong return value from is_heap"); + } + // is_heap with predicate + { + bool expected = is_heap(first, last, pred); + bool actual = is_heap(exec, first, last, pred); + EXPECT_TRUE(expected == actual, "wrong return value from is_heap with predicate"); + } + // is_heap_until + { + Iterator expected = is_heap_until(first, last); + Iterator actual = is_heap_until(exec, first, last); + EXPECT_TRUE(expected == actual, "wrong return value from is_heap_until"); + } + // is_heap_until with predicate + { + const Iterator expected = is_heap_until(first, last, pred); + const auto y = std::distance(first, expected); + const Iterator actual = is_heap_until(exec, first, last, pred); + const auto x = std::distance(first, actual); + EXPECT_TRUE(expected == actual, "wrong return value from is_heap_until with predicate"); + } + } + + // is_heap, is_heap_until works only with random access iterators + template <typename Policy, typename Iterator, typename Predicate> + typename std::enable_if<!is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value, void>::type + operator()(Policy&& exec, Iterator first, Iterator last, Predicate pred) + { + } +}; + +template <typename T, typename Comp> +void +test_is_heap_by_type(Comp comp) +{ + using namespace std; + + const size_t max_size = 100000; + for (size_t n = 0; n <= max_size; n = n <= 16 ? n + 1 : size_t(3.1415 * n)) + { + Sequence<T> in(n, [](size_t v) -> T { return T(v); }); + + invoke_on_all_policies(test_is_heap(), in.begin(), in.end(), comp); + + std::make_heap(in.begin(), in.begin() + n / 4, comp); + invoke_on_all_policies(test_is_heap(), in.cbegin(), in.cend(), comp); + + std::make_heap(in.begin(), in.begin() + n / 3, comp); + invoke_on_all_policies(test_is_heap(), in.begin(), in.end(), comp); + + std::make_heap(in.begin(), in.end(), comp); + invoke_on_all_policies(test_is_heap(), in.cbegin(), in.cend(), comp); + } + + Sequence<T> in(max_size / 10, [](size_t v) -> T { return T(1); }); + invoke_on_all_policies(test_is_heap(), in.begin(), in.end(), comp); +} + +template <typename T> +struct test_non_const +{ + template <typename Policy, typename Iterator> + void + operator()(Policy&& exec, Iterator iter) + { + invoke_if(exec, [&]() { + is_heap(exec, iter, iter, non_const(std::less<T>())); + is_heap_until(exec, iter, iter, non_const(std::less<T>())); + }); + } +}; + +int32_t +main() +{ + test_is_heap_by_type<float32_t>(std::greater<float32_t>()); + test_is_heap_by_type<WithCmpOp>(std::less<WithCmpOp>()); + test_is_heap_by_type<uint64_t>([](uint64_t x, uint64_t y) { return x % 100 < y % 100; }); + + test_algo_basic_single<int32_t>(run_for_rnd<test_non_const<int32_t>>()); + + std::cout << done() << std::endl; + return 0; +} |