@@ -200,8 +200,10 @@ namespace lib_interval_tree
200
200
201
201
public:
202
202
friend lib_interval_tree::interval_tree <interval_type>;
203
- friend lib_interval_tree::const_interval_tree_iterator <node <numerical_type, interval_type> >;
204
- friend lib_interval_tree::interval_tree_iterator <node <numerical_type, interval_type> >;
203
+ friend lib_interval_tree::const_interval_tree_iterator <node <numerical_type, interval_type>, true >;
204
+ friend lib_interval_tree::const_interval_tree_iterator <node <numerical_type, interval_type>, false >;
205
+ friend lib_interval_tree::interval_tree_iterator <node <numerical_type, interval_type>, true >;
206
+ friend lib_interval_tree::interval_tree_iterator <node <numerical_type, interval_type>, false >;
205
207
206
208
public:
207
209
node (node* parent, interval_type interval)
@@ -404,7 +406,12 @@ namespace lib_interval_tree
404
406
owner_type owner_;
405
407
};
406
408
// ############################################################################################################
407
- template <typename node_type>
409
+ template <typename T>
410
+ inline void increment (T& iter);
411
+ template <typename T>
412
+ inline void increment_reverse (T& iter);
413
+ // ############################################################################################################
414
+ template <typename node_type, bool reverse>
408
415
class const_interval_tree_iterator
409
416
: public basic_interval_tree_iterator <node_type,
410
417
interval_tree <typename node_type::interval_type> const *>
@@ -425,37 +432,19 @@ namespace lib_interval_tree
425
432
const_interval_tree_iterator& operator =(const_interval_tree_iterator const &) = default ;
426
433
const_interval_tree_iterator& operator =(const_interval_tree_iterator&&) noexcept = default ;
427
434
435
+ friend void increment<const_interval_tree_iterator<node_type, reverse>>(const_interval_tree_iterator<node_type, reverse>& iter);
436
+ friend void increment_reverse<const_interval_tree_iterator<node_type, reverse>>(const_interval_tree_iterator<node_type, reverse>& iter);
437
+
428
438
const_interval_tree_iterator& operator ++()
429
439
{
430
- if (!node_)
431
- {
432
- node_ = owner_->root_ ;
433
-
434
- if (!node_)
435
- return *this ;
436
-
437
- while (node_->left_ )
438
- node_ = node_->left_ ;
439
- }
440
-
441
- if (node_->right_ )
442
- {
443
- node_ = node_->right_ ;
444
-
445
- while (node_->left_ )
446
- node_ = node_->left_ ;
447
- }
440
+ #if __cplusplus >= 201703L
441
+ if constexpr (reverse)
442
+ #else
443
+ if (reverse)
444
+ #endif
445
+ increment_reverse (*this );
448
446
else
449
- {
450
- auto * parent = node_->parent_ ;
451
- while (parent != nullptr && node_ == parent->right_ )
452
- {
453
- node_ = parent;
454
- parent = parent->parent_ ;
455
- }
456
- node_ = parent;
457
- }
458
-
447
+ increment (*this );
459
448
return *this ;
460
449
}
461
450
@@ -525,7 +514,7 @@ namespace lib_interval_tree
525
514
}
526
515
};
527
516
// ############################################################################################################
528
- template <typename node_type>
517
+ template <typename node_type, bool reverse = false >
529
518
class interval_tree_iterator
530
519
: public basic_interval_tree_iterator <node_type,
531
520
interval_tree <typename node_type::interval_type>*>
@@ -546,37 +535,19 @@ namespace lib_interval_tree
546
535
interval_tree_iterator& operator =(interval_tree_iterator const &) = default ;
547
536
interval_tree_iterator& operator =(interval_tree_iterator&&) noexcept = default ;
548
537
538
+ friend void increment<interval_tree_iterator<node_type, reverse>>(interval_tree_iterator<node_type, reverse>& iter);
539
+ friend void increment_reverse<interval_tree_iterator<node_type, reverse>>(interval_tree_iterator<node_type, reverse>& iter);
540
+
549
541
interval_tree_iterator& operator ++()
550
542
{
551
- if (!node_)
552
- {
553
- node_ = owner_->root_ ;
554
-
555
- if (!node_)
556
- return *this ;
557
-
558
- while (node_->left_ )
559
- node_ = node_->left_ ;
560
- }
561
-
562
- if (node_->right_ )
563
- {
564
- node_ = node_->right_ ;
565
-
566
- while (node_->left_ )
567
- node_ = node_->left_ ;
568
- }
543
+ #if __cplusplus >= 201703L
544
+ if constexpr (reverse)
545
+ #else
546
+ if (reverse)
547
+ #endif
548
+ increment_reverse (*this );
569
549
else
570
- {
571
- auto * parent = node_->parent_ ;
572
- while (parent != nullptr && node_ == parent->right_ )
573
- {
574
- node_ = parent;
575
- parent = parent->parent_ ;
576
- }
577
- node_ = parent;
578
- }
579
-
550
+ increment (*this );
580
551
return *this ;
581
552
}
582
553
@@ -645,6 +616,71 @@ namespace lib_interval_tree
645
616
{
646
617
}
647
618
};
619
+ // ############################################################################################################
620
+ template <typename T>
621
+ inline void increment (T& iter)
622
+ {
623
+ if (!iter.node_ )
624
+ {
625
+ iter.node_ = iter.owner_ ->root_ ;
626
+
627
+ if (!iter.node_ )
628
+ return ;
629
+
630
+ while (iter.node_ ->left_ )
631
+ iter.node_ = iter.node_ ->left_ ;
632
+ }
633
+
634
+ if (iter.node_ ->right_ )
635
+ {
636
+ iter.node_ = iter.node_ ->right_ ;
637
+
638
+ while (iter.node_ ->left_ )
639
+ iter.node_ = iter.node_ ->left_ ;
640
+ }
641
+ else
642
+ {
643
+ auto * parent = iter.node_ ->parent_ ;
644
+ while (parent != nullptr && iter.node_ == parent->right_ )
645
+ {
646
+ iter.node_ = parent;
647
+ parent = parent->parent_ ;
648
+ }
649
+ iter.node_ = parent;
650
+ }
651
+ }
652
+ template <typename T>
653
+ inline void increment_reverse (T& iter)
654
+ {
655
+ if (!iter.node_ )
656
+ {
657
+ iter.node_ = iter.owner_ ->root_ ;
658
+
659
+ if (!iter.node_ )
660
+ return ;
661
+
662
+ while (iter.node_ ->right_ )
663
+ iter.node_ = iter.node_ ->right_ ;
664
+ }
665
+
666
+ if (iter.node_ ->left_ )
667
+ {
668
+ iter.node_ = iter.node_ ->left_ ;
669
+
670
+ while (iter.node_ ->right_ )
671
+ iter.node_ = iter.node_ ->right_ ;
672
+ }
673
+ else
674
+ {
675
+ auto * parent = iter.node_ ->parent_ ;
676
+ while (parent != nullptr && iter.node_ == parent->left_ )
677
+ {
678
+ iter.node_ = parent;
679
+ parent = parent->parent_ ;
680
+ }
681
+ iter.node_ = parent;
682
+ }
683
+ }
648
684
// ############################################################################################################
649
685
template <typename IntervalT = interval <int , closed>>
650
686
class interval_tree
@@ -653,14 +689,18 @@ namespace lib_interval_tree
653
689
using interval_type = IntervalT;
654
690
using value_type = typename interval_type::value_type;
655
691
using node_type = node <value_type, interval_type>;
656
- using iterator = interval_tree_iterator <node_type>;
657
- using const_iterator = const_interval_tree_iterator <node_type>;
692
+ using iterator = interval_tree_iterator <node_type, false >;
693
+ using const_iterator = const_interval_tree_iterator <node_type, false >;
694
+ using reverse_iterator = interval_tree_iterator <node_type, true >;
695
+ using const_reverse_iterator = const_interval_tree_iterator <node_type, true >;
658
696
using size_type = long long ;
659
697
using this_type = interval_tree<interval_type>;
660
698
661
699
public:
662
- friend const_interval_tree_iterator <node_type>;
663
- friend interval_tree_iterator <node_type>;
700
+ friend const_interval_tree_iterator <node_type, true >;
701
+ friend const_interval_tree_iterator <node_type, false >;
702
+ friend interval_tree_iterator <node_type, true >;
703
+ friend interval_tree_iterator <node_type, false >;
664
704
665
705
public:
666
706
interval_tree ()
@@ -1124,6 +1164,23 @@ namespace lib_interval_tree
1124
1164
return {nullptr , this };
1125
1165
}
1126
1166
1167
+ reverse_iterator rbegin ()
1168
+ {
1169
+ if (!root_)
1170
+ return {nullptr , this };
1171
+
1172
+ auto * iter = root_;
1173
+
1174
+ while (iter->right_ )
1175
+ iter = iter->right_ ;
1176
+
1177
+ return {iter, this };
1178
+ }
1179
+ reverse_iterator rend ()
1180
+ {
1181
+ return {nullptr , this };
1182
+ }
1183
+
1127
1184
const_iterator cbegin () const
1128
1185
{
1129
1186
if (!root_)
@@ -1149,6 +1206,31 @@ namespace lib_interval_tree
1149
1206
return cend ();
1150
1207
}
1151
1208
1209
+ const_reverse_iterator crbegin () const
1210
+ {
1211
+ if (!root_)
1212
+ return {nullptr , this };
1213
+
1214
+ auto * iter = root_;
1215
+
1216
+ while (iter->right_ )
1217
+ iter = iter->right_ ;
1218
+
1219
+ return const_reverse_iterator{iter, this };
1220
+ }
1221
+ const_reverse_iterator crend () const
1222
+ {
1223
+ return const_reverse_iterator{nullptr , this };
1224
+ }
1225
+ const_reverse_iterator rbegin () const
1226
+ {
1227
+ return crbegin ();
1228
+ }
1229
+ const_reverse_iterator rend () const
1230
+ {
1231
+ return crend ();
1232
+ }
1233
+
1152
1234
/* *
1153
1235
* Returns wether or not the tree is empty
1154
1236
*/
0 commit comments