99
1010#include " xcore.h"
1111
12+ #include < iterator>
1213#include < numeric>
1314#include < vector>
1415
1516CPL_BEGIN
16- #ifdef USE_DISJOINT_SET_ITERATORS
1717template <class MyDisj >
18- class _Disjoint_set_const_iterator {
18+ class disjoint_set_const_iterator {
1919public:
2020 using iterator_category = std::random_access_iterator_tag;
21+ using iterator_concept = std::random_access_iterator_tag;
22+ using difference_type = std::ptrdiff_t ;
23+
24+ private:
25+ using parent_value_type = typename MyDisj::value_type;
26+ using parent_rank_type = typename MyDisj::rank_type;
27+
28+ using parent_iterator = typename std::vector<parent_value_type>::const_iterator;
29+ using rank_iterator = typename std::vector<parent_rank_type>::const_iterator;
2130
2231protected:
23- using parent_iterator = typename std::vector<typename MyDisj::value_type>::iterator;
24- using rank_iterator = typename std::vector<typename MyDisj::rank_type>::iterator;
32+ using pair_cref = std::pair<const parent_value_type&, const parent_rank_type&>;
33+
34+ struct arrow_proxy {
35+ pair_cref ref;
36+
37+ const pair_cref* operator ->() const noexcept {
38+ return &ref;
39+ }
40+ };
2541
2642public:
27- using value_type = std::pair<typename MyDisj::value_type, typename MyDisj::rank_type>;
28- using difference_type = std::ptrdiff_t ;
29- using pointer = value_type*;
30- using const_pointer = value_type*;
31- using reference = value_type&;
32- using const_reference = const value_type&;
43+ using value_type = std::pair<parent_value_type, parent_rank_type>;
44+ using reference = value_type;
45+ using const_reference = value_type;
46+ using pointer = const value_type*;
47+ using const_pointer = const value_type*;
3348
34- _Disjoint_set_const_iterator (parent_iterator parent, rank_iterator rank) noexcept : parent(parent), rank(rank) {}
49+ disjoint_set_const_iterator () = default ;
3550
36- [[nodiscard]] value_type operator *() const noexcept {
37- return {(*parent), (*rank)};
51+ disjoint_set_const_iterator (parent_iterator parent, rank_iterator rank) noexcept : parent(parent), rank(rank) {}
52+
53+ [[nodiscard]] reference operator *() const noexcept {
54+ return reference{*parent, *rank};
3855 }
3956
40- [[nodiscard]] pointer operator ->() const noexcept {
41- return & operator *() ;
57+ [[nodiscard]] arrow_proxy operator ->() const noexcept {
58+ return arrow_proxy{reference{*parent, *rank}} ;
4259 }
4360
44- _Disjoint_set_const_iterator & operator ++() noexcept {
61+ disjoint_set_const_iterator & operator ++() noexcept {
4562 ++parent;
4663 ++rank;
4764 return *this ;
4865 }
4966
50- _Disjoint_set_const_iterator& operator ++(int ) noexcept {
67+ disjoint_set_const_iterator operator ++(int ) noexcept {
5168 auto tmp = *this ;
5269 ++(*this );
5370 return tmp;
5471 }
5572
56- _Disjoint_set_const_iterator & operator --() noexcept {
73+ disjoint_set_const_iterator & operator --() noexcept {
5774 --parent;
5875 --rank;
5976 return *this ;
6077 }
6178
62- _Disjoint_set_const_iterator& operator --(int ) noexcept {
79+ disjoint_set_const_iterator operator --(int ) noexcept {
6380 auto tmp = *this ;
6481 --(*this );
6582 return tmp;
6683 }
6784
68- [[nodiscard]] _Disjoint_set_const_iterator & operator +=(const difference_type off) noexcept {
85+ [[nodiscard]] disjoint_set_const_iterator & operator +=(const difference_type off) noexcept {
6986 parent += off;
7087 rank += off;
7188 return *this ;
7289 }
7390
74- [[nodiscard]] _Disjoint_set_const_iterator operator +(const difference_type off) const noexcept {
91+ [[nodiscard]] disjoint_set_const_iterator operator +(const difference_type off) const noexcept {
7592 auto tmp = *this ;
7693 tmp += off;
7794 return tmp;
7895 }
7996
80- [[nodiscard]] friend _Disjoint_set_const_iterator operator +(
81- const difference_type off, _Disjoint_set_const_iterator next) noexcept {
97+ [[nodiscard]] friend disjoint_set_const_iterator operator +(
98+ const difference_type off, disjoint_set_const_iterator next) noexcept {
8299 next += off;
83100 return next;
84101 }
85102
86- [[nodiscard]] _Disjoint_set_const_iterator & operator -=(const difference_type off) noexcept {
103+ [[nodiscard]] disjoint_set_const_iterator & operator -=(const difference_type off) noexcept {
87104 return *this += -off;
88105 }
89106
90- [[nodiscard]] _Disjoint_set_const_iterator operator -(const difference_type off) const noexcept {
107+ [[nodiscard]] disjoint_set_const_iterator operator -(const difference_type off) const noexcept {
91108 auto tmp = *this ;
92109 tmp -= off;
93110 return tmp;
94111 }
95112
96- [[nodiscard]] difference_type operator -(const _Disjoint_set_const_iterator & right) const noexcept {
113+ [[nodiscard]] difference_type operator -(const disjoint_set_const_iterator & right) const noexcept {
97114 return static_cast <difference_type>(parent - right.parent );
98115 }
99116
100- [[nodiscard]] bool operator ==(const _Disjoint_set_const_iterator& right) const noexcept {
117+ [[nodiscard]] reference operator [](const difference_type off) const noexcept {
118+ return *(*this + off);
119+ }
120+
121+ [[nodiscard]] bool operator ==(const disjoint_set_const_iterator& right) const noexcept {
101122 return parent == right.parent ;
102123 }
103124
104- [[nodiscard]] bool operator !=(const _Disjoint_set_const_iterator & right) const noexcept {
125+ [[nodiscard]] bool operator !=(const disjoint_set_const_iterator & right) const noexcept {
105126 return !(*this == right);
106127 }
107128
129+ [[nodiscard]] bool operator <(const disjoint_set_const_iterator& right) const noexcept {
130+ return parent < right.parent ;
131+ }
132+
133+ [[nodiscard]] bool operator >(const disjoint_set_const_iterator& right) const noexcept {
134+ return right < *this ;
135+ }
136+
137+ [[nodiscard]] bool operator <=(const disjoint_set_const_iterator& right) const noexcept {
138+ return !(right < *this );
139+ }
140+
141+ [[nodiscard]] bool operator >=(const disjoint_set_const_iterator& right) const noexcept {
142+ return !(*this < right);
143+ }
144+
108145protected:
109146 parent_iterator parent;
110147 rank_iterator rank;
111148};
112149
113150template <class Mydisj >
114- class _Disjoint_set_iterator : public _Disjoint_set_const_iterator <Mydisj> {
151+ class disjoint_set_iterator : public disjoint_set_const_iterator <Mydisj> {
115152protected:
116- using _Mybase = _Disjoint_set_const_iterator <Mydisj>;
153+ using Mybase = disjoint_set_const_iterator <Mydisj>;
117154
118155public:
119- using _Mybase::_Mybase;
156+ using iterator_category = std::random_access_iterator_tag;
157+ using iterator_concept = std::random_access_iterator_tag;
158+ using difference_type = typename Mybase::difference_type;
159+
160+ using value_type = typename Mybase::value_type;
161+ using reference = typename Mybase::reference;
162+ using pointer = typename Mybase::pointer;
163+
164+ using Mybase::Mybase;
165+
166+ [[nodiscard]] reference operator *() const noexcept {
167+ return Mybase::operator *();
168+ }
169+
170+ [[nodiscard]] Mybase::arrow_proxy operator ->() const noexcept {
171+ return Mybase::operator ->();
172+ }
173+
174+ disjoint_set_iterator& operator ++() noexcept {
175+ Mybase::operator ++();
176+ return *this ;
177+ }
178+
179+ disjoint_set_iterator operator ++(int ) noexcept {
180+ auto tmp = *this ;
181+ Mybase::operator ++();
182+ return tmp;
183+ }
184+
185+ disjoint_set_iterator& operator --() noexcept {
186+ Mybase::operator --();
187+ return *this ;
188+ }
189+
190+ disjoint_set_iterator operator --(int ) noexcept {
191+ auto tmp = *this ;
192+ Mybase::operator --();
193+ return tmp;
194+ }
195+
196+ [[nodiscard]] disjoint_set_iterator& operator +=(const difference_type off) noexcept {
197+ Mybase::operator +=(off);
198+ return *this ;
199+ }
200+
201+ [[nodiscard]] disjoint_set_iterator operator +(const difference_type off) const noexcept {
202+ auto tmp = *this ;
203+ tmp += off;
204+ return tmp;
205+ }
206+
207+ [[nodiscard]] friend disjoint_set_iterator operator +(
208+ const difference_type off, disjoint_set_iterator next) noexcept {
209+ next += off;
210+ return next;
211+ }
212+
213+ [[nodiscard]] disjoint_set_iterator& operator -=(const difference_type off) noexcept {
214+ Mybase::operator -=(off);
215+ return *this ;
216+ }
217+
218+ [[nodiscard]] disjoint_set_iterator operator -(const difference_type off) const noexcept {
219+ auto tmp = *this ;
220+ tmp -= off;
221+ return tmp;
222+ }
223+
224+ [[nodiscard]] difference_type operator -(const disjoint_set_iterator& right) const noexcept {
225+ return static_cast <difference_type>(this ->parent - right.parent );
226+ }
227+
228+ [[nodiscard]] reference operator [](const difference_type off) const noexcept {
229+ return const_cast <reference>(Mybase::operator [](off));
230+ }
120231};
121- #endif // USE_DISJOINT_SET_ITERATORS
122232
123233template <class Ty , class Ranty = std::size_t >
124234class DisjointSet { // fixed size union find structure
@@ -180,9 +290,9 @@ class DisjointSet { // fixed size union find structure
180290 rank.resize (size, 0 );
181291 }
182292
183- #ifdef USE_DISJOINT_SET_ITERATORS
184- using iterator = _Disjoint_set_iterator <DisjointSet<value_type>>;
185- using const_iterator = _Disjoint_set_const_iterator <DisjointSet<value_type>>;
293+ #ifdef CPL
294+ using iterator = disjoint_set_iterator <DisjointSet<value_type>>;
295+ using const_iterator = disjoint_set_const_iterator <DisjointSet<value_type>>;
186296
187297 [[nodiscard]] iterator begin () noexcept {
188298 return iterator (parent.begin (), rank.begin ());
@@ -199,7 +309,7 @@ class DisjointSet { // fixed size union find structure
199309 [[nodiscard]] const_iterator end () const noexcept {
200310 return const_iterator (parent.end (), rank.end ());
201311 }
202- #endif // USE_DISJOINT_SET_ITERATORS
312+ #endif // CPL
203313
204314private:
205315 std::vector<value_type> parent;
0 commit comments