CppCommon  1.0.4.1
C++ Common Library
bintree.inl
Go to the documentation of this file.
1 
9 namespace CppCommon {
10 
11 template <typename T, typename TCompare>
12 template <class InputIterator>
13 inline BinTree<T, TCompare>::BinTree(InputIterator first, InputIterator last, const TCompare& compare) noexcept
14  : _compare(compare)
15 {
16  for (auto it = first; it != last; ++it)
17  insert(*it);
18 }
19 
20 template <typename T, typename TCompare>
21 inline T* BinTree<T, TCompare>::lowest() noexcept
22 {
23  return (T*)InternalLowest();
24 }
25 
26 template <typename T, typename TCompare>
27 inline const T* BinTree<T, TCompare>::lowest() const noexcept
28 {
29  return InternalLowest();
30 }
31 
32 template <typename T, typename TCompare>
33 inline const T* BinTree<T, TCompare>::InternalLowest() const noexcept
34 {
35  const T* result = _root;
36  if (result != nullptr)
37  while (result->left != nullptr)
38  result = result->left;
39  return result;
40 }
41 
42 template <typename T, typename TCompare>
43 inline T* BinTree<T, TCompare>::highest() noexcept
44 {
45  return (T*)InternalHighest();
46 }
47 
48 template <typename T, typename TCompare>
49 inline const T* BinTree<T, TCompare>::highest() const noexcept
50 {
51  return InternalHighest();
52 }
53 
54 template <typename T, typename TCompare>
55 inline const T* BinTree<T, TCompare>::InternalHighest() const noexcept
56 {
57  const T* result = _root;
58  if (result != nullptr)
59  while (result->right != nullptr)
60  result = result->right;
61  return result;
62 }
63 
64 template <typename T, typename TCompare>
66 {
67  return iterator(this, lowest());
68 }
69 
70 template <typename T, typename TCompare>
72 {
73  return const_iterator(this, lowest());
74 }
75 
76 template <typename T, typename TCompare>
78 {
79  return const_iterator(this, lowest());
80 }
81 
82 template <typename T, typename TCompare>
84 {
85  return iterator(this, nullptr);
86 }
87 
88 template <typename T, typename TCompare>
90 {
91  return const_iterator(this, nullptr);
92 }
93 
94 template <typename T, typename TCompare>
96 {
97  return const_iterator(this, nullptr);
98 }
99 
100 template <typename T, typename TCompare>
102 {
103  return reverse_iterator(this, highest());
104 }
105 
106 template <typename T, typename TCompare>
108 {
109  return const_reverse_iterator(this, highest());
110 }
111 
112 template <typename T, typename TCompare>
114 {
115  return const_reverse_iterator(this, highest());
116 }
117 
118 template <typename T, typename TCompare>
120 {
121  return reverse_iterator(this, nullptr);
122 }
123 
124 template <typename T, typename TCompare>
126 {
127  return const_reverse_iterator(this, nullptr);
128 }
129 
130 template <typename T, typename TCompare>
132 {
133  return const_reverse_iterator(this, nullptr);
134 }
135 
136 template <typename T, typename TCompare>
137 inline typename BinTree<T, TCompare>::iterator BinTree<T, TCompare>::find(const T& item) noexcept
138 {
139  return iterator(this, (T*)InternalFind(item));
140 }
141 
142 template <typename T, typename TCompare>
143 inline typename BinTree<T, TCompare>::const_iterator BinTree<T, TCompare>::find(const T& item) const noexcept
144 {
145  return const_iterator(this, InternalFind(item));
146 }
147 
148 template <typename T, typename TCompare>
149 inline const T* BinTree<T, TCompare>::InternalFind(const T& item) const noexcept
150 {
151  // Perform the binary tree search from the root node
152  const T* current = _root;
153 
154  while (current != nullptr)
155  {
156  // Move to the left subtree
157  if (compare(item, *current))
158  {
159  current = current->left;
160  continue;
161  }
162 
163  // Move to the right subtree
164  if (compare(*current, item))
165  {
166  current = current->right;
167  continue;
168  }
169 
170  // Found result node
171  return current;
172  }
173 
174  // Nothing was found...
175  return nullptr;
176 }
177 
178 template <typename T, typename TCompare>
180 {
181  return iterator(this, (T*)InternalLowerBound(item));
182 }
183 
184 template <typename T, typename TCompare>
185 inline typename BinTree<T, TCompare>::const_iterator BinTree<T, TCompare>::lower_bound(const T& item) const noexcept
186 {
187  return const_iterator(this, InternalLowerBound(item));
188 }
189 
190 template <typename T, typename TCompare>
191 inline const T* BinTree<T, TCompare>::InternalLowerBound(const T& item) const noexcept
192 {
193  // Perform the binary tree search from the root node
194  const T* current = _root;
195  const T* previous = nullptr;
196 
197  while (current != nullptr)
198  {
199  // Move to the left subtree
200  if (compare(item, *current))
201  {
202  previous = current;
203  current = current->left;
204  continue;
205  }
206 
207  // Move to the right subtree
208  if (compare(*current, item))
209  {
210  current = current->right;
211  continue;
212  }
213 
214  // Found result node
215  return current;
216  }
217 
218  // Return the previous lower bound node if any met
219  return previous;
220 }
221 
222 template <typename T, typename TCompare>
224 {
225  return iterator(this, (T*)InternalUpperBound(item));
226 }
227 
228 template <typename T, typename TCompare>
229 inline typename BinTree<T, TCompare>::const_iterator BinTree<T, TCompare>::upper_bound(const T& item) const noexcept
230 {
231  return const_iterator(this, InternalUpperBound(item));
232 }
233 
234 template <typename T, typename TCompare>
235 inline const T* BinTree<T, TCompare>::InternalUpperBound(const T& item) const noexcept
236 {
237  // Perform the binary tree search from the root node
238  const T* current = _root;
239  const T* previous = nullptr;
240 
241  while (current != nullptr)
242  {
243  // Move to the left subtree
244  if (compare(item, *current))
245  {
246  previous = current;
247  current = current->left;
248  continue;
249  }
250 
251  // Move to the right subtree
252  current = current->right;
253  }
254 
255  // Return the previous upper bound node if any met
256  return previous;
257 }
258 
259 template <typename T, typename TCompare>
260 inline std::pair<typename BinTree<T, TCompare>::iterator, bool> BinTree<T, TCompare>::insert(T& item) noexcept
261 {
262  return insert(const_iterator(this, _root), item);
263 }
264 
265 template <typename T, typename TCompare>
266 inline std::pair<typename BinTree<T, TCompare>::iterator, bool> BinTree<T, TCompare>::insert(const const_iterator& position, T& item) noexcept
267 {
268  // Perform the binary tree insert from the given node
269  T* current = (T*)position.operator->();
270 
271  while (current != nullptr)
272  {
273  // Move to the left subtree
274  if (compare(item, *current))
275  {
276  if (current->left != nullptr)
277  {
278  current = current->left;
279  continue;
280  }
281  else
282  {
283  // Link a new item to the left leaf
284  current->left = &item;
285  break;
286  }
287  }
288 
289  // Move to the right subtree
290  if (compare(*current, item))
291  {
292  if (current->right != nullptr)
293  {
294  current = current->right;
295  continue;
296  }
297  else
298  {
299  // Link a new item to the right leaf
300  current->right = &item;
301  break;
302  }
303  }
304 
305  // Found duplicate node
306  return std::make_pair(iterator(this, current), false);
307  }
308 
309  item.parent = current;
310  item.left = nullptr;
311  item.right = nullptr;
312  if (_root == nullptr)
313  _root = &item;
314  ++_size;
315 
316  return std::make_pair(iterator(this, &item), true);
317 }
318 
319 template <typename T, typename TCompare>
320 inline T* BinTree<T, TCompare>::erase(const T& item) noexcept
321 {
322  return erase(find(item)).operator->();
323 }
324 
325 template <typename T, typename TCompare>
327 {
328  T* result = ((iterator&)it).operator->();
329  if (result == nullptr)
330  return end();
331 
332  T* parent = result->parent;
333  T* left = result->left;
334  T* right = result->right;
335 
336  // Binary tree node without left child
337  if (left == nullptr)
338  {
339  // Link the parent node with a right child
340  if (parent != nullptr)
341  {
342  if (parent->left == result)
343  parent->left = right;
344  else
345  parent->right = right;
346  }
347  else
348  _root = right;
349  if (right != nullptr)
350  right->parent = parent;
351  }
352  // Binary tree node without right child
353  else if (right == nullptr)
354  {
355  // Link the parent node with a left child
356  if (parent != nullptr)
357  {
358  if (parent->left == result)
359  parent->left = left;
360  else
361  parent->right = left;
362  }
363  else
364  _root = left;
365  if (left != nullptr)
366  left->parent = parent;
367  }
368  // Binary tree node with both left and right childs
369  else
370  {
371  // Link the parent node with a left child
372  if (parent != nullptr)
373  {
374  if (parent->left == result)
375  parent->left = left;
376  else
377  parent->right = left;
378  }
379  else
380  _root = left;
381  left->parent = parent;
382 
383  // Find a new base node
384  T* temp = left;
385  while (temp->right != nullptr)
386  temp = temp->right;
387  temp->right = right;
388  right->parent = temp;
389  }
390 
391  result->parent = nullptr;
392  result->left = nullptr;
393  result->right = nullptr;
394  --_size;
395  return iterator(this, result);
396 }
397 
398 template <typename T, typename TCompare>
399 inline void BinTree<T, TCompare>::clear() noexcept
400 {
401  _size = 0;
402  _root = nullptr;
403 }
404 
405 template <typename T, typename TCompare>
406 inline void BinTree<T, TCompare>::swap(BinTree& bintree) noexcept
407 {
408  using std::swap;
409  swap(_compare, bintree._compare);
410  swap(_size, bintree._size);
411  swap(_root, bintree._root);
412 }
413 
414 template <typename T, typename TCompare>
415 inline void swap(BinTree<T, TCompare>& bintree1, BinTree<T, TCompare>& bintree2) noexcept
416 {
417  bintree1.swap(bintree2);
418 }
419 
420 template <class TContainer, typename T>
422 {
423  if (_node != nullptr)
424  {
425  if (_node->right != nullptr)
426  {
427  _node = _node->right;
428  while (_node->left != nullptr)
429  _node = _node->left;
430  }
431  else
432  {
433  while ((_node->parent != nullptr) && compare(*_node->parent, *_node))
434  _node = _node->parent;
435  _node = _node->parent;
436  }
437  }
438  return *this;
439 }
440 
441 template <class TContainer, typename T>
443 {
444  BinTreeIterator<TContainer, T> result(*this);
445  operator++();
446  return result;
447 }
448 
449 template <class TContainer, typename T>
451 {
452  assert((_node != nullptr) && "Iterator must be valid!");
453 
454  return *_node;
455 }
456 
457 template <class TContainer, typename T>
459 {
460  return _node;
461 }
462 
463 template <class TContainer, typename T>
465 {
466  using std::swap;
467  swap(_container, it._container);
468  swap(_node, it._node);
469 }
470 
471 template <class TContainer, typename T>
473 {
474  it1.swap(it2);
475 }
476 
477 template <class TContainer, typename T>
479 {
480  if (_node != nullptr)
481  {
482  if (_node->right != nullptr)
483  {
484  _node = _node->right;
485  while (_node->left != nullptr)
486  _node = _node->left;
487  }
488  else
489  {
490  while ((_node->parent != nullptr) && compare(*_node->parent, *_node))
491  _node = _node->parent;
492  _node = _node->parent;
493  }
494  }
495  return *this;
496 }
497 
498 template <class TContainer, typename T>
500 {
502  operator++();
503  return result;
504 }
505 
506 template <class TContainer, typename T>
508 {
509  assert((_node != nullptr) && "Iterator must be valid!");
510 
511  return *_node;
512 }
513 
514 template <class TContainer, typename T>
516 {
517  return _node;
518 }
519 
520 template <class TContainer, typename T>
522 {
523  using std::swap;
524  swap(_container, it._container);
525  swap(_node, it._node);
526 }
527 
528 template <class TContainer, typename T>
530 {
531  it1.swap(it2);
532 }
533 
534 template <class TContainer, typename T>
536 {
537  if (_node != nullptr)
538  {
539  if (_node->left != nullptr)
540  {
541  _node = _node->left;
542  while (_node->right != nullptr)
543  _node = _node->right;
544  }
545  else
546  {
547  while ((_node->parent != nullptr) && compare(*_node, *_node->parent))
548  _node = _node->parent;
549  _node = _node->parent;
550  }
551  }
552  return *this;
553 }
554 
555 template <class TContainer, typename T>
557 {
559  operator++();
560  return result;
561 }
562 
563 template <class TContainer, typename T>
565 {
566  assert((_node != nullptr) && "Iterator must be valid!");
567 
568  return *_node;
569 }
570 
571 template <class TContainer, typename T>
573 {
574  return _node;
575 }
576 
577 template <class TContainer, typename T>
579 {
580  using std::swap;
581  swap(_container, it._container);
582  swap(_node, it._node);
583 }
584 
585 template <class TContainer, typename T>
587 {
588  it1.swap(it2);
589 }
590 
591 template <class TContainer, typename T>
593 {
594  if (_node != nullptr)
595  {
596  if (_node->left != nullptr)
597  {
598  _node = _node->left;
599  while (_node->right != nullptr)
600  _node = _node->right;
601  }
602  else
603  {
604  while ((_node->parent != nullptr) && compare(*_node, *_node->parent))
605  _node = _node->parent;
606  _node = _node->parent;
607  }
608  }
609  return *this;
610 }
611 
612 template <class TContainer, typename T>
614 {
616  operator++();
617  return result;
618 }
619 
620 template <class TContainer, typename T>
622 {
623  assert((_node != nullptr) && "Iterator must be valid!");
624 
625  return *_node;
626 }
627 
628 template <class TContainer, typename T>
630 {
631  return _node;
632 }
633 
634 template <class TContainer, typename T>
636 {
637  using std::swap;
638  swap(_container, it._container);
639  swap(_node, it._node);
640 }
641 
642 template <class TContainer, typename T>
644 {
645  it1.swap(it2);
646 }
647 
648 } // namespace CppCommon
Intrusive binary tree constant iterator.
Definition: bintree.h:335
BinTreeConstIterator & operator++() noexcept
Definition: bintree.inl:478
const value_type & const_reference
Definition: bintree.h:340
const_pointer operator->() const noexcept
Definition: bintree.inl:515
const value_type * const_pointer
Definition: bintree.h:342
const_reference operator*() const noexcept
Definition: bintree.inl:507
void swap(BinTreeConstIterator &it) noexcept
Swap two instances.
Definition: bintree.inl:521
Intrusive binary tree constant reverse iterator.
Definition: bintree.h:448
BinTreeConstReverseIterator & operator++() noexcept
Definition: bintree.inl:592
const value_type * const_pointer
Definition: bintree.h:455
const_reference operator*() const noexcept
Definition: bintree.inl:621
void swap(BinTreeConstReverseIterator &it) noexcept
Swap two instances.
Definition: bintree.inl:635
const value_type & const_reference
Definition: bintree.h:453
const_pointer operator->() const noexcept
Definition: bintree.inl:629
Intrusive non balanced binary tree container.
Definition: bintree.h:139
std::pair< iterator, bool > insert(T &item) noexcept
Insert a new item into the binary tree.
Definition: bintree.inl:260
iterator upper_bound(const T &item) noexcept
Find the iterator which points to the first item that greater than the given item in the binary tree ...
Definition: bintree.inl:223
void clear() noexcept
Clear the binary tree.
Definition: bintree.inl:399
iterator lower_bound(const T &item) noexcept
Find the iterator which points to the first item that not less than the given item in the binary tree...
Definition: bintree.inl:179
reverse_iterator rend() noexcept
Get the reverse end binary tree iterator.
Definition: bintree.inl:119
iterator find(const T &item) noexcept
Find the iterator which points to the first equal item in the binary tree or return end iterator.
Definition: bintree.inl:137
iterator end() noexcept
Get the end binary tree iterator.
Definition: bintree.inl:83
BinTree(const TCompare &compare=TCompare()) noexcept
Definition: bintree.h:165
iterator begin() noexcept
Get the begin binary tree iterator.
Definition: bintree.inl:65
T * highest() noexcept
Get the highest binary tree item.
Definition: bintree.inl:43
const_reverse_iterator crend() const noexcept
Definition: bintree.inl:131
T * lowest() noexcept
Get the lowest binary tree item.
Definition: bintree.inl:21
T * erase(const T &item) noexcept
Erase the given item from the binary tree.
Definition: bintree.inl:320
const_iterator cbegin() const noexcept
Definition: bintree.inl:77
const_iterator cend() const noexcept
Definition: bintree.inl:95
reverse_iterator rbegin() noexcept
Get the reverse begin binary tree iterator.
Definition: bintree.inl:101
void swap(BinTree &bintree) noexcept
Swap two instances.
Definition: bintree.inl:406
const_reverse_iterator crbegin() const noexcept
Definition: bintree.inl:113
Intrusive binary tree iterator.
Definition: bintree.h:279
reference operator*() noexcept
Definition: bintree.inl:450
value_type & reference
Definition: bintree.h:285
void swap(BinTreeIterator &it) noexcept
Swap two instances.
Definition: bintree.inl:464
value_type * pointer
Definition: bintree.h:287
pointer operator->() noexcept
Definition: bintree.inl:458
BinTreeIterator & operator++() noexcept
Definition: bintree.inl:421
Intrusive binary tree reverse iterator.
Definition: bintree.h:392
void swap(BinTreeReverseIterator &it) noexcept
Swap two instances.
Definition: bintree.inl:578
pointer operator->() noexcept
Definition: bintree.inl:572
reference operator*() noexcept
Definition: bintree.inl:564
BinTreeReverseIterator & operator++() noexcept
Definition: bintree.inl:535
C++ Common project definitions.
Definition: token_bucket.h:15
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition: filecache.inl:23
void swap(BinTreeConstReverseIterator< TContainer, T > &it1, BinTreeConstReverseIterator< TContainer, T > &it2) noexcept
Definition: bintree.inl:643