omega_h
Reliable mesh adaptation
Omega_h_rbtree.hpp
1 /* Dan Ibanez took the code from HP/SGI and modified it to:
2  * 1. be user-space instead of standard-namespace
3  * 2. Not have Unicode foreign language comments
4  * 3. Not have allocators (just uses new and delete)
5  */
6 
7 /*
8  *
9  * Copyright (c) 1996,1997
10  * Silicon Graphics Computer Systems, Inc.
11  *
12  * Permission to use, copy, modify, distribute and sell this software
13  * and its documentation for any purpose is hereby granted without fee,
14  * provided that the above copyright notice appear in all copies and
15  * that both that copyright notice and this permission notice appear
16  * in supporting documentation. Silicon Graphics makes no
17  * representations about the suitability of this software for any
18  * purpose. It is provided "as is" without express or implied warranty.
19  *
20  *
21  * Copyright (c) 1994
22  * Hewlett-Packard Company
23  *
24  * Permission to use, copy, modify, distribute and sell this software
25  * and its documentation for any purpose is hereby granted without fee,
26  * provided that the above copyright notice appear in all copies and
27  * that both that copyright notice and this permission notice appear
28  * in supporting documentation. Hewlett-Packard Company makes no
29  * representations about the suitability of this software for any
30  * purpose. It is provided "as is" without express or implied warranty.
31  *
32  *
33  */
34 
35 #ifndef OMEGA_H_RB_TREE_HPP
36 #define OMEGA_H_RB_TREE_HPP
37 
38 /*
39 
40 Red-black tree class, designed for use in implementing STL
41 associative containers (set, multiset, map, and multimap). The
42 insertion and deletion algorithms are based on those in Cormen,
43 Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990),
44 except that
45 
46 (1) the header cell is maintained with links not only to the root
47 but also to the leftmost node of the tree, to enable constant time
48 begin(), and to the rightmost node of the tree, to enable linear time
49 performance when used with the generic set algorithms (set_union,
50 etc.);
51 
52 (2) when a node being deleted has two children its successor node is
53 relinked into its place, rather than copied, so that the only
54 iterators invalidated are those referring to the deleted node.
55 
56 */
57 
58 #include <cstddef>
59 #include <cstdlib>
60 #include <functional>
61 #include <iterator>
62 #include <utility>
63 
64 namespace Omega_h {
65 
66 namespace nonstd {
67 template <typename T>
68 void swap(T& a, T& b) {
69  T c = a;
70  a = b;
71  b = c;
72 }
73 } // namespace nonstd
74 
75 typedef bool Rb_tree_Color_type;
76 static constexpr Rb_tree_Color_type S_rb_tree_red = false;
77 static constexpr Rb_tree_Color_type S_rb_tree_black = true;
78 
80  typedef Rb_tree_Color_type Color_type;
81  typedef Rb_tree_node_base* Base_ptr;
82 
83  Color_type M_color;
84  Base_ptr M_parent;
85  Base_ptr M_left;
86  Base_ptr M_right;
87 
88  static Base_ptr S_minimum(Base_ptr x) {
89  while (x->M_left != nullptr) x = x->M_left;
90  return x;
91  }
92 
93  static Base_ptr S_maximum(Base_ptr x) {
94  while (x->M_right != nullptr) x = x->M_right;
95  return x;
96  }
97 };
98 
99 template <class Value>
102  Value M_value_field;
103 };
104 
107  typedef std::ptrdiff_t difference_type;
108  using iterator_category = std::bidirectional_iterator_tag;
109  Base_ptr M_node;
110 
111  void M_increment() {
112  if (M_node->M_right != nullptr) {
113  M_node = M_node->M_right;
114  while (M_node->M_left != nullptr) M_node = M_node->M_left;
115  } else {
116  Base_ptr y = M_node->M_parent;
117  while (M_node == y->M_right) {
118  M_node = y;
119  y = y->M_parent;
120  }
121  if (M_node->M_right != y) M_node = y;
122  }
123  }
124 
125  void M_decrement() {
126  if (M_node->M_color == S_rb_tree_red &&
127  M_node->M_parent->M_parent == M_node)
128  M_node = M_node->M_right;
129  else if (M_node->M_left != nullptr) {
130  Base_ptr y = M_node->M_left;
131  while (y->M_right != nullptr) y = y->M_right;
132  M_node = y;
133  } else {
134  Base_ptr y = M_node->M_parent;
135  while (M_node == y->M_left) {
136  M_node = y;
137  y = y->M_parent;
138  }
139  M_node = y;
140  }
141  }
142 };
143 
144 template <class Value, class Ref, class Ptr>
146  typedef Value value_type;
147  typedef Ref reference;
148  typedef Ptr pointer;
153 
154  Rb_tree_iterator() {}
155  Rb_tree_iterator(Link_type x) { M_node = x; }
156  Rb_tree_iterator(const Self&) = default;
157  Rb_tree_iterator& operator=(Rb_tree_iterator const&) = default;
158 
159  reference operator*() const { return Link_type(M_node)->M_value_field; }
160  pointer operator->() const { return &(operator*()); }
161 
162  Self& operator++() {
163  M_increment();
164  return *this;
165  }
166  Self operator++(int) {
167  Self tmp = *this;
168  M_increment();
169  return tmp;
170  }
171 
172  Self& operator--() {
173  M_decrement();
174  return *this;
175  }
176  Self operator--(int) {
177  Self tmp = *this;
178  M_decrement();
179  return tmp;
180  }
181 };
182 
183 inline bool operator==(
184  const Rb_tree_base_iterator& x, const Rb_tree_base_iterator& y) {
185  return x.M_node == y.M_node;
186 }
187 
188 inline bool operator!=(
189  const Rb_tree_base_iterator& x, const Rb_tree_base_iterator& y) {
190  return x.M_node != y.M_node;
191 }
192 
193 inline void Rb_tree_rotate_left(
194  Rb_tree_node_base* x, Rb_tree_node_base*& root) {
195  Rb_tree_node_base* y = x->M_right;
196  x->M_right = y->M_left;
197  if (y->M_left != nullptr) y->M_left->M_parent = x;
198  y->M_parent = x->M_parent;
199 
200  if (x == root)
201  root = y;
202  else if (x == x->M_parent->M_left)
203  x->M_parent->M_left = y;
204  else
205  x->M_parent->M_right = y;
206  y->M_left = x;
207  x->M_parent = y;
208 }
209 
210 inline void Rb_tree_rotate_right(
211  Rb_tree_node_base* x, Rb_tree_node_base*& root) {
212  Rb_tree_node_base* y = x->M_left;
213  x->M_left = y->M_right;
214  if (y->M_right != nullptr) y->M_right->M_parent = x;
215  y->M_parent = x->M_parent;
216 
217  if (x == root)
218  root = y;
219  else if (x == x->M_parent->M_right)
220  x->M_parent->M_right = y;
221  else
222  x->M_parent->M_left = y;
223  y->M_right = x;
224  x->M_parent = y;
225 }
226 
227 inline void Rb_tree_rebalance(Rb_tree_node_base* x, Rb_tree_node_base*& root) {
228  x->M_color = S_rb_tree_red;
229  while (x != root && x->M_parent->M_color == S_rb_tree_red) {
230  if (x->M_parent == x->M_parent->M_parent->M_left) {
231  Rb_tree_node_base* y = x->M_parent->M_parent->M_right;
232  if (y && y->M_color == S_rb_tree_red) {
233  x->M_parent->M_color = S_rb_tree_black;
234  y->M_color = S_rb_tree_black;
235  x->M_parent->M_parent->M_color = S_rb_tree_red;
236  x = x->M_parent->M_parent;
237  } else {
238  if (x == x->M_parent->M_right) {
239  x = x->M_parent;
240  Rb_tree_rotate_left(x, root);
241  }
242  x->M_parent->M_color = S_rb_tree_black;
243  x->M_parent->M_parent->M_color = S_rb_tree_red;
244  Rb_tree_rotate_right(x->M_parent->M_parent, root);
245  }
246  } else {
247  Rb_tree_node_base* y = x->M_parent->M_parent->M_left;
248  if (y && y->M_color == S_rb_tree_red) {
249  x->M_parent->M_color = S_rb_tree_black;
250  y->M_color = S_rb_tree_black;
251  x->M_parent->M_parent->M_color = S_rb_tree_red;
252  x = x->M_parent->M_parent;
253  } else {
254  if (x == x->M_parent->M_left) {
255  x = x->M_parent;
256  Rb_tree_rotate_right(x, root);
257  }
258  x->M_parent->M_color = S_rb_tree_black;
259  x->M_parent->M_parent->M_color = S_rb_tree_red;
260  Rb_tree_rotate_left(x->M_parent->M_parent, root);
261  }
262  }
263  }
264  root->M_color = S_rb_tree_black;
265 }
266 
267 inline Rb_tree_node_base* Rb_tree_rebalance_for_erase(Rb_tree_node_base* z,
268  Rb_tree_node_base*& root, Rb_tree_node_base*& leftmost,
269  Rb_tree_node_base*& rightmost) {
270  Rb_tree_node_base* y = z;
271  Rb_tree_node_base* x = nullptr;
272  Rb_tree_node_base* x_parent = nullptr;
273  if (y->M_left == nullptr) // z has at most one non-null child. y == z.
274  x = y->M_right; // x might be null.
275  else if (y->M_right == nullptr) // z has exactly one non-null child. y == z.
276  x = y->M_left; // x is not null.
277  else { // z has two non-null children. Set y to
278  y = y->M_right; // z's successor. x might be null.
279  while (y->M_left != nullptr) y = y->M_left;
280  x = y->M_right;
281  }
282  if (y != z) { // relink y in place of z. y is z's successor
283  z->M_left->M_parent = y;
284  y->M_left = z->M_left;
285  if (y != z->M_right) {
286  x_parent = y->M_parent;
287  if (x) x->M_parent = y->M_parent;
288  y->M_parent->M_left = x; // y must be a child of M_left
289  y->M_right = z->M_right;
290  z->M_right->M_parent = y;
291  } else
292  x_parent = y;
293  if (root == z)
294  root = y;
295  else if (z->M_parent->M_left == z)
296  z->M_parent->M_left = y;
297  else
298  z->M_parent->M_right = y;
299  y->M_parent = z->M_parent;
300  nonstd::swap(y->M_color, z->M_color);
301  y = z;
302  // y now points to node to be actually deleted
303  } else { // y == z
304  x_parent = y->M_parent;
305  if (x) x->M_parent = y->M_parent;
306  if (root == z)
307  root = x;
308  else if (z->M_parent->M_left == z)
309  z->M_parent->M_left = x;
310  else
311  z->M_parent->M_right = x;
312  if (leftmost == z) {
313  if (z->M_right == nullptr) { // z->M_left must be null also
314  leftmost = z->M_parent;
315  // makes leftmost == M_header if z == root
316  } else {
317  leftmost = Rb_tree_node_base::S_minimum(x);
318  }
319  }
320  if (rightmost == z) {
321  if (z->M_left == nullptr) { // z->M_right must be null also
322  rightmost = z->M_parent;
323  // makes rightmost == M_header if z == root
324  } else { // x == z->M_left
325  rightmost = Rb_tree_node_base::S_maximum(x);
326  }
327  }
328  }
329  if (y->M_color != S_rb_tree_red) {
330  while (x != root && (x == nullptr || x->M_color == S_rb_tree_black))
331  if (x == x_parent->M_left) {
332  Rb_tree_node_base* w = x_parent->M_right;
333  if (w->M_color == S_rb_tree_red) {
334  w->M_color = S_rb_tree_black;
335  x_parent->M_color = S_rb_tree_red;
336  Rb_tree_rotate_left(x_parent, root);
337  w = x_parent->M_right;
338  }
339  if ((w->M_left == nullptr || w->M_left->M_color == S_rb_tree_black) &&
340  (w->M_right == nullptr || w->M_right->M_color == S_rb_tree_black)) {
341  w->M_color = S_rb_tree_red;
342  x = x_parent;
343  x_parent = x_parent->M_parent;
344  } else {
345  if (w->M_right == nullptr || w->M_right->M_color == S_rb_tree_black) {
346  if (w->M_left) w->M_left->M_color = S_rb_tree_black;
347  w->M_color = S_rb_tree_red;
348  Rb_tree_rotate_right(w, root);
349  w = x_parent->M_right;
350  }
351  w->M_color = x_parent->M_color;
352  x_parent->M_color = S_rb_tree_black;
353  if (w->M_right) w->M_right->M_color = S_rb_tree_black;
354  Rb_tree_rotate_left(x_parent, root);
355  break;
356  }
357  } else { // same as above, with M_right <-> M_left.
358  Rb_tree_node_base* w = x_parent->M_left;
359  if (w->M_color == S_rb_tree_red) {
360  w->M_color = S_rb_tree_black;
361  x_parent->M_color = S_rb_tree_red;
362  Rb_tree_rotate_right(x_parent, root);
363  w = x_parent->M_left;
364  }
365  if ((w->M_right == nullptr || w->M_right->M_color == S_rb_tree_black) &&
366  (w->M_left == nullptr || w->M_left->M_color == S_rb_tree_black)) {
367  w->M_color = S_rb_tree_red;
368  x = x_parent;
369  x_parent = x_parent->M_parent;
370  } else {
371  if (w->M_left == nullptr || w->M_left->M_color == S_rb_tree_black) {
372  if (w->M_right) w->M_right->M_color = S_rb_tree_black;
373  w->M_color = S_rb_tree_red;
374  Rb_tree_rotate_left(w, root);
375  w = x_parent->M_left;
376  }
377  w->M_color = x_parent->M_color;
378  x_parent->M_color = S_rb_tree_black;
379  if (w->M_left) w->M_left->M_color = S_rb_tree_black;
380  Rb_tree_rotate_right(x_parent, root);
381  break;
382  }
383  }
384  if (x) x->M_color = S_rb_tree_black;
385  }
386  return y;
387 }
388 
389 // Base class to encapsulate the differences between old SGI-style
390 // allocators and standard-conforming allocators. In order to avoid
391 // having an empty base class, we arbitrarily move one of rb_tree's
392 // data members into the base class.
393 
394 template <class Tp>
395 struct Rb_tree_base {
396  Rb_tree_base() : M_header(nullptr) { M_header = M_get_node(); }
397  ~Rb_tree_base() { M_put_node(M_header); }
398 
399  protected:
400  Rb_tree_node<Tp>* M_header;
401 
402  Rb_tree_node<Tp>* M_get_node() {
403  return static_cast<Rb_tree_node<Tp>*>(
404  std::malloc(sizeof(Rb_tree_node<Tp>)));
405  }
406  void M_put_node(Rb_tree_node<Tp>* p) { std::free(p); }
407 };
408 
409 template <class Key, class Value, class KeyOfValue, class Compare>
410 class Rb_tree : protected Rb_tree_base<Value> {
411  typedef Rb_tree_base<Value> Base;
412 
413  protected:
414  typedef Rb_tree_node_base* Base_ptr;
416  typedef Rb_tree_Color_type Color_type;
417 
418  public:
419  typedef Key key_type;
420  typedef Value value_type;
421  typedef value_type* pointer;
422  typedef const value_type* const_pointer;
423  typedef value_type& reference;
424  typedef const value_type& const_reference;
425  typedef Node_type* Link_type;
426  typedef std::size_t size_type;
427  typedef std::ptrdiff_t difference_type;
428 
429  protected:
430  using Base::M_get_node;
431  using Base::M_header;
432  using Base::M_put_node;
433 
434  protected:
435  Link_type M_create_node(const value_type& x) {
436  Link_type tmp = M_get_node();
437  try {
438  new (&tmp->M_value_field) Value(x);
439  } catch (...) {
440  M_put_node(tmp);
441  throw;
442  }
443  return tmp;
444  }
445 
446  Link_type M_create_node(value_type&& x) {
447  Link_type tmp = M_get_node();
448  try {
449  new (&tmp->M_value_field) Value(x);
450  } catch (...) {
451  M_put_node(tmp);
452  throw;
453  }
454  return tmp;
455  }
456 
457  Link_type M_clone_node(Link_type x) {
458  Link_type tmp = M_create_node(x->M_value_field);
459  tmp->M_color = x->M_color;
460  tmp->M_left = nullptr;
461  tmp->M_right = nullptr;
462  return tmp;
463  }
464 
465  void destroy_node(Link_type p) {
466  p->M_value_field.~Value();
467  M_put_node(p);
468  }
469 
470  protected:
471  size_type M_node_count; // keeps track of size of tree
472  Compare M_key_compare;
473 
474 // although the following casts may technically break aliasing rules,
475 // they provide an excellent separation of the generic tree code (base)
476 // from the specific value type selected by the user
477 #ifdef __clang__
478 #pragma clang diagnostic push
479 #pragma clang diagnostic ignored "-Wold-style-cast"
480 #endif
481  Link_type& M_root() const { return (Link_type&)(M_header->M_parent); }
482  Link_type& M_leftmost() const { return (Link_type&)(M_header->M_left); }
483  Link_type& M_rightmost() const { return (Link_type&)(M_header->M_right); }
484 
485  static Link_type& S_left(Link_type x) { return (Link_type&)(x->M_left); }
486  static Link_type& S_right(Link_type x) { return (Link_type&)(x->M_right); }
487  static Link_type& S_parent(Link_type x) { return (Link_type&)(x->M_parent); }
488  static reference S_value(Link_type x) { return x->M_value_field; }
489  static const Key& S_key(Link_type x) { return KeyOfValue()(S_value(x)); }
490  static Color_type& S_color(Link_type x) { return (x->M_color); }
491 
492  static Link_type& S_left(Base_ptr x) { return (Link_type&)(x->M_left); }
493  static Link_type& S_right(Base_ptr x) { return (Link_type&)(x->M_right); }
494  static Link_type& S_parent(Base_ptr x) { return (Link_type&)(x->M_parent); }
495  static reference S_value(Base_ptr x) { return Link_type(x)->M_value_field; }
496  static const Key& S_key(Base_ptr x) {
497  return KeyOfValue()(S_value(Link_type(x)));
498  }
499  static Color_type& S_color(Base_ptr x) { return Link_type(x)->M_color; }
500 #ifdef __clang__
501 #pragma clang diagnostic pop
502 #endif
503 
504  static Link_type S_minimum(Link_type x) {
505  return static_cast<Link_type>(Rb_tree_node_base::S_minimum(x));
506  }
507 
508  static Link_type S_maximum(Link_type x) {
509  return static_cast<Link_type>(Rb_tree_node_base::S_maximum(x));
510  }
511 
512  public:
516 
517  private:
518  iterator M_insert(Base_ptr x, Base_ptr y, const value_type& v);
519  iterator M_insert(Base_ptr x, Base_ptr y, value_type&& v);
520  Link_type M_copy(Link_type x, Link_type p);
521  void M_erase(Link_type x);
522 
523  public:
524  // allocation/deallocation
525  Rb_tree() : Base(), M_node_count(0), M_key_compare() { M_empty_initialize(); }
526 
527  Rb_tree(const Compare& comp) : Base(), M_node_count(0), M_key_compare(comp) {
528  M_empty_initialize();
529  }
530 
532  : Base(), M_node_count(0), M_key_compare(x.M_key_compare) {
533  if (x.M_root() == nullptr)
534  M_empty_initialize();
535  else {
536  S_color(M_header) = S_rb_tree_red;
537  M_root() = M_copy(x.M_root(), M_header);
538  M_leftmost() = S_minimum(M_root());
539  M_rightmost() = S_maximum(M_root());
540  }
541  M_node_count = x.M_node_count;
542  }
543  ~Rb_tree() { clear(); }
546 
547  private:
548  void M_empty_initialize() {
549  S_color(M_header) = S_rb_tree_red; // used to distinguish header from
550  // root, in iterator.operator++
551  M_root() = nullptr;
552  M_leftmost() = M_header;
553  M_rightmost() = M_header;
554  }
555 
556  public:
557  // accessors:
558  Compare key_comp() const { return M_key_compare; }
559  iterator begin() { return M_leftmost(); }
560  const_iterator begin() const { return M_leftmost(); }
561  iterator end() { return M_header; }
562  const_iterator end() const { return M_header; }
563  bool empty() const { return M_node_count == 0; }
564  size_type size() const { return M_node_count; }
565  size_type max_size() const { return size_type(-1); }
566 
568  nonstd::swap(M_header, t.M_header);
569  nonstd::swap(M_node_count, t.M_node_count);
570  nonstd::swap(M_key_compare, t.M_key_compare);
571  }
572 
573  public:
574  // insert/erase
575  std::pair<iterator, bool> insert(const value_type& x);
576  std::pair<iterator, bool> insert(value_type&& x);
577 
578  iterator insert(iterator position, const value_type& x);
579  iterator insert(iterator position, value_type&& x);
580 
581  template <class InputIterator>
582  void insert(InputIterator first, InputIterator last);
583 
584  void erase(iterator position);
585  size_type erase(const key_type& x);
586  void erase(iterator first, iterator last);
587  void erase(const key_type* first, const key_type* last);
588  void clear() {
589  if (M_node_count != 0) {
590  M_erase(M_root());
591  M_leftmost() = M_header;
592  M_root() = nullptr;
593  M_rightmost() = M_header;
594  M_node_count = 0;
595  }
596  }
597 
598  public:
599  // set operations:
600  iterator find(const key_type& x);
601  const_iterator find(const key_type& x) const;
602  size_type count(const key_type& x) const;
603  iterator lower_bound(const key_type& x);
604  const_iterator lower_bound(const key_type& x) const;
605  iterator upper_bound(const key_type& x);
606  const_iterator upper_bound(const key_type& x) const;
607  std::pair<iterator, iterator> equal_range(const key_type& x);
608  std::pair<const_iterator, const_iterator> equal_range(
609  const key_type& x) const;
610 };
611 
612 template <class Key, class Value, class KeyOfValue, class Compare>
613 inline bool operator==(const Rb_tree<Key, Value, KeyOfValue, Compare>& x,
615  return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
616 }
617 
618 template <class Key, class Value, class KeyOfValue, class Compare>
619 inline bool operator<(const Rb_tree<Key, Value, KeyOfValue, Compare>& x,
620  const Rb_tree<Key, Value, KeyOfValue, Compare>& y) {
621  return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
622 }
623 
624 template <class Key, class Value, class KeyOfValue, class Compare>
625 Rb_tree<Key, Value, KeyOfValue, Compare>&
626 Rb_tree<Key, Value, KeyOfValue, Compare>::operator=(
627  const Rb_tree<Key, Value, KeyOfValue, Compare>& x) {
628  if (this != &x) { // Note that Key may be a constant type.
629  clear();
630  M_node_count = 0;
631  M_key_compare = x.M_key_compare;
632  if (x.M_root() == nullptr) {
633  M_root() = nullptr;
634  M_leftmost() = M_header;
635  M_rightmost() = M_header;
636  } else {
637  M_root() = M_copy(x.M_root(), M_header);
638  M_leftmost() = S_minimum(M_root());
639  M_rightmost() = S_maximum(M_root());
640  M_node_count = x.M_node_count;
641  }
642  }
643  return *this;
644 }
645 
646 template <class Key, class Value, class KeyOfValue, class Compare>
647 typename Rb_tree<Key, Value, KeyOfValue, Compare>::iterator
648 Rb_tree<Key, Value, KeyOfValue, Compare>::M_insert(
649  Base_ptr x_, Base_ptr y_, const Value& v) {
650  Link_type x = Link_type(x_);
651  Link_type y = Link_type(y_);
652  Link_type z;
653 
654  if (y == M_header || x != nullptr ||
655  M_key_compare(KeyOfValue()(v), S_key(y))) {
656  z = M_create_node(v);
657  S_left(y) = z; // also makes M_leftmost() = z
658  // when y == M_header
659  if (y == M_header) {
660  M_root() = z;
661  M_rightmost() = z;
662  } else if (y == M_leftmost())
663  M_leftmost() = z; // maintain M_leftmost() pointing to min node
664  } else {
665  z = M_create_node(v);
666  S_right(y) = z;
667  if (y == M_rightmost())
668  M_rightmost() = z; // maintain M_rightmost() pointing to max node
669  }
670  S_parent(z) = y;
671  S_left(z) = nullptr;
672  S_right(z) = nullptr;
673  Rb_tree_rebalance(z, M_header->M_parent);
674  ++M_node_count;
675  return iterator(z);
676 }
677 
678 template <class Key, class Value, class KeyOfValue, class Compare>
679 typename Rb_tree<Key, Value, KeyOfValue, Compare>::iterator
680 Rb_tree<Key, Value, KeyOfValue, Compare>::M_insert(
681  Base_ptr x_, Base_ptr y_, Value&& v) {
682  Link_type x = Link_type(x_);
683  Link_type y = Link_type(y_);
684  Link_type z;
685 
686  if (y == M_header || x != nullptr ||
687  M_key_compare(KeyOfValue()(v), S_key(y))) {
688  z = M_create_node(std::move(v));
689  S_left(y) = z; // also makes M_leftmost() = z
690  // when y == M_header
691  if (y == M_header) {
692  M_root() = z;
693  M_rightmost() = z;
694  } else if (y == M_leftmost())
695  M_leftmost() = z; // maintain M_leftmost() pointing to min node
696  } else {
697  z = M_create_node(std::move(v));
698  S_right(y) = z;
699  if (y == M_rightmost())
700  M_rightmost() = z; // maintain M_rightmost() pointing to max node
701  }
702  S_parent(z) = y;
703  S_left(z) = nullptr;
704  S_right(z) = nullptr;
705  Rb_tree_rebalance(z, M_header->M_parent);
706  ++M_node_count;
707  return iterator(z);
708 }
709 
710 template <class Key, class Value, class KeyOfValue, class Compare>
711 std::pair<typename Rb_tree<Key, Value, KeyOfValue, Compare>::iterator, bool>
712 Rb_tree<Key, Value, KeyOfValue, Compare>::insert(const Value& v) {
713  Link_type y = M_header;
714  Link_type x = M_root();
715  bool comp = true;
716  while (x != nullptr) {
717  y = x;
718  comp = M_key_compare(KeyOfValue()(v), S_key(x));
719  x = comp ? S_left(x) : S_right(x);
720  }
721  iterator j = iterator(y);
722  if (comp) {
723  if (j == begin()) {
724  return std::pair<iterator, bool>(M_insert(x, y, v), true);
725  } else {
726  --j;
727  }
728  }
729  if (M_key_compare(S_key(j.M_node), KeyOfValue()(v))) {
730  return std::pair<iterator, bool>(M_insert(x, y, v), true);
731  }
732  return std::pair<iterator, bool>(j, false);
733 }
734 
735 template <class Key, class Value, class KeyOfValue, class Compare>
736 std::pair<typename Rb_tree<Key, Value, KeyOfValue, Compare>::iterator, bool>
737 Rb_tree<Key, Value, KeyOfValue, Compare>::insert(Value&& v) {
738  Link_type y = M_header;
739  Link_type x = M_root();
740  bool comp = true;
741  while (x != nullptr) {
742  y = x;
743  comp = M_key_compare(KeyOfValue()(v), S_key(x));
744  x = comp ? S_left(x) : S_right(x);
745  }
746  iterator j = iterator(y);
747  if (comp) {
748  if (j == begin()) {
749  return std::pair<iterator, bool>(M_insert(x, y, std::move(v)), true);
750  } else {
751  --j;
752  }
753  }
754  if (M_key_compare(S_key(j.M_node), KeyOfValue()(v))) {
755  return std::pair<iterator, bool>(M_insert(x, y, std::move(v)), true);
756  }
757  return std::pair<iterator, bool>(j, false);
758 }
759 
760 template <class Key, class Val, class KeyOfValue, class Compare>
761 typename Rb_tree<Key, Val, KeyOfValue, Compare>::iterator
762 Rb_tree<Key, Val, KeyOfValue, Compare>::insert(
763  iterator position, const Val& v) {
764  if (position.M_node == M_header->M_left) { // begin()
765  if (size() > 0 && M_key_compare(KeyOfValue()(v), S_key(position.M_node)))
766  return M_insert(position.M_node, position.M_node, v);
767  // first argument just needs to be non-null
768  else
769  return insert(v).first;
770  } else if (position.M_node == M_header) { // end()
771  if (M_key_compare(S_key(M_rightmost()), KeyOfValue()(v)))
772  return M_insert(nullptr, M_rightmost(), v);
773  else
774  return insert(v).first;
775  } else {
776  iterator before = position;
777  --before;
778  if (M_key_compare(S_key(before.M_node), KeyOfValue()(v)) &&
779  M_key_compare(KeyOfValue()(v), S_key(position.M_node))) {
780  if (S_right(before.M_node) == nullptr)
781  return M_insert(nullptr, before.M_node, v);
782  else
783  return M_insert(position.M_node, position.M_node, v);
784  // first argument just needs to be non-null
785  } else
786  return insert(v).first;
787  }
788 }
789 
790 template <class Key, class Val, class KeyOfValue, class Compare>
791 typename Rb_tree<Key, Val, KeyOfValue, Compare>::iterator
792 Rb_tree<Key, Val, KeyOfValue, Compare>::insert(iterator position, Val&& v) {
793  if (position.M_node == M_header->M_left) { // begin()
794  if (size() > 0 && M_key_compare(KeyOfValue()(v), S_key(position.M_node)))
795  return M_insert(position.M_node, position.M_node, std::move(v));
796  // first argument just needs to be non-null
797  else
798  return insert(std::move(v)).first;
799  } else if (position.M_node == M_header) { // end()
800  if (M_key_compare(S_key(M_rightmost()), KeyOfValue()(v)))
801  return M_insert(nullptr, M_rightmost(), std::move(v));
802  else
803  return insert(std::move(v)).first;
804  } else {
805  iterator before = position;
806  --before;
807  if (M_key_compare(S_key(before.M_node), KeyOfValue()(v)) &&
808  M_key_compare(KeyOfValue()(v), S_key(position.M_node))) {
809  if (S_right(before.M_node) == nullptr)
810  return M_insert(nullptr, before.M_node, std::move(v));
811  else
812  return M_insert(position.M_node, position.M_node, std::move(v));
813  // first argument just needs to be non-null
814  } else
815  return insert(std::move(v)).first;
816  }
817 }
818 
819 template <class Key, class Val, class KeyOfValue, class Cmp>
820 template <class II>
821 void Rb_tree<Key, Val, KeyOfValue, Cmp>::insert(II first, II last) {
822  for (; first != last; ++first) insert(*first);
823 }
824 
825 template <class Key, class Value, class KeyOfValue, class Compare>
826 inline void Rb_tree<Key, Value, KeyOfValue, Compare>::erase(iterator position) {
827  Link_type y = Rb_tree_rebalance_for_erase(
828  position.M_node, M_header->M_parent, M_header->M_left, M_header->M_right);
829  destroy_node(y);
830  --M_node_count;
831 }
832 
833 template <class Key, class Value, class KeyOfValue, class Compare>
834 typename Rb_tree<Key, Value, KeyOfValue, Compare>::size_type
835 Rb_tree<Key, Value, KeyOfValue, Compare>::erase(const Key& x) {
836  std::pair<iterator, iterator> p = equal_range(x);
837  size_type n = size_type(std::distance(p.first, p.second));
838  erase(p.first, p.second);
839  return n;
840 }
841 
842 template <class Key, class Val, class KeyOfValue, class Compare>
843 typename Rb_tree<Key, Val, KeyOfValue, Compare>::Link_type
844 Rb_tree<Key, Val, KeyOfValue, Compare>::M_copy(Link_type x, Link_type p) {
845  // structural copy. x and p must be non-null.
846  Link_type top = M_clone_node(x);
847  top->M_parent = p;
848 
849  try {
850  if (x->M_right) top->M_right = M_copy(S_right(x), top);
851  p = top;
852  x = S_left(x);
853 
854  while (x != nullptr) {
855  Link_type y = M_clone_node(x);
856  p->M_left = y;
857  y->M_parent = p;
858  if (x->M_right) y->M_right = M_copy(S_right(x), y);
859  p = y;
860  x = S_left(x);
861  }
862  } catch (...) {
863  M_erase(top);
864  throw;
865  }
866 
867  return top;
868 }
869 
870 template <class Key, class Value, class KeyOfValue, class Compare>
871 void Rb_tree<Key, Value, KeyOfValue, Compare>::M_erase(
872  Link_type x) { // erase without rebalancing
873  while (x != nullptr) {
874  M_erase(S_right(x));
875  Link_type y = S_left(x);
876  destroy_node(x);
877  x = y;
878  }
879 }
880 
881 template <class Key, class Value, class KeyOfValue, class Compare>
882 void Rb_tree<Key, Value, KeyOfValue, Compare>::erase(
883  iterator first, iterator last) {
884  if (first == begin() && last == end())
885  clear();
886  else
887  while (first != last) erase(first++);
888 }
889 
890 template <class Key, class Value, class KeyOfValue, class Compare>
891 void Rb_tree<Key, Value, KeyOfValue, Compare>::erase(
892  const Key* first, const Key* last) {
893  while (first != last) erase(*first++);
894 }
895 
896 template <class Key, class Value, class KeyOfValue, class Compare>
897 typename Rb_tree<Key, Value, KeyOfValue, Compare>::iterator
898 Rb_tree<Key, Value, KeyOfValue, Compare>::find(const Key& k) {
899  Link_type y = M_header; // Last node which is not less than k.
900  Link_type x = M_root(); // Current node.
901 
902  while (x != nullptr)
903  if (!M_key_compare(S_key(x), k))
904  y = x, x = S_left(x);
905  else
906  x = S_right(x);
907 
908  iterator j = iterator(y);
909  return (j == end() || M_key_compare(k, S_key(j.M_node))) ? end() : j;
910 }
911 
912 template <class Key, class Value, class KeyOfValue, class Compare>
913 typename Rb_tree<Key, Value, KeyOfValue, Compare>::const_iterator
914 Rb_tree<Key, Value, KeyOfValue, Compare>::find(const Key& k) const {
915  Link_type y = M_header; /* Last node which is not less than k. */
916  Link_type x = M_root(); /* Current node. */
917 
918  while (x != nullptr) {
919  if (!M_key_compare(S_key(x), k))
920  y = x, x = S_left(x);
921  else
922  x = S_right(x);
923  }
924  const_iterator j = const_iterator(y);
925  return (j == end() || M_key_compare(k, S_key(j.M_node))) ? end() : j;
926 }
927 
928 template <class Key, class Value, class KeyOfValue, class Compare>
929 typename Rb_tree<Key, Value, KeyOfValue, Compare>::size_type
930 Rb_tree<Key, Value, KeyOfValue, Compare>::count(const Key& k) const {
931  std::pair<const_iterator, const_iterator> p = equal_range(k);
932  return size_type(std::distance(p.first, p.second));
933 }
934 
935 template <class Key, class Value, class KeyOfValue, class Compare>
936 typename Rb_tree<Key, Value, KeyOfValue, Compare>::iterator
937 Rb_tree<Key, Value, KeyOfValue, Compare>::lower_bound(const Key& k) {
938  Link_type y = M_header; /* Last node which is not less than k. */
939  Link_type x = M_root(); /* Current node. */
940 
941  while (x != nullptr)
942  if (!M_key_compare(S_key(x), k))
943  y = x, x = S_left(x);
944  else
945  x = S_right(x);
946 
947  return iterator(y);
948 }
949 
950 template <class Key, class Value, class KeyOfValue, class Compare>
951 typename Rb_tree<Key, Value, KeyOfValue, Compare>::const_iterator
952 Rb_tree<Key, Value, KeyOfValue, Compare>::lower_bound(const Key& k) const {
953  Link_type y = M_header; /* Last node which is not less than k. */
954  Link_type x = M_root(); /* Current node. */
955 
956  while (x != nullptr)
957  if (!M_key_compare(S_key(x), k))
958  y = x, x = S_left(x);
959  else
960  x = S_right(x);
961 
962  return const_iterator(y);
963 }
964 
965 template <class Key, class Value, class KeyOfValue, class Compare>
966 typename Rb_tree<Key, Value, KeyOfValue, Compare>::iterator
967 Rb_tree<Key, Value, KeyOfValue, Compare>::upper_bound(const Key& k) {
968  Link_type y = M_header; /* Last node which is greater than k. */
969  Link_type x = M_root(); /* Current node. */
970 
971  while (x != nullptr)
972  if (M_key_compare(k, S_key(x)))
973  y = x, x = S_left(x);
974  else
975  x = S_right(x);
976 
977  return iterator(y);
978 }
979 
980 template <class Key, class Value, class KeyOfValue, class Compare>
981 typename Rb_tree<Key, Value, KeyOfValue, Compare>::const_iterator
982 Rb_tree<Key, Value, KeyOfValue, Compare>::upper_bound(const Key& k) const {
983  Link_type y = M_header; /* Last node which is greater than k. */
984  Link_type x = M_root(); /* Current node. */
985 
986  while (x != nullptr)
987  if (M_key_compare(k, S_key(x)))
988  y = x, x = S_left(x);
989  else
990  x = S_right(x);
991 
992  return const_iterator(y);
993 }
994 
995 template <class Key, class Value, class KeyOfValue, class Compare>
996 inline std::pair<typename Rb_tree<Key, Value, KeyOfValue, Compare>::iterator,
997  typename Rb_tree<Key, Value, KeyOfValue, Compare>::iterator>
998 Rb_tree<Key, Value, KeyOfValue, Compare>::equal_range(const Key& k) {
999  return std::pair<iterator, iterator>(lower_bound(k), upper_bound(k));
1000 }
1001 
1002 template <class Key, class Value, class KeyOfValue, class Compare>
1003 inline std::pair<
1004  typename Rb_tree<Key, Value, KeyOfValue, Compare>::const_iterator,
1005  typename Rb_tree<Key, Value, KeyOfValue, Compare>::const_iterator>
1006 Rb_tree<Key, Value, KeyOfValue, Compare>::equal_range(const Key& k) const {
1007  return std::pair<const_iterator, const_iterator>(
1008  lower_bound(k), upper_bound(k));
1009 }
1010 
1011 template <class Key, class Value, class KeyOfValue,
1012  class Compare = std::less<Key>>
1013 struct rb_tree : public Rb_tree<Key, Value, KeyOfValue, Compare> {
1015 
1016  rb_tree(const Compare& comp = Compare()) : Base(comp) {}
1017 
1018  rb_tree(rb_tree const&) = default;
1019  ~rb_tree() = default;
1020 };
1021 
1022 template <class T>
1024  T const& operator()(T const& value) const { return value; }
1025 };
1026 
1027 template <class Key>
1029 
1030 template <class T1, class T2>
1032  T1 const& operator()(std::pair<T1, T2> const& value) const {
1033  return value.first;
1034  }
1035 };
1036 
1037 template <class Key, class Value>
1038 struct map
1039  : public rb_tree<Key, std::pair<Key, Value>, Rb_first_as_key<Key, Value>> {
1040  Value& operator[](const Key& key) {
1041  auto it = this->upper_bound(key);
1042  if (it == this->end() || (!(it->first == key))) {
1043  it = this->insert(it, std::make_pair(key, Value()));
1044  }
1045  return it->second;
1046  }
1047 };
1048 
1049 } // namespace Omega_h
1050 
1051 #endif
Definition: Omega_h_rbtree.hpp:410
Definition: amr_mpi_test.cpp:6
Definition: Omega_h_rbtree.hpp:1031
Definition: Omega_h_rbtree.hpp:105
Definition: Omega_h_rbtree.hpp:395
Definition: Omega_h_rbtree.hpp:145
Definition: Omega_h_rbtree.hpp:79
Definition: Omega_h_rbtree.hpp:100
Definition: Omega_h_rbtree.hpp:1023
Definition: Omega_h_rbtree.hpp:1039
Definition: Omega_h_rbtree.hpp:1013