Yggdrasill  0.2
rbtree.hpp
1 #ifndef YGG_RBTREE_HPP
2 #define YGG_RBTREE_HPP
3 
4 #include "bst.hpp"
5 #include "options.hpp"
6 #include "size_holder.hpp"
7 #include "tree_iterator.hpp"
8 
9 #include <cassert>
10 #include <cstddef>
11 #include <set>
12 #include <type_traits>
13 
14 // Only for debugging purposes
15 #include <fstream>
16 #include <vector>
17 
18 namespace ygg {
19 namespace rbtree_internal {
21 
22 enum class Color : unsigned char
23 {
24  BLACK = 0,
25  RED = 1
26 };
27 
28 template <class Node, bool compress_color>
29 class ColorParentStorage;
30 
31 template <class Node>
32 class ColorParentStorage<Node, true> {
33 public:
34  void set_color(Color new_color) noexcept;
35  void make_black() noexcept;
36  void make_red() noexcept;
37 
38  Color get_color() const noexcept;
39  void set_parent(Node * new_parent) noexcept;
40  Node * get_parent() const noexcept;
41 
42  void swap_parent_with(ColorParentStorage<Node, true> & other) noexcept;
43  void swap_color_with(ColorParentStorage<Node, true> & other) noexcept;
44 
45  static constexpr bool parent_reference = false;
46 
47 private:
48  Node * parent;
49 };
50 
51 template <class Node>
52 class ColorParentStorage<Node, false> {
53 public:
54  void set_color(Color new_color) noexcept;
55  void make_black() noexcept;
56  void make_red() noexcept;
57 
58  Color get_color() const noexcept;
59  void set_parent(Node * new_parent) noexcept;
60  Node *& get_parent() noexcept;
61  Node * get_parent() const noexcept;
62 
63  void swap_parent_with(ColorParentStorage<Node, false> & other) noexcept;
64  void swap_color_with(ColorParentStorage<Node, false> & other) noexcept;
65 
66  static constexpr bool parent_reference = true;
67 
68 private:
69  Node * parent = nullptr;
70  Color color;
71 };
72 
74 } // namespace rbtree_internal
75 
91 template <class Node, class Options = DefaultOptions, class Tag = int>
93  : public bst::BSTNodeBase<
94  Node, Tag,
95  rbtree_internal::ColorParentStorage<Node, Options::compress_color>> {
96 public:
97  // TODO namespacing!
98 
99  void set_color(rbtree_internal::Color new_color) noexcept;
100  void make_black() noexcept;
101  void make_red() noexcept;
102  rbtree_internal::Color get_color() const noexcept;
103 
104  void swap_parent_with(Node * other) noexcept;
105  void swap_color_with(Node * other) noexcept;
106 
107 private:
108  using ActiveOptions = Options;
109  friend class rbtree_internal::ColorParentStorage<Node,
110  Options::compress_color>;
111 };
112 
121 public:
122  // TODO document
123  template <class Node, class Tree>
124  static void
125  leaf_inserted(Node & node, Tree & t) noexcept
126  {
127  (void)node;
128  (void)t;
129  }
130 
131  template <class Node, class Tree>
132  static void
133  rotated_left(Node & node, Tree & t) noexcept
134  {
135  (void)node;
136  (void)t;
137  }
138 
139  template <class Node, class Tree>
140  static void
141  rotated_right(Node & node, Tree & t) noexcept
142  {
143  (void)node;
144  (void)t;
145  }
146 
147  template <class Node, class Tree>
148  static void
149  delete_leaf(Node & node, Tree & t) noexcept
150  {
151  (void)node;
152  (void)t;
153  }
154 
155  template <class Node, class Tree>
156  static void
157  deleted_below(Node & node, Tree & t) noexcept
158  {
159  (void)node;
160  (void)t;
161  }
162 
163  template <class Node, class Tree>
164  static void
165  swapped(Node & old_ancestor, Node & old_descendant, Tree & t) noexcept
166  {
167  (void)old_ancestor;
168  (void)old_descendant;
169  (void)t;
170  }
171 };
172 
192 template <class Node, class NodeTraits, class Options = DefaultOptions,
193  class Tag = int, class Compare = ygg::utilities::flexible_less>
194 class RBTree
195  : public bst::BinarySearchTree<
196  Node, Options, Tag, Compare,
197  rbtree_internal::ColorParentStorage<Node, Options::compress_color>>
198 
199 {
200 public:
202  // Node Base
204  using TB = bst::BinarySearchTree<
205  Node, Options, Tag, Compare,
206  rbtree_internal::ColorParentStorage<Node, Options::compress_color>>;
207  static_assert(std::is_base_of<NB, Node>::value,
208  "Node class not properly derived from RBTreeNodeBase");
209 
213  RBTree() noexcept;
214 
223  RBTree(MyClass && other) noexcept;
224 
225  /*
226  * Pull in classes from base tree
227  */
228  template <bool reverse>
229  using iterator = typename TB::template iterator<reverse>;
230  template <bool reverse>
231  using const_iterator = typename TB::template const_iterator<reverse>;
232 
247  void insert(Node & node) CMP_NOEXCEPT(node);
248  void insert(Node & node, Node & hint) CMP_NOEXCEPT(node);
249  void insert(Node & node, iterator<false> hint) CMP_NOEXCEPT(node);
250 
251  // TODO document hinted inserts
252  // TODO should order be preserved on hints?
253 
261  void remove(Node & node) CMP_NOEXCEPT(node);
262 
284  template <class Comparable>
285  utilities::select_type_t<size_t, Node *, Options::stl_erase>
286  erase(const Comparable & c) CMP_NOEXCEPT(c);
287 
302  template <bool reverse>
303  utilities::select_type_t<const iterator<reverse>, Node *, Options::stl_erase>
304  erase(const iterator<reverse> & it) CMP_NOEXCEPT(*it);
305 
306  // Mainly debugging methods
308  void dbg_verify() const;
309  bool verify_integrity() const;
311 
312 protected:
313  using Path = std::vector<Node *>;
314 
315  void remove_to_leaf(Node & node) CMP_NOEXCEPT(node);
316  void fixup_after_delete(Node * parent, bool deleted_left) noexcept;
317 
318  void insert_leaf_base(Node & node, Node * start) CMP_NOEXCEPT(node);
319 
320  void fixup_after_insert(Node * node) noexcept;
321  void rotate_left(Node * parent) noexcept;
322  void rotate_right(Node * parent) noexcept;
323 
324  void swap_nodes(Node * n1, Node * n2, bool swap_colors = true) noexcept;
325  void replace_node(Node * to_be_replaced, Node * replace_with) noexcept;
326  void swap_unrelated_nodes(Node * n1, Node * n2) noexcept;
327  void swap_neighbors(Node * parent, Node * child) noexcept;
328 
329  void verify_black_root() const;
330  void verify_black_paths(const Node * node, unsigned int * path_length) const;
331  void verify_red_black(const Node * node) const;
332 };
333 
334 } // namespace ygg
335 
336 #ifndef YGG_RBTREE_CPP
337 #include "rbtree.cpp"
338 #endif
339 
340 #endif // YGG_RBTREE_HPP
Definition: bst.hpp:123
Helper base class for the NodeTraits you need to implement.
Definition: rbtree.hpp:120
Base class (template) to supply your node class with metainformation.
Definition: rbtree.hpp:92
The Red-Black Tree.
Definition: rbtree.hpp:194
Definition: rbtree.hpp:18