2 * Copyright (c) 2018 Jaroslav Jindrak
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifndef LIBCPP_BITS_ADT_RBTREE
30 #define LIBCPP_BITS_ADT_RBTREE
32 #include <__bits/adt/key_extractors.hpp>
33 #include <__bits/adt/rbtree_iterators.hpp>
34 #include <__bits/adt/rbtree_node.hpp>
35 #include <__bits/adt/rbtree_policies.hpp>
40 class Value
, class Key
, class KeyExtractor
,
41 class KeyComp
, class Alloc
, class Size
,
42 class Iterator
, class ConstIterator
,
43 class Policy
, class Node
48 using value_type
= Value
;
50 using size_type
= Size
;
51 using allocator_type
= Alloc
;
52 using key_compare
= KeyComp
;
53 using key_extract
= KeyExtractor
;
55 using iterator
= Iterator
;
56 using const_iterator
= ConstIterator
;
58 using reverse_iterator
= std::reverse_iterator
<iterator
>;
59 using const_reverse_iterator
= std::reverse_iterator
<const_iterator
>;
61 using node_type
= Node
;
63 rbtree(const key_compare
& kcmp
= key_compare
{})
64 : root_
{nullptr}, size_
{}, key_compare_
{},
68 rbtree(const rbtree
& other
)
69 : rbtree
{other
.key_compare_
}
71 for (const auto& x
: other
)
75 rbtree(rbtree
&& other
)
76 : root_
{other
.root_
}, size_
{other
.size_
},
77 key_compare_
{move(other
.key_compare_
)},
78 key_extractor_
{move(other
.key_extractor_
)}
80 other
.root_
= nullptr;
81 other
.size_
= size_type
{};
84 rbtree
& operator=(const rbtree
& other
)
92 rbtree
& operator=(rbtree
&& other
)
94 rbtree tmp
{move(other
)};
100 bool empty() const noexcept
105 size_type
size() const noexcept
110 size_type
max_size(allocator_type
& alloc
)
112 return allocator_traits
<allocator_type
>::max_size(alloc
);
117 return iterator
{find_smallest_(), false};
120 const_iterator
begin() const
128 * In case we have lists of nodes
129 * we need to get the actual end
130 * from the largest node.
132 auto res
= find_largest_();
134 return iterator
{res
->get_end(), true};
136 return iterator
{res
, true};
139 const_iterator
end() const
144 reverse_iterator
rbegin()
146 return make_reverse_iterator(end());
149 const_reverse_iterator
rbegin() const
151 return make_reverse_iterator(cend());
154 reverse_iterator
rend()
156 return make_reverse_iterator(begin());
159 const_reverse_iterator
rend() const
161 return make_reverse_iterator(cbegin());
164 const_iterator
cbegin() const
166 return const_iterator
{find_smallest_(), false};
169 const_iterator
cend() const
171 auto res
= find_largest_();
173 return const_iterator
{res
->get_end(), true};
175 return const_iterator
{res
, true};
178 const_reverse_iterator
crbegin() const
180 return make_reverse_iterator(cend());
183 const_reverse_iterator
crend() const
185 return make_reverse_iterator(cbegin());
188 template<class... Args
>
189 auto emplace(Args
&&... args
)
191 return Policy::emplace(*this, forward
<Args
>(args
)...);
194 auto insert(const value_type
& val
)
196 return Policy::insert(*this, val
);
199 auto insert(value_type
&& val
)
201 return Policy::insert(*this, forward
<value_type
>(val
));
204 size_type
erase(const key_type
& key
)
206 return Policy::erase(*this, key
);
209 iterator
erase(const_iterator it
)
214 auto node
= const_cast<node_type
*>(it
.node());
216 node
= delete_node(node
);
218 return iterator
{find_largest_(), true};
220 return iterator
{const_cast<node_type
*>(node
), false};
223 void clear() noexcept
233 void swap(rbtree
& other
)
234 noexcept(allocator_traits
<allocator_type
>::is_always_equal::value
&&
235 noexcept(std::swap(declval
<KeyComp
&>(), declval
<KeyComp
&>())))
237 std::swap(root_
, other
.root_
);
238 std::swap(size_
, other
.size_
);
239 std::swap(key_compare_
, other
.key_compare_
);
240 std::swap(key_extractor_
, other
.key_extractor_
);
243 key_compare
key_comp() const
248 iterator
find(const key_type
& key
)
250 auto node
= find_(key
);
252 return iterator
{node
, false};
257 const_iterator
find(const key_type
& key
) const
259 auto node
= find_(key
);
261 return const_iterator
{node
, false};
266 size_type
count(const key_type
& key
) const
268 return Policy::count(*this, key
);
271 iterator
upper_bound(const key_type
& key
)
273 return Policy::upper_bound(*this, key
);
276 const_iterator
upper_bound(const key_type
& key
) const
278 return Policy::upper_bound_const(*this, key
);
281 iterator
lower_bound(const key_type
& key
)
283 return Policy::lower_bound(*this, key
);
286 const_iterator
lower_bound(const key_type
& key
) const
288 return Policy::lower_bound_const(*this, key
);
291 pair
<iterator
, iterator
> equal_range(const key_type
& key
)
293 return Policy::equal_range(*this, key
);
296 pair
<const_iterator
, const_iterator
> equal_range(const key_type
& key
) const
298 return Policy::equal_range_const(*this, key
);
301 bool is_eq_to(const rbtree
& other
) const
303 if (size_
!= other
.size())
307 auto it2
= other
.begin();
309 // TODO: this doesn't compare values :/
310 while (keys_equal(*it1
++, *it2
++))
313 return (it1
== end()) && (it2
== other
.end());
316 const key_type
& get_key(const value_type
& val
) const
318 return key_extractor_(val
);
321 bool keys_comp(const key_type
& key
, const value_type
& val
) const
323 return key_compare_(key
, key_extractor_(val
));
326 bool keys_equal(const key_type
& k1
, const key_type
& k2
) const
328 return !key_compare_(k1
, k2
) && !key_compare_(k2
, k1
);
331 node_type
* find_parent_for_insertion(const key_type
& key
) const
333 auto current
= root_
;
334 auto parent
= current
;
339 if (key_compare_(key
, key_extractor_(current
->value
)))
340 current
= current
->left();
341 else if (key_compare_(key_extractor_(current
->value
), key
))
342 current
= current
->right();
350 node_type
* delete_node(const node_type
* n
)
352 auto node
= const_cast<node_type
*>(n
);
358 auto succ
= node
->successor();
359 if (auto tmp
= node
->get_node_for_deletion(); tmp
!= nullptr)
362 * This will kick in multi containers,
363 * we popped one node from a list of nodes
364 * with equivalent keys and we can delete it
365 * and return the successor which was the next
370 update_root_(succ
); // Incase the first in list was root.
373 else if (node
== root_
)
374 { // Only executed if root_ is unique.
381 if (node
->left() && node
->right())
384 if (succ
&& !succ
->parent())
387 // Node now has at most one child.
388 // Also: If succ was nullptr, the swap
389 // didn't do anything and we can
390 // safely delete node.
391 return delete_node(node
);
394 auto child
= node
->right() ? node
->right() : node
->left();
397 // Simply remove the node.
398 // TODO: repair here too?
404 // Replace with the child.
405 child
->parent(node
->parent());
406 if (node
->is_left_child())
407 child
->parent()->left(child
);
408 else if (node
->is_right_child())
409 child
->parent()->right(child
);
410 node
->parent(nullptr);
412 node
->right(nullptr);
415 repair_after_erase_(node
, child
);
424 void insert_node(node_type
* node
, node_type
* parent
)
426 Policy::insert(*this, node
, parent
);
432 key_compare key_compare_
;
433 key_extract key_extractor_
;
435 node_type
* find_(const key_type
& key
) const
437 auto current
= root_
;
438 while (current
!= nullptr)
440 if (key_compare_(key
, key_extractor_(current
->value
)))
441 current
= current
->left();
442 else if (key_compare_(key_extractor_(current
->value
), key
))
443 current
= current
->right();
451 node_type
* find_smallest_() const
454 return root_
->find_smallest();
459 node_type
* find_largest_() const
462 return root_
->find_largest();
467 void update_root_(const node_type
* node
)
472 root_
= const_cast<node_type
*>(node
);
473 while (root_
->parent())
474 root_
= root_
->parent();
477 void repair_after_insert_(const node_type
* node
)
482 void repair_after_erase_(const node_type
* node
, const node_type
* child
)