@@ -200,8 +200,10 @@ namespace lib_interval_tree
200200
201201 public:
202202 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 >;
205207
206208 public:
207209 node (node* parent, interval_type interval)
@@ -404,7 +406,12 @@ namespace lib_interval_tree
404406 owner_type owner_;
405407 };
406408// ############################################################################################################
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>
408415 class const_interval_tree_iterator
409416 : public basic_interval_tree_iterator <node_type,
410417 interval_tree <typename node_type::interval_type> const *>
@@ -425,37 +432,19 @@ namespace lib_interval_tree
425432 const_interval_tree_iterator& operator =(const_interval_tree_iterator const &) = default ;
426433 const_interval_tree_iterator& operator =(const_interval_tree_iterator&&) noexcept = default ;
427434
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+
428438 const_interval_tree_iterator& operator ++()
429439 {
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 );
448446 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 );
459448 return *this ;
460449 }
461450
@@ -525,7 +514,7 @@ namespace lib_interval_tree
525514 }
526515 };
527516// ############################################################################################################
528- template <typename node_type>
517+ template <typename node_type, bool reverse = false >
529518 class interval_tree_iterator
530519 : public basic_interval_tree_iterator <node_type,
531520 interval_tree <typename node_type::interval_type>*>
@@ -546,37 +535,19 @@ namespace lib_interval_tree
546535 interval_tree_iterator& operator =(interval_tree_iterator const &) = default ;
547536 interval_tree_iterator& operator =(interval_tree_iterator&&) noexcept = default ;
548537
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+
549541 interval_tree_iterator& operator ++()
550542 {
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 );
569549 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 );
580551 return *this ;
581552 }
582553
@@ -645,6 +616,71 @@ namespace lib_interval_tree
645616 {
646617 }
647618 };
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+ }
648684// ############################################################################################################
649685 template <typename IntervalT = interval <int , closed>>
650686 class interval_tree
@@ -653,14 +689,18 @@ namespace lib_interval_tree
653689 using interval_type = IntervalT;
654690 using value_type = typename interval_type::value_type;
655691 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 >;
658696 using size_type = long long ;
659697 using this_type = interval_tree<interval_type>;
660698
661699 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 >;
664704
665705 public:
666706 interval_tree ()
@@ -1124,6 +1164,23 @@ namespace lib_interval_tree
11241164 return {nullptr , this };
11251165 }
11261166
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+
11271184 const_iterator cbegin () const
11281185 {
11291186 if (!root_)
@@ -1149,6 +1206,31 @@ namespace lib_interval_tree
11491206 return cend ();
11501207 }
11511208
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+
11521234 /* *
11531235 * Returns wether or not the tree is empty
11541236 */
0 commit comments