2
2
3
3
#include " interval_tree_fwd.hpp"
4
4
#include " interval_types.hpp"
5
+ #include " tree_hooks.hpp"
5
6
6
7
#include < string>
7
8
#include < memory>
@@ -25,12 +26,13 @@ namespace lib_interval_tree
25
26
// ############################################################################################################
26
27
using default_interval_value_type = int ;
27
28
// ############################################################################################################
28
- template <typename numerical_type, typename interval_kind_ = closed>
29
+ template <typename numerical_type, typename interval_kind_ = closed, typename tree_hooks = hooks::regular >
29
30
struct interval
30
31
{
31
32
public:
32
33
using value_type = numerical_type;
33
34
using interval_kind = interval_kind_;
35
+ friend tree_hooks;
34
36
35
37
/* *
36
38
* Constructs an interval. low MUST be smaller than high.
@@ -178,7 +180,7 @@ namespace lib_interval_tree
178
180
/* *
179
181
* Creates a safe interval that puts the lower bound left automatically.
180
182
*/
181
- template <typename numerical_type, typename interval_kind_ = closed>
183
+ template <typename numerical_type, typename interval_kind_ = closed, typename tree_hooks = hooks::regular >
182
184
#if __cplusplus >= 201703L
183
185
constexpr
184
186
#endif
@@ -190,7 +192,8 @@ namespace lib_interval_tree
190
192
// ############################################################################################################
191
193
template <
192
194
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>
194
197
class node
195
198
{
196
199
private:
@@ -199,13 +202,15 @@ namespace lib_interval_tree
199
202
public:
200
203
using interval_type = interval_type_;
201
204
using value_type = numerical_type;
205
+ using tree_hooks_type = tree_hooks;
206
+ friend tree_hooks_type;
202
207
203
208
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 >;
209
214
210
215
template <typename T>
211
216
friend void increment (T& iter);
@@ -344,9 +349,11 @@ namespace lib_interval_tree
344
349
class basic_interval_tree_iterator : public std ::forward_iterator_tag
345
350
{
346
351
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;
348
354
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>;
350
357
using value_type = node_type;
351
358
352
359
using node_ptr_t = typename std::conditional<
@@ -416,16 +423,20 @@ namespace lib_interval_tree
416
423
// ############################################################################################################
417
424
template <typename node_type, bool reverse>
418
425
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 *>
420
429
{
421
430
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>;
423
433
using iterator_base = basic_interval_tree_iterator<node_type, tree_type const *>;
424
434
using value_type = typename iterator_base::value_type;
425
435
using iterator_base::node_;
426
436
using iterator_base::owner_;
427
437
428
438
friend tree_type;
439
+ friend tree_hooks_type;
429
440
430
441
public:
431
442
~const_interval_tree_iterator () = default ;
@@ -519,16 +530,20 @@ namespace lib_interval_tree
519
530
// ############################################################################################################
520
531
template <typename node_type, bool reverse = false >
521
532
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>*>
523
536
{
524
537
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>;
526
540
using iterator_base = basic_interval_tree_iterator<node_type, tree_type*>;
527
541
using value_type = typename iterator_base::value_type;
528
542
using iterator_base::node_;
529
543
using iterator_base::owner_;
530
544
531
545
friend tree_type;
546
+ friend tree_hooks_type;
532
547
533
548
public:
534
549
~interval_tree_iterator () = default ;
@@ -685,25 +700,40 @@ namespace lib_interval_tree
685
700
}
686
701
}
687
702
// ############################################################################################################
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
690
705
{
691
706
public:
692
707
using interval_type = IntervalT;
708
+ using tree_hooks_type = tree_hooks;
693
709
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:
695
718
using iterator = interval_tree_iterator<node_type, false >;
696
719
using const_iterator = const_interval_tree_iterator<node_type, false >;
697
720
using reverse_iterator = interval_tree_iterator<node_type, true >;
698
721
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>;
701
730
702
731
public:
703
732
friend const_interval_tree_iterator<node_type, true >;
704
733
friend const_interval_tree_iterator<node_type, false >;
705
734
friend interval_tree_iterator<node_type, true >;
706
735
friend interval_tree_iterator<node_type, false >;
736
+ friend tree_hooks;
707
737
708
738
template <typename T>
709
739
friend void increment (T& iter);
@@ -718,6 +748,7 @@ namespace lib_interval_tree
718
748
719
749
~interval_tree ()
720
750
{
751
+ tree_hooks::template on_destroy<this_type>(*this );
721
752
clear ();
722
753
}
723
754
@@ -815,6 +846,7 @@ namespace lib_interval_tree
815
846
816
847
insert_fixup (z);
817
848
recalculate_max (z);
849
+
818
850
++size_;
819
851
return {z, this };
820
852
}
@@ -1331,6 +1363,7 @@ namespace lib_interval_tree
1331
1363
ComparatorFunctionT const & compare
1332
1364
)
1333
1365
{
1366
+ std::decay_t <ThisType>::tree_hooks_type::template on_find_all<this_type>(*self, ptr, ival, compare);
1334
1367
if (compare (*ptr->interval (), ival))
1335
1368
{
1336
1369
if (!on_find (IteratorT{ptr, self}))
@@ -1359,6 +1392,7 @@ namespace lib_interval_tree
1359
1392
template <typename ComparatorFunctionT>
1360
1393
node_type* find_i (node_type* ptr, interval_type const & ival, ComparatorFunctionT const & compare) const
1361
1394
{
1395
+ tree_hooks::template on_find<this_type>(*this , ptr, ival, compare);
1362
1396
if (compare (*ptr->interval (), ival))
1363
1397
return ptr;
1364
1398
else
@@ -1394,6 +1428,7 @@ namespace lib_interval_tree
1394
1428
template <bool Exclusive>
1395
1429
node_type* overlap_find_i (node_type* ptr, interval_type const & ival) const
1396
1430
{
1431
+ tree_hooks::template on_overlap_find<this_type>(*this , ptr, ival);
1397
1432
#if __cplusplus >= 201703L
1398
1433
if constexpr (Exclusive)
1399
1434
#else
@@ -1420,6 +1455,7 @@ namespace lib_interval_tree
1420
1455
FunctionT const & on_find
1421
1456
)
1422
1457
{
1458
+ std::decay_t <ThisType>::tree_hooks_type::template on_overlap_find_all<ThisType>(*self, ptr, ival);
1423
1459
#if __cplusplus >= 201703L
1424
1460
if constexpr (Exclusive)
1425
1461
#else
@@ -1505,30 +1541,6 @@ namespace lib_interval_tree
1505
1541
return y;
1506
1542
}
1507
1543
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
-
1532
1544
/* *
1533
1545
* Get leftest of x.
1534
1546
*/
@@ -1610,6 +1622,8 @@ namespace lib_interval_tree
1610
1622
1611
1623
void recalculate_max (node_type* reacalculation_root)
1612
1624
{
1625
+ tree_hooks::template on_before_recalculate_max<this_type>(*this , reacalculation_root);
1626
+
1613
1627
auto * p = reacalculation_root;
1614
1628
while (p && p->max_ <= reacalculation_root->max_ )
1615
1629
{
@@ -1619,10 +1633,14 @@ namespace lib_interval_tree
1619
1633
p->max_ = p->right_ ->max_ ;
1620
1634
p = p->parent_ ;
1621
1635
}
1636
+
1637
+ tree_hooks::template on_after_recalculate_max<this_type>(*this , reacalculation_root);
1622
1638
}
1623
1639
1624
1640
void insert_fixup (node_type* z)
1625
1641
{
1642
+ tree_hooks::template on_before_insert_fixup<this_type>(*this , z);
1643
+
1626
1644
while (z->parent_ && z->parent_ ->color_ == rb_color::red)
1627
1645
{
1628
1646
if (!z->parent_ ->parent_ )
@@ -1673,10 +1691,14 @@ namespace lib_interval_tree
1673
1691
}
1674
1692
}
1675
1693
root_->color_ = rb_color::black;
1694
+
1695
+ tree_hooks::template on_after_insert_fixup<this_type>(*this , z);
1676
1696
}
1677
1697
1678
1698
void erase_fixup (node_type* x, node_type* x_parent, bool y_is_left)
1679
1699
{
1700
+ tree_hooks::template on_before_erase_fixup<this_type>(*this , x, x_parent, y_is_left);
1701
+
1680
1702
while (x != root_ && x->color_ == rb_color::black)
1681
1703
{
1682
1704
node_type* w;
@@ -1759,14 +1781,16 @@ namespace lib_interval_tree
1759
1781
}
1760
1782
1761
1783
x->color_ = rb_color::black;
1784
+
1785
+ tree_hooks::template on_after_erase_fixup<this_type>(*this , x, x_parent, y_is_left);
1762
1786
}
1763
1787
1764
1788
private:
1765
1789
node_type* root_;
1766
1790
size_type size_;
1767
1791
};
1768
1792
// ############################################################################################################
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 >;
1771
1795
// ############################################################################################################
1772
1796
}
0 commit comments