CppCommon 1.0.5.0
C++ Common Library
Loading...
Searching...
No Matches
bintree.inl
Go to the documentation of this file.
1
9namespace CppCommon {
10
11template <typename T, typename TCompare>
12template <class InputIterator>
13inline 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
20template <typename T, typename TCompare>
21inline T* BinTree<T, TCompare>::lowest() noexcept
22{
23 return (T*)InternalLowest();
24}
25
26template <typename T, typename TCompare>
27inline const T* BinTree<T, TCompare>::lowest() const noexcept
28{
29 return InternalLowest();
30}
31
32template <typename T, typename TCompare>
33inline 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
42template <typename T, typename TCompare>
44{
45 return (T*)InternalHighest();
46}
47
48template <typename T, typename TCompare>
49inline const T* BinTree<T, TCompare>::highest() const noexcept
50{
51 return InternalHighest();
52}
53
54template <typename T, typename TCompare>
55inline 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
64template <typename T, typename TCompare>
66{
67 return iterator(this, lowest());
68}
69
70template <typename T, typename TCompare>
72{
73 return const_iterator(this, lowest());
74}
75
76template <typename T, typename TCompare>
78{
79 return const_iterator(this, lowest());
80}
81
82template <typename T, typename TCompare>
84{
85 return iterator(this, nullptr);
86}
87
88template <typename T, typename TCompare>
90{
91 return const_iterator(this, nullptr);
92}
93
94template <typename T, typename TCompare>
96{
97 return const_iterator(this, nullptr);
98}
99
100template <typename T, typename TCompare>
102{
103 return reverse_iterator(this, highest());
104}
105
106template <typename T, typename TCompare>
108{
109 return const_reverse_iterator(this, highest());
110}
111
112template <typename T, typename TCompare>
114{
115 return const_reverse_iterator(this, highest());
116}
117
118template <typename T, typename TCompare>
120{
121 return reverse_iterator(this, nullptr);
122}
123
124template <typename T, typename TCompare>
126{
127 return const_reverse_iterator(this, nullptr);
128}
129
130template <typename T, typename TCompare>
132{
133 return const_reverse_iterator(this, nullptr);
134}
135
136template <typename T, typename TCompare>
137inline typename BinTree<T, TCompare>::iterator BinTree<T, TCompare>::find(const T& item) noexcept
138{
139 return iterator(this, (T*)InternalFind(item));
140}
141
142template <typename T, typename TCompare>
143inline 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
148template <typename T, typename TCompare>
149inline 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
178template <typename T, typename TCompare>
180{
181 return iterator(this, (T*)InternalLowerBound(item));
182}
183
184template <typename T, typename TCompare>
186{
187 return const_iterator(this, InternalLowerBound(item));
188}
189
190template <typename T, typename TCompare>
191inline 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
222template <typename T, typename TCompare>
224{
225 return iterator(this, (T*)InternalUpperBound(item));
226}
227
228template <typename T, typename TCompare>
230{
231 return const_iterator(this, InternalUpperBound(item));
232}
233
234template <typename T, typename TCompare>
235inline 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
259template <typename T, typename TCompare>
260inline 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
265template <typename T, typename TCompare>
266inline 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
319template <typename T, typename TCompare>
320inline T* BinTree<T, TCompare>::erase(const T& item) noexcept
321{
322 return erase(find(item)).operator->();
323}
324
325template <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
398template <typename T, typename TCompare>
399inline void BinTree<T, TCompare>::clear() noexcept
400{
401 _size = 0;
402 _root = nullptr;
403}
404
405template <typename T, typename TCompare>
406inline 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
414template <typename T, typename TCompare>
415inline void swap(BinTree<T, TCompare>& bintree1, BinTree<T, TCompare>& bintree2) noexcept
416{
417 bintree1.swap(bintree2);
418}
419
420template <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
441template <class TContainer, typename T>
443{
444 BinTreeIterator<TContainer, T> result(*this);
445 operator++();
446 return result;
447}
448
449template <class TContainer, typename T>
451{
452 assert((_node != nullptr) && "Iterator must be valid!");
453
454 return *_node;
455}
456
457template <class TContainer, typename T>
462
463template <class TContainer, typename T>
465{
466 using std::swap;
467 swap(_container, it._container);
468 swap(_node, it._node);
469}
470
471template <class TContainer, typename T>
473{
474 it1.swap(it2);
475}
476
477template <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
498template <class TContainer, typename T>
500{
502 operator++();
503 return result;
504}
505
506template <class TContainer, typename T>
508{
509 assert((_node != nullptr) && "Iterator must be valid!");
510
511 return *_node;
512}
513
514template <class TContainer, typename T>
519
520template <class TContainer, typename T>
522{
523 using std::swap;
524 swap(_container, it._container);
525 swap(_node, it._node);
526}
527
528template <class TContainer, typename T>
530{
531 it1.swap(it2);
532}
533
534template <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
555template <class TContainer, typename T>
557{
559 operator++();
560 return result;
561}
562
563template <class TContainer, typename T>
565{
566 assert((_node != nullptr) && "Iterator must be valid!");
567
568 return *_node;
569}
570
571template <class TContainer, typename T>
576
577template <class TContainer, typename T>
579{
580 using std::swap;
581 swap(_container, it._container);
582 swap(_node, it._node);
583}
584
585template <class TContainer, typename T>
587{
588 it1.swap(it2);
589}
590
591template <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
612template <class TContainer, typename T>
619
620template <class TContainer, typename T>
622{
623 assert((_node != nullptr) && "Iterator must be valid!");
624
625 return *_node;
626}
627
628template <class TContainer, typename T>
633
634template <class TContainer, typename T>
636{
637 using std::swap;
638 swap(_container, it._container);
639 swap(_node, it._node);
640}
641
642template <class TContainer, typename T>
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
friend void swap(BinTreeConstIterator< UContainer, U > &it1, BinTreeConstIterator< UContainer, U > &it2) noexcept
const value_type * const_pointer
Definition bintree.h:342
const_reference operator*() const noexcept
Definition bintree.inl:507
Intrusive binary tree constant reverse iterator.
Definition bintree.h:448
BinTreeConstReverseIterator & operator++() noexcept
Definition bintree.inl:592
const_reference operator*() const noexcept
Definition bintree.inl:621
friend void swap(BinTreeConstReverseIterator< UContainer, U > &it1, BinTreeConstReverseIterator< UContainer, U > &it2) noexcept
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
const_reverse_iterator crbegin() const noexcept
Definition bintree.inl:113
friend void swap(BinTree< U, UCompare > &bintree1, BinTree< U, UCompare > &bintree2) noexcept
Intrusive binary tree iterator.
Definition bintree.h:279
reference operator*() noexcept
Definition bintree.inl:450
pointer operator->() noexcept
Definition bintree.inl:458
friend void swap(BinTreeIterator< UContainer, U > &it1, BinTreeIterator< UContainer, U > &it2) noexcept
BinTreeIterator & operator++() noexcept
Definition bintree.inl:421
Intrusive binary tree reverse iterator.
Definition bintree.h:392
pointer operator->() noexcept
Definition bintree.inl:572
reference operator*() noexcept
Definition bintree.inl:564
BinTreeReverseIterator & operator++() noexcept
Definition bintree.inl:535
friend void swap(BinTreeReverseIterator< UContainer, U > &it1, BinTreeReverseIterator< UContainer, U > &it2) noexcept
C++ Common project definitions.
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition filecache.inl:23