CppCommon  1.0.4.1
C++ Common Library
bintree_aa.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 BinTreeAA<T, TCompare>::BinTreeAA(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* BinTreeAA<T, TCompare>::lowest() noexcept
22 {
23  return (T*)InternalLowest();
24 }
25 
26 template <typename T, typename TCompare>
27 inline const T* BinTreeAA<T, TCompare>::lowest() const noexcept
28 {
29  return InternalLowest();
30 }
31 
32 template <typename T, typename TCompare>
33 inline const T* BinTreeAA<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* BinTreeAA<T, TCompare>::highest() noexcept
44 {
45  return (T*)InternalHighest();
46 }
47 
48 template <typename T, typename TCompare>
49 inline const T* BinTreeAA<T, TCompare>::highest() const noexcept
50 {
51  return InternalHighest();
52 }
53 
54 template <typename T, typename TCompare>
55 inline const T* BinTreeAA<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 BinTreeAA<T, TCompare>::iterator BinTreeAA<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 BinTreeAA<T, TCompare>::const_iterator BinTreeAA<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* BinTreeAA<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>
186 {
187  return const_iterator(this, InternalLowerBound(item));
188 }
189 
190 template <typename T, typename TCompare>
191 inline const T* BinTreeAA<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>
230 {
231  return const_iterator(this, InternalUpperBound(item));
232 }
233 
234 template <typename T, typename TCompare>
235 inline const T* BinTreeAA<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 BinTreeAA<T, TCompare>::iterator, bool> BinTreeAA<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 BinTreeAA<T, TCompare>::iterator, bool> BinTreeAA<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  // Balance the binary tree
317  T* node = &item;
318  node->level = 1;
319  while (node->parent != nullptr)
320  {
321  node = node->parent;
322  if (node->level != ((node->left != nullptr) ? node->left->level + 1 : 1))
323  {
324  Skew(node);
325  if ((node->right == nullptr) || (node->level != node->right->level))
326  node = node->parent;
327  }
328 
329  if (!Split(node->parent))
330  break;
331  }
332 
333  return std::make_pair(iterator(this, &item), true);
334 }
335 
336 template <typename T, typename TCompare>
337 inline T* BinTreeAA<T, TCompare>::erase(const T& item) noexcept
338 {
339  return erase(find(item)).operator->();
340 }
341 
342 template <typename T, typename TCompare>
344 {
345  T* result = ((iterator&)it).operator->();
346  if (result == nullptr)
347  return end();
348 
349  T* node = result;
350  T* temp;
351 
352  if (result->left != nullptr)
353  {
354  node = result->left;
355  while (node->right != nullptr)
356  node = node->right;
357  }
358  else if (result->right != nullptr)
359  node = result->right;
360 
361  temp = ((node->parent == result) ? node : node->parent);
362  if (node->parent != nullptr)
363  {
364  if (node->parent->left == node)
365  node->parent->left = nullptr;
366  else
367  node->parent->right = nullptr;
368  }
369  else
370  _root = nullptr;
371 
372  if (result != node)
373  {
374  if (result->parent != nullptr)
375  {
376  if (result->parent->left == result)
377  result->parent->left = node;
378  else
379  result->parent->right = node;
380  }
381  else
382  _root = node;
383 
384  node->parent = result->parent;
385  if (result->left != nullptr)
386  result->left->parent = node;
387  node->left = result->left;
388  if (result->right != nullptr)
389  result->right->parent = node;
390  node->right = result->right;
391 
392  // Copy levels
393  node->level = result->level;
394  }
395 
396  while (temp != nullptr)
397  {
398  if (temp->level > ((temp->left != nullptr) ? temp->left->level + 1 : 1))
399  {
400  temp->level = temp->level - 1;
401  if (Split(temp))
402  {
403  if (Split(temp))
404  Skew(temp->parent->parent);
405  break;
406  }
407  }
408  else if (temp->level <= ((temp->right != nullptr) ? temp->right->level + 1 : 1))
409  break;
410  else
411  {
412  Skew(temp);
413  if (temp->level > temp->parent->level)
414  {
415  Skew(temp);
416  Split(temp->parent->parent);
417  break;
418  }
419  temp = temp->parent;
420  }
421  temp = temp->parent;
422  }
423 
424  result->parent = nullptr;
425  result->left = nullptr;
426  result->right = nullptr;
427  --_size;
428  return iterator(this, result);
429 }
430 
431 template <typename T, typename TCompare>
432 inline void BinTreeAA<T, TCompare>::Skew(T* node)
433 {
434  if (node == nullptr)
435  return;
436 
437  T* current = node->left;
438  if (node->parent != nullptr)
439  {
440  if (node->parent->left == node)
441  node->parent->left = current;
442  else
443  node->parent->right = current;
444  }
445  else
446  _root = current;
447  current->parent = node->parent;
448  node->parent = current;
449 
450  node->left = current->right;
451  if (node->left != nullptr)
452  node->left->parent = node;
453  current->right = node;
454 
455  if (node->left != nullptr)
456  node->level = node->left->level + 1;
457  else
458  node->level = 1;
459 }
460 
461 template <typename T, typename TCompare>
462 inline bool BinTreeAA<T, TCompare>::Split(T* node)
463 {
464  if (node == nullptr)
465  return false;
466 
467  T* current = node->right;
468  if ((current != nullptr) && (current->right != nullptr) && (current->right->level == node->level))
469  {
470  if (node->parent != nullptr)
471  {
472  if (node->parent->left == node)
473  node->parent->left = current;
474  else
475  node->parent->right = current;
476  }
477  else
478  _root = current;
479  current->parent = node->parent;
480  node->parent = current;
481 
482  node->right = current->left;
483  if (node->right != nullptr)
484  node->right->parent = node;
485  current->left = node;
486  current->level = node->level + 1;
487  return true;
488  }
489 
490  return false;
491 }
492 
493 template <typename T, typename TCompare>
494 inline void BinTreeAA<T, TCompare>::clear() noexcept
495 {
496  _size = 0;
497  _root = nullptr;
498 }
499 
500 template <typename T, typename TCompare>
501 inline void BinTreeAA<T, TCompare>::swap(BinTreeAA& bintree) noexcept
502 {
503  using std::swap;
504  swap(_compare, bintree._compare);
505  swap(_size, bintree._size);
506  swap(_root, bintree._root);
507 }
508 
509 template <typename T, typename TCompare>
510 inline void swap(BinTreeAA<T, TCompare>& bintree1, BinTreeAA<T, TCompare>& bintree2) noexcept
511 {
512  bintree1.swap(bintree2);
513 }
514 
515 } // namespace CppCommon
Intrusive balanced A.Andersson binary tree container.
Definition: bintree_aa.h:60
void clear() noexcept
Clear the binary tree.
Definition: bintree_aa.inl:494
const_reverse_iterator crend() const noexcept
Definition: bintree_aa.inl:131
void swap(BinTreeAA &bintree) noexcept
Swap two instances.
Definition: bintree_aa.inl:501
iterator begin() noexcept
Get the begin binary tree iterator.
Definition: bintree_aa.inl:65
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_aa.inl:223
BinTreeAA(const TCompare &compare=TCompare()) noexcept
Definition: bintree_aa.h:87
reverse_iterator rend() noexcept
Get the reverse end binary tree iterator.
Definition: bintree_aa.inl:119
const_reverse_iterator crbegin() const noexcept
Definition: bintree_aa.inl:113
iterator end() noexcept
Get the end binary tree iterator.
Definition: bintree_aa.inl:83
const_iterator cbegin() const noexcept
Definition: bintree_aa.inl:77
T * lowest() noexcept
Get the lowest binary tree item.
Definition: bintree_aa.inl:21
const_iterator cend() const noexcept
Definition: bintree_aa.inl:95
T * highest() noexcept
Get the highest binary tree item.
Definition: bintree_aa.inl:43
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_aa.inl:137
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_aa.inl:179
T * erase(const T &item) noexcept
Erase the given item from the binary tree.
Definition: bintree_aa.inl:337
std::pair< iterator, bool > insert(T &item) noexcept
Insert a new item into the binary tree.
Definition: bintree_aa.inl:260
reverse_iterator rbegin() noexcept
Get the reverse begin binary tree iterator.
Definition: bintree_aa.inl:101
Intrusive binary tree constant iterator.
Definition: bintree.h:335
Intrusive binary tree constant reverse iterator.
Definition: bintree.h:448
Intrusive binary tree iterator.
Definition: bintree.h:279
Intrusive binary tree reverse iterator.
Definition: bintree.h:392
C++ Common project definitions.
Definition: token_bucket.h:15
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition: filecache.inl:23
void swap(BinTreeAA< T, TCompare > &bintree1, BinTreeAA< T, TCompare > &bintree2) noexcept
Definition: bintree_aa.inl:510