22
33#include " interval_tree_fwd.hpp"
44#include " interval_types.hpp"
5+ #include " tree_hooks.hpp"
56
67#include < string>
78#include < memory>
@@ -25,12 +26,13 @@ namespace lib_interval_tree
2526 // ############################################################################################################
2627 using default_interval_value_type = int ;
2728 // ############################################################################################################
28- template <typename numerical_type, typename interval_kind_ = closed>
29+ template <typename numerical_type, typename interval_kind_ = closed, typename tree_hooks = hooks::regular >
2930 struct interval
3031 {
3132 public:
3233 using value_type = numerical_type;
3334 using interval_kind = interval_kind_;
35+ friend tree_hooks;
3436
3537 /* *
3638 * Constructs an interval. low MUST be smaller than high.
@@ -178,7 +180,7 @@ namespace lib_interval_tree
178180 /* *
179181 * Creates a safe interval that puts the lower bound left automatically.
180182 */
181- template <typename numerical_type, typename interval_kind_ = closed>
183+ template <typename numerical_type, typename interval_kind_ = closed, typename tree_hooks = hooks::regular >
182184#if __cplusplus >= 201703L
183185 constexpr
184186#endif
@@ -190,7 +192,8 @@ namespace lib_interval_tree
190192 // ############################################################################################################
191193 template <
192194 typename numerical_type = default_interval_value_type,
193- typename interval_type_ = interval<numerical_type, closed>>
195+ typename interval_type_ = interval<numerical_type, closed, hooks::regular>,
196+ typename tree_hooks = hooks::regular>
194197 class node
195198 {
196199 private:
@@ -199,13 +202,15 @@ namespace lib_interval_tree
199202 public:
200203 using interval_type = interval_type_;
201204 using value_type = numerical_type;
205+ using tree_hooks_type = tree_hooks;
206+ friend tree_hooks_type;
202207
203208 public:
204- friend lib_interval_tree::interval_tree<interval_type>;
205- friend lib_interval_tree::const_interval_tree_iterator<node<numerical_type, interval_type>, true >;
206- friend lib_interval_tree::const_interval_tree_iterator<node<numerical_type, interval_type>, false >;
207- friend lib_interval_tree::interval_tree_iterator<node<numerical_type, interval_type>, true >;
208- friend lib_interval_tree::interval_tree_iterator<node<numerical_type, interval_type>, false >;
209+ friend lib_interval_tree::interval_tree<interval_type, tree_hooks >;
210+ friend lib_interval_tree::const_interval_tree_iterator<node<numerical_type, interval_type, tree_hooks >, true >;
211+ friend lib_interval_tree::const_interval_tree_iterator<node<numerical_type, interval_type, tree_hooks >, false >;
212+ friend lib_interval_tree::interval_tree_iterator<node<numerical_type, interval_type, tree_hooks >, true >;
213+ friend lib_interval_tree::interval_tree_iterator<node<numerical_type, interval_type, tree_hooks >, false >;
209214
210215 template <typename T>
211216 friend void increment (T& iter);
@@ -344,9 +349,11 @@ namespace lib_interval_tree
344349 class basic_interval_tree_iterator : public std ::forward_iterator_tag
345350 {
346351 public:
347- friend interval_tree<typename node_type::interval_type>;
352+ friend interval_tree<typename node_type::interval_type, typename node_type::tree_hooks_type>;
353+ friend typename node_type::tree_hooks_type;
348354
349- using tree_type = interval_tree<typename node_type::interval_type>;
355+ using tree_hooks_type = typename node_type::tree_hooks_type;
356+ using tree_type = interval_tree<typename node_type::interval_type, tree_hooks_type>;
350357 using value_type = node_type;
351358
352359 using node_ptr_t = typename std::conditional<
@@ -416,16 +423,20 @@ namespace lib_interval_tree
416423 // ############################################################################################################
417424 template <typename node_type, bool reverse>
418425 class const_interval_tree_iterator
419- : public basic_interval_tree_iterator<node_type, interval_tree<typename node_type::interval_type> const *>
426+ : public basic_interval_tree_iterator<
427+ node_type,
428+ interval_tree<typename node_type::interval_type, typename node_type::tree_hooks_type> const *>
420429 {
421430 public:
422- using tree_type = interval_tree<typename node_type::interval_type>;
431+ using tree_hooks_type = typename node_type::tree_hooks_type;
432+ using tree_type = interval_tree<typename node_type::interval_type, tree_hooks_type>;
423433 using iterator_base = basic_interval_tree_iterator<node_type, tree_type const *>;
424434 using value_type = typename iterator_base::value_type;
425435 using iterator_base::node_;
426436 using iterator_base::owner_;
427437
428438 friend tree_type;
439+ friend tree_hooks_type;
429440
430441 public:
431442 ~const_interval_tree_iterator () = default ;
@@ -519,16 +530,20 @@ namespace lib_interval_tree
519530 // ############################################################################################################
520531 template <typename node_type, bool reverse = false >
521532 class interval_tree_iterator
522- : public basic_interval_tree_iterator<node_type, interval_tree<typename node_type::interval_type>*>
533+ : public basic_interval_tree_iterator<
534+ node_type,
535+ interval_tree<typename node_type::interval_type, typename node_type::tree_hooks_type>*>
523536 {
524537 public:
525- using tree_type = interval_tree<typename node_type::interval_type>;
538+ using tree_hooks_type = typename node_type::tree_hooks_type;
539+ using tree_type = interval_tree<typename node_type::interval_type, tree_hooks_type>;
526540 using iterator_base = basic_interval_tree_iterator<node_type, tree_type*>;
527541 using value_type = typename iterator_base::value_type;
528542 using iterator_base::node_;
529543 using iterator_base::owner_;
530544
531545 friend tree_type;
546+ friend tree_hooks_type;
532547
533548 public:
534549 ~interval_tree_iterator () = default ;
@@ -685,25 +700,40 @@ namespace lib_interval_tree
685700 }
686701 }
687702 // ############################################################################################################
688- template <typename IntervalT = interval<int , closed>>
689- class interval_tree
703+ template <typename IntervalT = interval<int , closed>, typename tree_hooks = hooks::regular >
704+ class interval_tree : public tree_hooks ::hook_state
690705 {
691706 public:
692707 using interval_type = IntervalT;
708+ using tree_hooks_type = tree_hooks;
693709 using value_type = typename interval_type::value_type;
694- using node_type = node<value_type, interval_type>;
710+
711+ // Node type:
712+ using node_type = std::conditional_t <
713+ std::is_same_v<typename tree_hooks::node_type, void >,
714+ node<value_type, interval_type, tree_hooks>,
715+ typename tree_hooks::node_type>;
716+
717+ // Iterators:
695718 using iterator = interval_tree_iterator<node_type, false >;
696719 using const_iterator = const_interval_tree_iterator<node_type, false >;
697720 using reverse_iterator = interval_tree_iterator<node_type, true >;
698721 using const_reverse_iterator = const_interval_tree_iterator<node_type, true >;
699- using size_type = long long ;
700- using this_type = interval_tree<interval_type>;
722+
723+ // Size type:
724+ using size_type = std::conditional_t <
725+ std::is_same_v<typename tree_hooks::size_type, void >,
726+ long long ,
727+ typename tree_hooks::size_type>;
728+
729+ using this_type = interval_tree<interval_type, tree_hooks>;
701730
702731 public:
703732 friend const_interval_tree_iterator<node_type, true >;
704733 friend const_interval_tree_iterator<node_type, false >;
705734 friend interval_tree_iterator<node_type, true >;
706735 friend interval_tree_iterator<node_type, false >;
736+ friend tree_hooks;
707737
708738 template <typename T>
709739 friend void increment (T& iter);
@@ -718,6 +748,7 @@ namespace lib_interval_tree
718748
719749 ~interval_tree ()
720750 {
751+ tree_hooks::template on_destroy<this_type>(*this );
721752 clear ();
722753 }
723754
@@ -815,6 +846,7 @@ namespace lib_interval_tree
815846
816847 insert_fixup (z);
817848 recalculate_max (z);
849+
818850 ++size_;
819851 return {z, this };
820852 }
@@ -1331,6 +1363,7 @@ namespace lib_interval_tree
13311363 ComparatorFunctionT const & compare
13321364 )
13331365 {
1366+ std::decay_t <ThisType>::tree_hooks_type::template on_find_all<this_type>(*self, ptr, ival, compare);
13341367 if (compare (*ptr->interval (), ival))
13351368 {
13361369 if (!on_find (IteratorT{ptr, self}))
@@ -1359,6 +1392,7 @@ namespace lib_interval_tree
13591392 template <typename ComparatorFunctionT>
13601393 node_type* find_i (node_type* ptr, interval_type const & ival, ComparatorFunctionT const & compare) const
13611394 {
1395+ tree_hooks::template on_find<this_type>(*this , ptr, ival, compare);
13621396 if (compare (*ptr->interval (), ival))
13631397 return ptr;
13641398 else
@@ -1394,6 +1428,7 @@ namespace lib_interval_tree
13941428 template <bool Exclusive>
13951429 node_type* overlap_find_i (node_type* ptr, interval_type const & ival) const
13961430 {
1431+ tree_hooks::template on_overlap_find<this_type>(*this , ptr, ival);
13971432#if __cplusplus >= 201703L
13981433 if constexpr (Exclusive)
13991434#else
@@ -1420,6 +1455,7 @@ namespace lib_interval_tree
14201455 FunctionT const & on_find
14211456 )
14221457 {
1458+ std::decay_t <ThisType>::tree_hooks_type::template on_overlap_find_all<ThisType>(*self, ptr, ival);
14231459#if __cplusplus >= 201703L
14241460 if constexpr (Exclusive)
14251461#else
@@ -1505,30 +1541,6 @@ namespace lib_interval_tree
15051541 return y;
15061542 }
15071543
1508- bool is_descendant (iterator par, iterator desc)
1509- {
1510- auto p = desc->parent_ ;
1511- for (; p && p != par.node_ ; p = p->parent_ )
1512- {}
1513- return p != nullptr ;
1514- }
1515-
1516- /* *
1517- * Set v inplace of u. Does not delete u.
1518- * Creates orphaned nodes. A transplant call must be succeeded by delete calls.
1519- */
1520- void transplant (node_type* u, node_type* v)
1521- {
1522- if (u->is_root ())
1523- root_ = v;
1524- else if (u->is_left ())
1525- u->parent_ ->left_ = v;
1526- else
1527- u->parent_ ->right_ = v;
1528- if (v)
1529- v->parent_ = u->parent_ ;
1530- }
1531-
15321544 /* *
15331545 * Get leftest of x.
15341546 */
@@ -1610,6 +1622,8 @@ namespace lib_interval_tree
16101622
16111623 void recalculate_max (node_type* reacalculation_root)
16121624 {
1625+ tree_hooks::template on_before_recalculate_max<this_type>(*this , reacalculation_root);
1626+
16131627 auto * p = reacalculation_root;
16141628 while (p && p->max_ <= reacalculation_root->max_ )
16151629 {
@@ -1619,10 +1633,14 @@ namespace lib_interval_tree
16191633 p->max_ = p->right_ ->max_ ;
16201634 p = p->parent_ ;
16211635 }
1636+
1637+ tree_hooks::template on_after_recalculate_max<this_type>(*this , reacalculation_root);
16221638 }
16231639
16241640 void insert_fixup (node_type* z)
16251641 {
1642+ tree_hooks::template on_before_insert_fixup<this_type>(*this , z);
1643+
16261644 while (z->parent_ && z->parent_ ->color_ == rb_color::red)
16271645 {
16281646 if (!z->parent_ ->parent_ )
@@ -1673,10 +1691,14 @@ namespace lib_interval_tree
16731691 }
16741692 }
16751693 root_->color_ = rb_color::black;
1694+
1695+ tree_hooks::template on_after_insert_fixup<this_type>(*this , z);
16761696 }
16771697
16781698 void erase_fixup (node_type* x, node_type* x_parent, bool y_is_left)
16791699 {
1700+ tree_hooks::template on_before_erase_fixup<this_type>(*this , x, x_parent, y_is_left);
1701+
16801702 while (x != root_ && x->color_ == rb_color::black)
16811703 {
16821704 node_type* w;
@@ -1759,14 +1781,16 @@ namespace lib_interval_tree
17591781 }
17601782
17611783 x->color_ = rb_color::black;
1784+
1785+ tree_hooks::template on_after_erase_fixup<this_type>(*this , x, x_parent, y_is_left);
17621786 }
17631787
17641788 private:
17651789 node_type* root_;
17661790 size_type size_;
17671791 };
17681792 // ############################################################################################################
1769- template <typename T, typename Kind = closed>
1770- using interval_tree_t = interval_tree<interval<T, Kind>>;
1793+ template <typename T, typename Kind = closed, typename tree_hooks = hooks::regular >
1794+ using interval_tree_t = interval_tree<interval<T, Kind>, tree_hooks >;
17711795 // ############################################################################################################
17721796}
0 commit comments