322 static_assert(!std::is_reference<Value>::value,
"Value must not be a reference type");
325 static_assert(std::is_empty<Compare>::value,
"Compare must be empty and stateless");
326 static_assert(std::is_empty<AllocPolicy>::value,
"AllocPolicy must be empty");
327 static_assert(std::is_empty<KeySelector>::value,
"KeySelector must be empty and stateless");
330 static_assert(std::is_default_constructible_v<Compare>,
"Compare must be default-constructible");
331 static_assert(std::is_default_constructible_v<AllocPolicy>,
"AllocPolicy must be default-constructible");
332 static_assert(std::is_default_constructible_v<KeySelector>,
"KeySelector must be default-constructible");
336 using key_selector = KeySelector;
338 friend class qtree_detail::qtree_tester;
340 template <
class,
class,
class,
class,
bool>
359 struct qtree_node_unpacked
362 qtree_node_unpacked *_parent() noexcept {
return parent_; }
363 qtree_node_unpacked
const *_parent() const noexcept {
return parent_; }
364 void _set_parent(qtree_node_unpacked *p)
noexcept { parent_ = p; }
366 Color _color() const noexcept {
return color_; }
367 void _set_color(
Color c)
noexcept { color_ = c; }
369 uint8_t _is_nil() const noexcept {
return is_nil_; }
370 void _set_is_nil(uint8_t is_nil)
noexcept { is_nil_ = is_nil; }
373 alignas(
alignof(
void *)) qtree_node_unpacked *parent_ =
nullptr;
374 alignas(
alignof(
void *)) qtree_node_unpacked *left_ =
nullptr;
375 alignas(
alignof(
void *)) qtree_node_unpacked *right_ =
nullptr;
377 uint8_t is_nil_ =
true;
378 alignas(Value) std::byte storage_[
sizeof(Value)] = {};
383 static_assert(offsetof(qtree_node_unpacked, parent_) == 0,
"qtree_node_unpacked::parent_ must be at offset 0");
384 static_assert(offsetof(qtree_node_unpacked, color_) == 3 *
sizeof(
void *),
"qtree_node_unpacked::color_ must follow the three pointer-sized fields");
385 static_assert(offsetof(qtree_node_unpacked, is_nil_) == 3 *
sizeof(
void *) + 1,
"qtree_node_unpacked::is_nil_ must follow color_");
386 static_assert(offsetof(qtree_node_unpacked, storage_) >= 3 *
sizeof(
void *) + 2,
"qtree_node_unpacked::storage_ must follow is_nil_");
392 struct qtree_node_packed
395 qtree_node_packed *_parent() noexcept {
return untag(parent_and_tags_); }
396 qtree_node_packed
const *_parent() const noexcept {
return untag(parent_and_tags_); }
398 void _set_parent(qtree_node_packed *p)
noexcept { parent_and_tags_ = tagptr(p, parent_and_tags_); }
401 void _set_color(
Color c)
noexcept { set_or_clear(c ==
Color::Red, color_mask_); }
403 uint8_t _is_nil() const noexcept {
return ternary(nil_mask_, (uint8_t)1, (uint8_t)0); }
404 void _set_is_nil(uint8_t is_nil)
noexcept { set_or_clear(is_nil != 0, nil_mask_); }
408 alignas(
alignof(
void *)) std::uintptr_t parent_and_tags_ = 0;
409 alignas(
alignof(
void *)) qtree_node_packed *left_ =
nullptr;
410 alignas(
alignof(
void *)) qtree_node_packed *right_ =
nullptr;
411 alignas(Value) std::byte storage_[
sizeof(Value)] = {};
413 static_assert(
alignof(
void *) >= 4,
"pointer tagging requires >= 2 tag bits");
415 static_assert(
sizeof(
void *) ==
sizeof(std::uintptr_t),
"uintptr_t must match pointer size");
418 static constexpr std::uintptr_t color_mask_ = 0x1;
419 static constexpr std::uintptr_t nil_mask_ = 0x2;
420 static constexpr std::uintptr_t tag_mask_ = color_mask_ | nil_mask_;
421 static constexpr std::uintptr_t ptr_mask_ = ~tag_mask_;
424 static qtree_node_packed *untag(std::uintptr_t v)
noexcept
426 return reinterpret_cast<qtree_node_packed*
>(v & ptr_mask_);
430 static std::uintptr_t tagptr(qtree_node_packed *p, std::uintptr_t tags)
noexcept
432 return (
reinterpret_cast<std::uintptr_t
>(p) & ptr_mask_) | (tags & tag_mask_);
436 template <
class T> T ternary(std::uintptr_t mask, T
t, T f)
const noexcept
438 return (parent_and_tags_ & mask) ?
t : f;
442 void set_or_clear(
bool b, std::uintptr_t mask)
445 parent_and_tags_ |= mask;
447 parent_and_tags_ &= ~mask;
453 static_assert(offsetof(qtree_node_packed, parent_and_tags_) == 0,
"qtree_node_packed::parent_and_tags_ must be at offset 0");
454 static_assert(
alignof(Value) >
alignof(
void *) || offsetof(qtree_node_packed, storage_) == 3 *
sizeof(
void *),
"qtree_node_packed::storage_ must immediately follow right_");
455 static_assert(
alignof(Value) <=
alignof(
void *) || offsetof(qtree_node_packed, storage_) > 3 *
sizeof(
void *),
"qtree_node_packed::storage_ must follow right_");
459 using node_type = std::conditional_t<PackNode, qtree_node_packed, qtree_node_unpacked>;
460 using node_alloc = qallocator<node_type, AllocPolicy>;
461 using node_traits = std::allocator_traits<node_alloc>;
462 static node_alloc make_node_alloc() noexcept {
return node_alloc {}; }
466 static_assert(
alignof(node_type) >=
alignof(
void *),
"node alignment");
467 static_assert(std::is_standard_layout<node_type>::value,
"node_type must be standard layout");
468 static_assert(offsetof(node_type, left_) %
alignof(
void *) == 0,
"packed layout not allowed");
469 static_assert(offsetof(node_type, left_) ==
sizeof(
void *),
"left_ must immediately follow parent field");
470 static_assert(offsetof(node_type, right_) %
alignof(
void *) == 0,
"packed layout not allowed");
471 static_assert(offsetof(node_type, right_) == 2 *
sizeof(
void *),
"right_ must immediately follow left_");
472 static_assert(offsetof(node_type, storage_) %
alignof(Value) == 0,
"storage_ must be Value-aligned (don't compile under packing)");
473 static_assert(
alignof(node_type) >= (
alignof(
void *) >
alignof(Value) ?
alignof(
void *) :
alignof(Value)),
"node alignment must meet pointer/value alignment");
507 : header_(
nullptr), node_count_(0)
513 insert(init.begin(), init.end());
517 : header_(nullptr), node_count_(0)
522 header_ = allocate_header();
531 node_delete(header_);
537 : header_(other.header_), node_count_(other.node_count_)
539 other.header_ =
nullptr;
540 other.node_count_ = 0;
545 if ( header_ !=
nullptr )
548 node_delete(header_);
554 if (
this == &other )
564 if (
this == &other )
568 if ( header_ !=
nullptr )
571 node_delete(header_);
574 header_ = other.header_;
575 node_count_ = other.node_count_;
577 other.header_ =
nullptr;
578 other.node_count_ = 0;
584 if (
this == &other )
587 swap(header_, other.header_);
588 swap(node_count_, other.node_count_);
590 friend void swap(
qtree &a,
qtree &b)
noexcept(
noexcept(a.swap(b))) { a.swap(b); }
608 reference operator*() const noexcept {
return *value_ptr(node_); }
639 return lhs.node_ == rhs.node_;
644 return !(lhs == rhs);
648 node_type *node_ =
nullptr;
654 void increment() { node_ = successor(node_); }
657 void decrement() { node_ = prev_including_header(node_); }
661 template <
class,
class,
class,
class,
bool>
665 static_assert(std::is_trivially_copyable<mutable_iterator>::value,
"iter must be trivial");
666 static_assert(
sizeof(
mutable_iterator) ==
sizeof(
void *),
"iter size must be 1 ptr");
717 return lhs.node_ == rhs.node_;
722 return !(lhs == rhs);
726 node_type *node_ =
nullptr;
732 void increment() { node_ = successor(node_); }
735 void decrement() { node_ = prev_including_header(node_); }
740 static_assert(std::is_trivially_copyable<const_iterator>::value,
"citer must be trivial");
741 static_assert(
sizeof(
const_iterator) ==
sizeof(
void *),
"citer size must be 1 ptr");
752 if ( header_ ==
nullptr || node_count_ == 0 )
756 const_iterator
begin() const noexcept
758 if ( header_ ==
nullptr || node_count_ == 0 )
760 return const_iterator(left(header_));
765 const_iterator
end() const noexcept {
return const_iterator(header_); }
766 const_iterator
cend() const noexcept {
return end(); }
777 friend bool operator==(mutable_iterator l, const_iterator r)
noexcept {
return const_iterator(l) == r; }
778 friend bool operator==(const_iterator l, mutable_iterator r)
noexcept {
return l == const_iterator(r); }
779 friend bool operator!=(mutable_iterator l, const_iterator r)
noexcept {
return !(l == r); }
780 friend bool operator!=(const_iterator l, mutable_iterator r)
noexcept {
return !(l == r); }
801 using enable_hetero_eqrange = std::enable_if_t<cmp_key_to_k_v<Compare, key_type, K> && cmp_k_to_key_v<Compare, K, key_type>,
int>;
814 bool empty() const noexcept {
return node_count_ == 0; }
834 return std::lexicographical_compare(a.
begin(), a.
end(), b.
begin(), b.
end());
859 return const_iterator(find_node(key));
862 template <
class K,
class = enable_hetero_eq<K>>
868 template <
class K,
class = enable_hetero_eq<K>>
869 [[nodiscard]] const_iterator
find(K
const &key)
const
871 return const_iterator(find_node(key));
876 return find_node(key) != header_;
879 template <
class K,
class = enable_hetero_eq<K>>
882 return find_node(key) != header_;
890 template <
class K,
class = enable_hetero_eq<K>>
898 return iterator(lower_bound_node(key));
903 return const_iterator(lower_bound_node(key));
906 template <
class K,
class = enable_hetero_lb<K>>
909 return iterator(lower_bound_node(key));
912 template <
class K,
class = enable_hetero_lb<K>>
915 return const_iterator(lower_bound_node(key));
920 return iterator(upper_bound_node(key));
925 return const_iterator(upper_bound_node(key));
928 template <
class K,
class = enable_hetero_ub<K>>
931 return iterator(upper_bound_node(key));
934 template <
class K,
class = enable_hetero_ub<K>>
937 return const_iterator(upper_bound_node(key));
950 template <
class K,
class = enable_hetero_eqrange<K>>
953 return {
iterator(lower_bound_node(key)),
iterator(upper_bound_node(key)) };
956 template <
class K,
class = enable_hetero_eqrange<K>>
959 return { const_iterator(lower_bound_node(key)), const_iterator(upper_bound_node(key)) };
966 template <
class InputIt>
969 for ( ; first != last; ++first )
973 void insert(std::initializer_list<value_type> init)
975 insert(init.begin(), init.end());
980 return lazy_emplace_impl(
981 KeySelector {} (value),
987 return lazy_emplace_impl(
988 KeySelector {} (value),
994 auto result = lazy_emplace_with_hint(
995 KeySelector {} (value),
1003 auto result = lazy_emplace_with_hint(
1004 KeySelector {} (value),
1010 template <
class... Args>
1014 return lazy_emplace_impl(
1015 KeySelector {} (tmp),
1019 template <
class... Args>
1023 auto result = lazy_emplace_with_hint(
1024 KeySelector {} (tmp),
1039 erase_node(
pos.node_);
1047 while ( it != last_it )
1054 node_type *node = find_node(key);
1055 if ( node == header_ )
1061 template <
class K,
class = enable_hetero_eq<K>>
1064 node_type *node = find_node(key);
1065 if ( node == header_ )
1071 template<
class Pred>
1075 for (
auto it =
begin(); it !=
end(); )
1090 if ( header_ ==
nullptr || node_count_ == 0 )
1094 if ( header_ !=
nullptr )
1099 clear_subtree(root());
1119 static node_type *left(node_type *node)
noexcept {
return node->left_; }
1120 static node_type
const *left(
const node_type *node)
noexcept {
return node->left_; }
1121 static void set_left(node_type *node, node_type *left)
noexcept { node->left_ = left; }
1123 static node_type *right(node_type *node)
noexcept {
return node->right_; }
1124 static node_type
const *right(
const node_type *node)
noexcept {
return node->right_; }
1125 static void set_right(node_type *node, node_type *right)
noexcept { node->right_ = right; }
1127 static node_type *parent(node_type *node)
noexcept {
return node->_parent(); }
1128 static node_type
const *parent(
const node_type *node)
noexcept {
return node->_parent(); }
1129 static void set_parent(node_type *node, node_type *parent)
noexcept { node->_set_parent(parent); }
1131 static Color color(
const node_type *node)
noexcept {
return node->_color(); }
1132 static void set_color(node_type *node,
Color color_val)
noexcept { node->_set_color(color_val); }
1134 static std::uint8_t is_nil(
const node_type *node)
noexcept {
return node->_is_nil(); }
1135 static void set_is_nil(node_type *node, std::uint8_t is_nil_val)
noexcept { node->_set_is_nil(is_nil_val); }
1143 static node_type *minimum(node_type *node)
1145 return minimum_impl(node);
1147 static const node_type *minimum(
const node_type *node)
1149 return minimum_impl(
const_cast<node_type *
>(node));
1151 static node_type *minimum_impl(node_type *node)
1153 QASSERT(3437, !is_nil(node));
1154 while ( !is_nil(left(node)) )
1167 static node_type *maximum(node_type *node)
1169 return maximum_impl(node);
1171 static const node_type *maximum(
const node_type *node)
1173 return maximum_impl(
const_cast<node_type *
>(node));
1175 static node_type *maximum_impl(node_type *node)
1177 QASSERT(3438, !is_nil(node));
1178 while ( !is_nil(right(node)) )
1190 static node_type *successor(node_type *node)
1192 return successor_impl(node);
1194 static const node_type *successor(
const node_type *node)
1196 return successor_impl(
const_cast<node_type *
>(node));
1198 static node_type *successor_impl(node_type *node)
1205 if ( !is_nil(right(node)) )
1208 return minimum(right(node));
1210 node_type *parent_node = parent(node);
1211 while ( !is_nil(parent_node) && node == right(parent_node) )
1216 parent_node = parent(parent_node);
1226 static node_type *predecessor(node_type *node)
1228 return predecessor_impl(node);
1230 static node_type *predecessor(
const node_type *node)
1232 return predecessor_impl(
const_cast<node_type *
>(node));
1234 static node_type *predecessor_impl(node_type *node)
1240 if ( !is_nil(left(node)) )
1243 return maximum(left(node));
1245 node_type *parent_node = parent(node);
1246 while ( !is_nil(parent_node) && node == left(parent_node) )
1251 parent_node = parent(parent_node);
1256 static Color node_color(
const node_type *node)
noexcept
1260 static Color left_color(
const node_type *node)
noexcept
1262 return is_nil(node) ?
Color::Black : node_color(left(node));
1264 static Color right_color(
const node_type *node)
noexcept
1266 return is_nil(node) ?
Color::Black : node_color(right(node));
1268 static node_type *prev_including_header(node_type *node)
1270 return is_nil(node) ? right(node) : predecessor(node);
1272 static const node_type *prev_including_header(
const node_type *node)
1274 return is_nil(node) ? right(node) : predecessor(node);
1280 static void destroy_value(node_type *node)
noexcept
1282 if ( !is_nil(node) )
1284 value_addr(node)->~Value();
1285 set_is_nil(node,
true);
1289 static Value *value_addr(node_type *node)
noexcept {
return reinterpret_cast<Value *
>(node->storage_); }
1290 static Value
const *value_addr(
const node_type *node)
noexcept {
return reinterpret_cast<Value
const *
>(node->storage_); }
1292 static Value *value_ptr(node_type *node)
noexcept {
return q_launder(value_addr(node)); }
1293 static Value
const *value_ptr(
const node_type *node)
noexcept {
return q_launder(value_addr(node)); }
1300 node_type *allocate_header()
1302 node_type *h = node_new();
1307 set_is_nil(h,
true);
1316 void init_header() noexcept
1318 set_parent(header_, header_);
1319 set_left(header_, header_);
1320 set_right(header_, header_);
1322 set_is_nil(header_,
true);
1325 void ensure_header()
1327 if ( header_ ==
nullptr )
1329 header_ = allocate_header();
1337 void clear_subtree(node_type *node)
noexcept
1341 if ( !is_nil(left(node)) )
1344 clear_subtree(left(node));
1346 if ( !is_nil(right(node)) )
1349 clear_subtree(right(node));
1351 destroy_value(node);
1359 node_type *clone_subtree(node_type
const *other_node, node_type *parent_node)
1361 if ( is_nil(other_node) )
1364 node_type *new_node = node_new();
1367 ::new (value_addr(new_node)) Value(*value_ptr(other_node));
1368 set_is_nil(new_node,
false);
1372 node_delete(new_node);
1376 set_color(new_node, color(other_node));
1377 set_parent(new_node, parent_node);
1378 set_left(new_node, header_);
1379 set_right(new_node, header_);
1384 set_left(new_node, clone_subtree(left(other_node), new_node));
1385 set_right(new_node, clone_subtree(right(other_node), new_node));
1389 clear_subtree(new_node);
1399 void clone_from(
qtree const &other)
1402 QASSERT(3439, !other.empty());
1406 node_type *new_root = clone_subtree(other.root(), header_);
1407 set_parent(header_, new_root);
1408 set_left(header_, minimum(new_root));
1409 set_right(header_, maximum(new_root));
1410 node_count_ = other.node_count_;
1432 node_type *root() noexcept
1434 if ( header_ ==
nullptr )
1436 return parent(header_);
1440 node_type
const *root() const noexcept
1442 if ( header_ ==
nullptr )
1444 return parent(header_);
1450 key_type const &node_key(node_type
const *node)
const
1452 return KeySelector {} (*value_ptr(node));
1486 node_type *right_node = right(node);
1487 QASSERT(3440, !is_nil(right_node));
1490 set_right(node, left(right_node));
1491 if ( !is_nil(left(right_node)) )
1492 set_parent(left(right_node), node);
1495 set_parent(right_node, parent(node));
1496 if ( parent(node) == header_ )
1497 set_parent(header_, right_node);
1498 else if ( node == left(parent(node)) )
1499 set_left(parent(node), right_node);
1501 set_right(parent(node), right_node);
1504 set_left(right_node, node);
1505 set_parent(node, right_node);
1537 void rotate_right(node_type *node)
noexcept
1539 node_type *left_node = left(node);
1540 QASSERT(3441, !is_nil(left_node));
1543 set_left(node, right(left_node));
1544 if ( !is_nil(right(left_node)) )
1545 set_parent(right(left_node), node);
1548 set_parent(left_node, parent(node));
1549 if ( parent(node) == header_ )
1550 set_parent(header_, left_node);
1551 else if ( node == right(parent(node)) )
1552 set_right(parent(node), left_node);
1554 set_left(parent(node), left_node);
1557 set_right(left_node, node);
1558 set_parent(node, left_node);
1569 node_type *find_node(K
const &key)
const
1571 node_type *node =
const_cast<node_type *
>(root());
1573 if ( node ==
nullptr )
1575 const auto cmp = comp();
1576 while ( !is_nil(node) )
1578 key_type const &node_k = node_key(node);
1579 if ( cmp(key, node_k) )
1583 else if ( cmp(node_k, key) )
1592 return const_cast<node_type *
>(header_);
1599 node_type *lower_bound_node(K
const &key)
const
1601 node_type *node =
const_cast<node_type *
>(root());
1603 if ( node ==
nullptr )
1605 node_type *
result =
const_cast<node_type *
>(header_);
1606 const auto cmp = comp();
1607 while ( !is_nil(node) )
1609 if ( !cmp(node_key(node), key) )
1626 node_type *upper_bound_node(K
const &key)
const
1628 node_type *node =
const_cast<node_type *
>(root());
1630 if ( node ==
nullptr )
1632 node_type *
result =
const_cast<node_type *
>(header_);
1633 const auto cmp = comp();
1634 while ( !is_nil(node) )
1636 if ( cmp(key, node_key(node)) )
1658 const auto cmp = comp();
1659 return !cmp(lhs, rhs) && !cmp(rhs, lhs);
1663 template <
class K,
class = enable_hetero_eq<K>>
1664 bool keys_equal(
key_type const &lhs, K
const &rhs)
const
1666 const auto cmp = comp();
1667 return !cmp(lhs, rhs) && !cmp(rhs, lhs);
1677 node_type *find_insert_position(K
const &key, node_type *&parent_node,
bool &go_left)
1679 node_type *node = root();
1680 parent_node = header_;
1682 const auto cmp = comp();
1683 while ( !is_nil(node) )
1686 key_type const &node_k = node_key(node);
1687 if ( cmp(key, node_k) )
1692 else if ( cmp(node_k, key) )
1709 node_type *find_insert_position(
1711 node_type *&parent_node,
1713 node_type *&existing)
1715 existing = find_insert_position(key, parent_node, go_left);
1725 bool try_hint_insert(
1728 node_type *&parent_node,
1730 node_type *&existing)
1732 node_type *hint_node = hint.node_;
1733 if ( hint_node ==
nullptr )
1736 parent_node = header_;
1742 parent_node = header_;
1746 const auto cmp = comp();
1747 if ( hint_node == header_ )
1749 node_type *max_node = right(header_);
1750 if ( is_nil(max_node) )
1752 parent_node = header_;
1755 key_type const &max_key = node_key(max_node);
1756 if ( cmp(max_key, key) )
1758 parent_node = max_node;
1762 if ( keys_equal(max_key, key) )
1764 existing = max_node;
1770 key_type const &hint_key = node_key(hint_node);
1771 if ( keys_equal(hint_key, key) )
1773 existing = hint_node;
1777 if ( cmp(key, hint_key) )
1779 node_type *prev = predecessor(hint_node);
1780 if ( prev == header_ || cmp(node_key(prev), key) )
1782 if ( is_nil(left(hint_node)) )
1784 parent_node = hint_node;
1788 if ( prev != header_ && is_nil(right(prev)) )
1798 node_type *next = successor(hint_node);
1799 if ( next == header_ || cmp(key, node_key(next)) )
1801 if ( is_nil(right(hint_node)) )
1803 parent_node = hint_node;
1807 if ( next != header_ && is_nil(left(next)) )
1817 template <
class Builder>
1824 node_type *new_node = node_new();
1827 builder(value_addr(new_node));
1828 set_is_nil(new_node,
false);
1832 node_delete(new_node);
1835 set_parent(new_node, parent_node);
1836 set_left(new_node, header_);
1837 set_right(new_node, header_);
1840 if ( parent_node == header_ )
1842 set_parent(header_, new_node);
1843 set_left(header_, new_node);
1844 set_right(header_, new_node);
1846 set_parent(new_node, header_);
1852 set_left(parent_node, new_node);
1854 if ( parent_node == left(header_) )
1855 set_left(header_, new_node);
1859 set_right(parent_node, new_node);
1861 if ( parent_node == right(header_) )
1862 set_right(header_, new_node);
1864 insert_fixup(new_node);
1868 return {
iterator(new_node),
true };
1885 void insert_fixup(node_type *node)
noexcept
1887 while ( !is_nil(parent(node)) && color(parent(node)) ==
Color::Red )
1889 node_type *parent_node = parent(node);
1890 node_type *grand = parent(parent_node);
1895 if ( parent_node == left(grand) )
1897 node_type *uncle = right(grand);
1940 if ( node == right(parent_node) )
1944 parent_node = parent(node);
1945 grand = parent(parent_node);
1966 rotate_right(grand);
1973 node_type *uncle = left(grand);
2016 if ( node == left(parent_node) )
2020 parent_node = parent(node);
2021 grand = parent(parent_node);
2047 if ( !is_nil(parent(header_)) )
2051 template <
class Builder>
2057 if ( header_ ==
nullptr || node_count_ == 0 )
2058 return emplace_into_empty_tree(std::forward<Builder>(builder));
2060 node_type *parent_node = header_;
2061 bool go_left =
true;
2062 node_type *existing = this->find_insert_position(key, parent_node, go_left);
2063 if ( existing !=
nullptr )
2064 return {
iterator(existing),
false };
2065 return emplace_at(parent_node, go_left, std::forward<Builder>(builder));
2069 template <
class K,
class Builder,
class = std::enable_if_t<cmp_b
idir_v<Compare, key_type, K>>>
2072 if ( header_ ==
nullptr || node_count_ == 0 )
2073 return emplace_into_empty_tree(std::forward<Builder>(builder));
2075 node_type *parent_node = header_;
2076 bool go_left =
true;
2077 node_type *existing = this->find_insert_position(key, parent_node, go_left);
2078 if ( existing !=
nullptr )
2079 return {
iterator(existing),
false };
2080 return emplace_at(parent_node, go_left, std::forward<Builder>(builder));
2083 template <
class Builder>
2090 if ( header_ ==
nullptr || node_count_ == 0 )
2091 return emplace_into_empty_tree(std::forward<Builder>(builder));
2093 node_type *parent_node = header_;
2094 bool go_left =
true;
2095 node_type *existing =
nullptr;
2096 if ( hint.node_ !=
nullptr
2097 && try_hint_insert(key, hint, parent_node, go_left, existing) )
2099 if ( existing !=
nullptr )
2100 return {
iterator(existing),
false };
2101 return emplace_at(parent_node, go_left, std::forward<Builder>(builder));
2103 return lazy_emplace_impl(key, std::forward<Builder>(builder));
2106 template <
class K,
class Builder,
class = std::enable_if_t<cmp_b
idir_v<Compare, key_type, K>>>
2110 if ( header_ ==
nullptr || node_count_ == 0 )
2111 return emplace_into_empty_tree(std::forward<Builder>(builder));
2113 node_type *parent_node = header_;
2114 bool go_left =
true;
2115 node_type *existing =
nullptr;
2116 if ( hint.node_ !=
nullptr
2117 && try_hint_insert(key, hint, parent_node, go_left, existing) )
2119 if ( existing !=
nullptr )
2120 return {
iterator(existing),
false };
2121 return emplace_at(parent_node, go_left, std::forward<Builder>(builder));
2123 return lazy_emplace_impl(key, std::forward<Builder>(builder));
2126 template <
class Builder>
2130 node_type *parent_node = header_;
2131 bool go_left =
true;
2132 return emplace_at(parent_node, go_left, std::forward<Builder>(builder));
2151 void transplant(node_type *u, node_type *v)
noexcept
2153 if ( parent(u) == header_ )
2154 set_parent(header_, is_nil(v) ? header_ : v);
2155 else if ( u == left(parent(u)) )
2156 set_left(parent(u), v);
2158 set_right(parent(u), v);
2161 set_parent(v, parent(u));
2172 void erase_node(node_type *node)
2177 if ( node ==
nullptr )
2179 node_type *y = node;
2180 node_type *x = header_;
2181 node_type *x_parent = header_;
2182 Color original = color(y);
2194 if ( is_nil(left(node)) )
2197 x_parent = parent(node);
2198 transplant(node, right(node));
2210 else if ( is_nil(right(node)) )
2213 x_parent = parent(node);
2214 transplant(node, left(node));
2237 y = minimum(right(node));
2238 original = color(y);
2241 if ( parent(y) == node )
2259 transplant(y, right(y));
2262 set_right(y, right(node));
2263 if ( !is_nil(right(y)) )
2264 set_parent(right(y), y);
2266 x_parent = parent(y);
2277 transplant(node, y);
2280 set_left(y, left(node));
2281 if ( !is_nil(left(y)) )
2282 set_parent(left(y), y);
2285 set_color(y, color(node));
2289 destroy_value(node);
2295 erase_fixup(x, x_parent);
2298 if ( node_count_ == 0 )
2302 set_left(header_, minimum(parent(header_)));
2303 set_right(header_, maximum(parent(header_)));
2318 void erase_fixup(node_type *x, node_type *parent_node)
noexcept
2320 while ( x != parent(header_) && node_color(x) ==
Color::Black )
2324 if ( x == left(parent_node) )
2326 node_type *w = right(parent_node);
2346 w = right(parent_node);
2349 Color w_left = left_color(w);
2350 Color w_right = right_color(w);
2365 parent_node = parent(parent_node);
2389 if ( !is_nil(left(w)) )
2395 w = right(parent_node);
2414 set_color(w, color(parent_node));
2417 if ( !is_nil(right(w)) )
2423 x = parent(header_);
2424 parent_node = header_;
2431 node_type *w = left(parent_node);
2450 rotate_right(parent_node);
2451 w = left(parent_node);
2454 Color w_left = left_color(w);
2455 Color w_right = right_color(w);
2470 parent_node = parent(parent_node);
2494 if ( !is_nil(right(w)) )
2500 w = left(parent_node);
2519 set_color(w, color(parent_node));
2522 if ( !is_nil(left(w)) )
2525 rotate_right(parent_node);
2528 x = parent(header_);
2529 parent_node = header_;
2538 if ( !is_nil(parent(header_)) )
2548 node_type *node_new()
2550 node_alloc a = make_node_alloc();
2552 node_type *mem = node_traits::allocate(a, 1);
2555 return ::new (mem) node_type();
2559 node_traits::deallocate(a, mem, 1);
2566 void node_delete(node_type *p)
noexcept
2571 node_alloc a = make_node_alloc();
2572 node_traits::deallocate(a, p, 1);
2604 node_type *header_ =
nullptr;