|
@@ -1,6 +1,7 @@
|
|
|
#ifndef __GBLIBCPP_BITS_RBTREE__
|
|
|
#define __GBLIBCPP_BITS_RBTREE__
|
|
|
|
|
|
+#include <cstddef>
|
|
|
#include <functional>
|
|
|
#include <utility>
|
|
|
#include <memory>
|
|
@@ -269,6 +270,15 @@ private:
|
|
|
node_alloc_traits::deallocate(alloc, nd, 1);
|
|
|
}
|
|
|
|
|
|
+ constexpr void do_insertion(node* parent,
|
|
|
+ node*& child_inserted, node* nd)
|
|
|
+ {
|
|
|
+ nd->parent = parent;
|
|
|
+ child_inserted = nd;
|
|
|
+ this->balance(nd);
|
|
|
+ ++_size;
|
|
|
+ }
|
|
|
+
|
|
|
public:
|
|
|
constexpr iterator end(void) noexcept
|
|
|
{ return iterator(nullptr); }
|
|
@@ -583,39 +593,56 @@ public:
|
|
|
return const_iterator { nextpos };
|
|
|
}
|
|
|
|
|
|
+ template <typename U>
|
|
|
+ constexpr iterator lower_bound(U&& val) const
|
|
|
+ {
|
|
|
+ node* cur = root;
|
|
|
+ node* result = nullptr;
|
|
|
+
|
|
|
+ while (cur) {
|
|
|
+ if (!comp(cur->value, val)) {
|
|
|
+ result = cur;
|
|
|
+ cur = cur->left;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ cur = cur->right;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return iterator { result };
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename U>
|
|
|
+ constexpr iterator upper_bound(U&& val) const
|
|
|
+ {
|
|
|
+ iterator iter = lower_bound(std::forward<U>(val));
|
|
|
+ if (iter && !comp(*iter, val) && !comp(val, *iter))
|
|
|
+ return ++iter;
|
|
|
+ return iter;
|
|
|
+ }
|
|
|
+
|
|
|
// value in nd MUST NOT exist in the rbtree,
|
|
|
// that is, if a < b, then a > b
|
|
|
constexpr void insert(node* nd)
|
|
|
{
|
|
|
node* cur = root;
|
|
|
|
|
|
- while (cur) [[likely]] {
|
|
|
+ while (cur) {
|
|
|
if (comp(nd->value, cur->value)) {
|
|
|
if (!cur->left) {
|
|
|
- nd->parent = cur;
|
|
|
- cur->left = nd;
|
|
|
- this->balance(nd);
|
|
|
- ++_size;
|
|
|
+ do_insertion(cur, cur->left, nd);
|
|
|
return;
|
|
|
- } else {
|
|
|
- cur = cur->left;
|
|
|
}
|
|
|
+ cur = cur->left;
|
|
|
} else {
|
|
|
if (!cur->right) {
|
|
|
- nd->parent = cur;
|
|
|
- cur->right = nd;
|
|
|
- this->balance(nd);
|
|
|
- ++_size;
|
|
|
+ do_insertion(cur, cur->right, nd);
|
|
|
return;
|
|
|
- } else {
|
|
|
- cur = cur->right;
|
|
|
}
|
|
|
+ cur = cur->right;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- root = nd;
|
|
|
- root->toblack();
|
|
|
- ++_size;
|
|
|
+ do_insertion(cur, root, nd);
|
|
|
}
|
|
|
|
|
|
template <typename U>
|