51 using value_compare = Compare;
59 using const_reference = T
const&;
114 constexpr auto top()
const noexcept -> T& {
116 return static_cast<T&>(*root_);
125 constexpr auto empty()
const noexcept ->
bool {
return size() == size_type{}; }
130 constexpr void push(reference value)
noexcept {
131 ARENE_PRECONDITION(!value.tree_node::is_linked());
134 root_ =
static_cast<tree_node*>(&value);
135 parent(*root_) = root_;
142 auto& parent_of_new_node = find_node_by_index((size_ + 1U) >> 1U);
143 if (!is_even(size_)) {
145 left(parent_of_new_node) =
static_cast<tree_node*>(&value);
148 right(parent_of_new_node) =
static_cast<tree_node*>(&value);
150 parent(value) = &parent_of_new_node;
160 constexpr void pop()
noexcept {
161 ARENE_PRECONDITION(!empty());
169 constexpr void erase(reference node)
noexcept {
170 ARENE_PRECONDITION(!empty());
171 ARENE_PRECONDITION(contains(node));
179 swap(size_, other.size_);
180 swap(root_, other.root_);
205 static constexpr auto is_even(std::size_t value)
noexcept ->
bool {
return (value & std::size_t{1U}) == 0U; }
210 constexpr void erase_impl(tree_node& node)
noexcept {
213 parent(*root_) =
nullptr;
219 auto& last_node = find_node_by_index(size_);
220 bool reheapify_needed{
false};
222 if (
static_cast<tree_node*>(&node) != &last_node) {
224 swap_nodes(node, last_node);
225 reheapify_needed =
true;
229 if (left(*parent(node)) ==
static_cast<tree_node*>(&node)) {
230 left(*parent(node)) =
nullptr;
232 right(*parent(node)) =
nullptr;
234 parent(node) =
nullptr;
237 if (reheapify_needed) {
238 re_heapify(last_node);
249 constexpr auto compare_value(tree_node
const& node1, tree_node
const& node2)
const noexcept ->
bool {
250 return comp_(
static_cast<T
const&>(node1),
static_cast<T
const&>(node2));
255 constexpr void move_node_up(tree_node& node)
noexcept {
256 while ((&node != root_) &&
257 compare_value(*parent(node), node)) {
258 if (left(*parent(node)) == &node) {
259 swap_with_left(*parent(node));
261 swap_with_right(*parent(node));
268 constexpr void move_node_down(tree_node& node)
noexcept {
269 while ((left(node) !=
nullptr) || (right(node) !=
nullptr)) {
270 bool should_swap_with_left{(left(node) !=
nullptr) && compare_value(node, *left(node))};
271 bool should_swap_with_right{(right(node) !=
nullptr) && compare_value(node, *right(node))};
273 if (should_swap_with_left && should_swap_with_right) {
274 should_swap_with_left = compare_value(*right(node), *left(node));
277 if (should_swap_with_left) {
278 swap_with_left(node);
279 }
else if (should_swap_with_right) {
280 swap_with_right(node);
290 constexpr void re_heapify(tree_node& node)
noexcept {
292 move_node_down(node);
300 constexpr auto find_node_by_index(std::size_t n)
const noexcept -> tree_node& {
301 std::size_t
const layers_num{log2(n)};
303 for (std::size_t i{1U}; i < layers_num + 1U; ++i) {
310 ARENE_INVARIANT((layers_num - i) <= (
sizeof(std::size_t) * std::size_t{CHAR_BIT} - 1U));
314 if (is_even(n >> (layers_num - i))) {
321 ARENE_INVARIANT(ptr !=
nullptr);
327 constexpr void swap_with_left(tree_node& node)
noexcept { swap_nodes(node, *left(node)); }
331 constexpr void swap_with_right(tree_node& node)
noexcept { swap_nodes(node, *right(node)); }
337 constexpr auto contains(tree_node& node)
const noexcept ->
bool {
338 auto* traversed_root = &node;
339 while ((parent(*traversed_root) !=
nullptr) && (parent(*traversed_root) != traversed_root)) {
340 traversed_root = parent(*traversed_root);
343 return traversed_root == root_;
350 constexpr void swap_nodes(tree_node& node_1, tree_node& node_2)
noexcept {
351 if ((root_ == &node_1) || (root_ == &node_2)) {
352 parent(*root_) =
nullptr;
355 if (parent(node_1) != parent(node_2)) {
356 ::arene::base::swap(parent(node_1), parent(node_2));
361 update_child_of_parent(node_2, node_1);
364 update_child_of_parent(node_1, node_2);
366 auto* parent_node_ptr = parent(node_1);
367 ARENE_INVARIANT(parent_node_ptr !=
nullptr);
368 auto& common_parent_node = *parent_node_ptr;
370 ::arene::base::swap(left(common_parent_node), right(common_parent_node));
374 ::arene::base::swap(left(node_1), left(node_2));
375 ::arene::base::swap(right(node_1), right(node_2));
378 update_parent_of_child(node_1);
379 update_parent_of_child(node_2);
382 if (root_ == &node_1) {
384 parent(*root_) = root_;
392 static constexpr void update_child_of_parent(tree_node& node_1, tree_node& node_2)
noexcept {
393 if (parent(node_1) !=
nullptr) {
394 if (left(*parent(node_1)) == &node_2) {
395 left(*parent(node_1)) = &node_1;
397 right(*parent(node_1)) = &node_1;
406 static constexpr void update_parent_of_child(tree_node& node)
noexcept {
407 if (left(node) !=
nullptr) {
408 parent(*left(node)) = &node;
410 if (right(node) !=
nullptr) {
411 parent(*right(node)) = &node;
418 static constexpr auto parent(tree_node& node)
noexcept -> tree_node*& {
419 return get_parent_link(node, Tag{}, detail::binary_tree_node_pass_key{});
424 static constexpr auto left(tree_node& node)
noexcept -> tree_node*& {
425 return get_left_link(node, Tag{}, detail::binary_tree_node_pass_key{});
430 static constexpr auto right(tree_node& node)
noexcept -> tree_node*& {
431 return get_right_link(node, Tag{}, detail::binary_tree_node_pass_key{});
440 tree_node* root_{
nullptr};