Iros
 
Loading...
Searching...
No Matches
pop_heap.h
Go to the documentation of this file.
1#pragma once
2
9
10namespace di::container {
11namespace detail {
13 template<concepts::RandomAccessIterator It, concepts::SentinelFor<It> Sent, typename Comp = function::Compare,
14 typename Proj = function::Identity>
16 constexpr auto operator()(It first, Sent last, Comp comp = {}, Proj proj = {}) const -> It {
17 auto dist = container::distance(first, last);
18 return impl(util::move(first), util::ref(comp), util::ref(proj), dist);
19 }
20
21 template<concepts::RandomAccessContainer Con, typename Comp = function::Compare,
22 typename Proj = function::Identity>
24 constexpr auto operator()(Con&& container, Comp comp = {}, Proj proj = {}) const
27 }
28
29 private:
30 friend struct MakeHeapFunction;
31
32 constexpr static void bubble_down(auto first, auto comp, auto proj, auto size, decltype(size) index) {
33 using IndexType = decltype(size);
34
35 auto child_indices = [&](auto index) -> Tuple<Optional<IndexType>, Optional<IndexType>> {
36 auto left_index = 2 * (index + 1) - 1;
37 auto right_index = 2 * (index + 1);
38
39 auto maybe_index = [&](IndexType index) -> Optional<IndexType> {
40 if (index >= size) {
41 return nullopt;
42 }
43 return index;
44 };
45 return { maybe_index(left_index), maybe_index(right_index) };
46 };
47
48 for (;;) {
49 auto [left_child, right_child] = child_indices(index);
50 if (!left_child) {
51 break;
52 }
53 if (!right_child) {
54 if (function::invoke(comp, function::invoke(proj, first[*left_child]),
55 function::invoke(proj, first[index])) > 0) {
56 container::iterator_swap(first + *left_child, first + index);
57 }
58 break;
59 }
60
61 auto largest_child = function::invoke(comp, function::invoke(proj, first[*left_child]),
62 function::invoke(proj, first[*right_child])) > 0
63 ? *left_child
64 : *right_child;
65 if (function::invoke(comp, function::invoke(proj, first[index]),
66 function::invoke(proj, first[largest_child])) > 0) {
67 break;
68 }
69 container::iterator_swap(first + index, first + largest_child);
70 index = largest_child;
71 }
72 }
73
74 constexpr static auto impl(auto first, auto comp, auto proj, auto size) {
75 auto last = first + size;
76 container::iterator_swap(first, first + --size);
77 bubble_down(first, util::ref(comp), util::ref(proj), size, 0);
78 return last;
79 }
80 };
81}
82
83constexpr inline auto pop_heap = detail::PopHeapFunction {};
84}
85
86namespace di {
88}
Definition optional_forward_declaration.h:5
Definition tuple_forward_declaration.h:5
Definition random_access_container.h:8
Definition sortable.h:11
Definition sequence.h:13
constexpr auto last(concepts::detail::ConstantVector auto &vector, size_t count)
Definition vector_last.h:13
constexpr auto first(concepts::detail::ConstantVector auto &vector, size_t count)
Definition vector_first.h:13
Definition sequence.h:12
constexpr auto distance
Definition distance.h:44
constexpr auto size
Definition size.h:54
constexpr auto iterator_swap
Definition iterator_swap.h:49
constexpr auto pop_heap
Definition pop_heap.h:83
constexpr auto begin
Definition begin.h:44
constexpr auto invoke
Definition invoke.h:100
Conditional< concepts::BorrowedContainer< Con >, ContainerIterator< Con >, container::Dangling > BorrowedIterator
Definition borrowed_iterator.h:11
constexpr auto ref
Definition reference_wrapper.h:98
Definition zstring_parser.h:9
constexpr auto nullopt
Definition nullopt.h:15
constexpr auto proj
Definition proj.h:59
friend struct MakeHeapFunction
Definition pop_heap.h:30
Definition compare.h:8
Definition identity.h:7