// Boost.Geometry // Copyright (c) 2021, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html #include #include #include #include #include #include #include using namespace boost::geometry::index::detail; struct noncopyable { noncopyable(int i_) : i(i_) {} noncopyable(noncopyable const&) = delete; noncopyable& operator=(noncopyable const&) = delete; noncopyable(noncopyable&&) = default; noncopyable& operator=(noncopyable&&) = default; bool operator<(noncopyable const& other) const { return i < other.i; } operator int() const { return i; } int i; }; template struct minmax_default { minmax_default() = default; minmax_default(std::vector const& vec) : heap(vec.begin(), vec.end()) { make_minmax_heap(heap.begin(), heap.end()); } T const& top() const { return heap[0]; } T const& bottom() const { return bottom_minmax_heap(heap.begin(), heap.end()); } void push(int i) { heap.push_back(T(i)); push_minmax_heap(heap.begin(), heap.end()); } void pop_top() { pop_top_minmax_heap(heap.begin(), heap.end()); heap.pop_back(); } void pop_bottom() { pop_bottom_minmax_heap(heap.begin(), heap.end()); heap.pop_back(); } bool is_heap() const { return is_minmax_heap(heap.begin(), heap.end()); } bool empty() const { return heap.empty(); } std::vector heap; }; template struct minmax_less { minmax_less() = default; minmax_less(std::vector const& vec) : heap(vec.begin(), vec.end()) { make_minmax_heap(heap.begin(), heap.end(), std::less<>()); } T const& top() const { return heap[0]; } T const& bottom() const { return bottom_minmax_heap(heap.begin(), heap.end(), std::less<>()); } void push(int i) { heap.push_back(T(i)); push_minmax_heap(heap.begin(), heap.end(), std::less<>()); } void pop_top() { pop_top_minmax_heap(heap.begin(), heap.end(), std::less<>()); heap.pop_back(); } void pop_bottom() { pop_bottom_minmax_heap(heap.begin(), heap.end(), std::less<>()); heap.pop_back(); } bool is_heap() const { return is_minmax_heap(heap.begin(), heap.end(), std::less<>()); } bool empty() const { return heap.empty(); } std::vector heap; }; template struct maxmin_greater { maxmin_greater() = default; maxmin_greater(std::vector const& vec) : heap(vec.begin(), vec.end()) { make_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); } T const& top() const { return heap[0]; } T const& bottom() const { return bottom_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); } void push(int i) { heap.push_back(T(i)); push_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); } void pop_top() { pop_top_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); heap.pop_back(); } void pop_bottom() { pop_bottom_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); heap.pop_back(); } bool is_heap() const { return is_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); } bool empty() const { return heap.empty(); } std::vector heap; }; template struct maxmin_default_switch { maxmin_default_switch() = default; maxmin_default_switch(std::vector const& vec) : heap(vec.begin(), vec.end()) { make_maxmin_heap(heap.begin(), heap.end()); } T const& bottom() const { return heap[0]; } T const& top() const { return bottom_maxmin_heap(heap.begin(), heap.end()); } void push(int i) { heap.push_back(T(i)); push_maxmin_heap(heap.begin(), heap.end()); } void pop_top() { pop_bottom_maxmin_heap(heap.begin(), heap.end()); heap.pop_back(); } void pop_bottom() { pop_top_maxmin_heap(heap.begin(), heap.end()); heap.pop_back(); } bool is_heap() const { return is_maxmin_heap(heap.begin(), heap.end()); } bool empty() const { return heap.empty(); } std::vector heap; }; template void test() { std::vector vec; int const n = 20; for (int i = 0; i < n; ++i) { vec.push_back(rand() % n); } { std::map map; Heap heap; for (int i : vec) { heap.push(i); BOOST_CHECK(heap.is_heap()); map[i]++; BOOST_CHECK_EQUAL(heap.top(), map.begin()->first); BOOST_CHECK_EQUAL(heap.bottom(), (--map.end())->first); } while (! heap.empty()) { int i = heap.top(); BOOST_CHECK_EQUAL(i, map.begin()->first); BOOST_CHECK_EQUAL(heap.bottom(), (--map.end())->first); BOOST_CHECK(map[i] > 0); map[i]--; if (map[i] <= 0) map.erase(i); heap.pop_top(); BOOST_CHECK(heap.is_heap()); } BOOST_CHECK(map.empty()); } { Heap heap(vec); BOOST_CHECK(heap.is_heap()); std::map map; for (int i : vec) map[i]++; BOOST_CHECK_EQUAL(heap.top(), map.begin()->first); BOOST_CHECK_EQUAL(heap.bottom(), (--map.end())->first); while (! heap.empty()) { int i = heap.bottom(); BOOST_CHECK_EQUAL(heap.top(), map.begin()->first); BOOST_CHECK_EQUAL(i, (--map.end())->first); BOOST_CHECK(map[i] > 0); map[i]--; if (map[i] <= 0) map.erase(i); heap.pop_bottom(); BOOST_CHECK(heap.is_heap()); } BOOST_CHECK(map.empty()); } } int test_main(int, char* []) { test>(); test>(); test>(); test>(); test>(); return 0; }