]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/geometry/iterators/flatten_iterator.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / iterators / flatten_iterator.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
20effc67 3// Copyright (c) 2014-2020, Oracle and/or its affiliates.
7c673cae 4// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
20effc67 5// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7c673cae
FG
6
7// Licensed under the Boost Software License version 1.0.
8// http://www.boost.org/users/license.html
9
10#ifndef BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP
11#define BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP
12
20effc67
TL
13#include <type_traits>
14
7c673cae
FG
15#include <boost/iterator/iterator_facade.hpp>
16#include <boost/iterator/iterator_categories.hpp>
17
18#include <boost/geometry/core/assert.hpp>
20effc67 19#include <boost/geometry/core/static_assert.hpp>
7c673cae
FG
20
21namespace boost { namespace geometry
22{
23
24
25
26template
27<
28 typename OuterIterator,
29 typename InnerIterator,
30 typename Value,
31 typename AccessInnerBegin,
32 typename AccessInnerEnd,
33 typename Reference = Value&
34>
35class flatten_iterator
36 : public boost::iterator_facade
37 <
38 flatten_iterator
39 <
40 OuterIterator,
41 InnerIterator,
42 Value,
43 AccessInnerBegin,
44 AccessInnerEnd,
45 Reference
46 >,
47 Value,
48 boost::bidirectional_traversal_tag,
49 Reference
50 >
51{
52private:
53 OuterIterator m_outer_it, m_outer_end;
54 InnerIterator m_inner_it;
55
56public:
57 typedef OuterIterator outer_iterator_type;
58 typedef InnerIterator inner_iterator_type;
59
60 // default constructor
61 flatten_iterator() {}
62
63 // for begin
64 flatten_iterator(OuterIterator outer_it, OuterIterator outer_end)
65 : m_outer_it(outer_it), m_outer_end(outer_end)
66 {
67 advance_through_empty();
68 }
69
70 // for end
71 flatten_iterator(OuterIterator outer_end)
72 : m_outer_it(outer_end), m_outer_end(outer_end)
73 {}
74
75 template
76 <
77 typename OtherOuterIterator, typename OtherInnerIterator,
78 typename OtherValue,
79 typename OtherAccessInnerBegin, typename OtherAccessInnerEnd,
80 typename OtherReference
81 >
82 flatten_iterator(flatten_iterator
83 <
84 OtherOuterIterator,
85 OtherInnerIterator,
86 OtherValue,
87 OtherAccessInnerBegin,
88 OtherAccessInnerEnd,
89 OtherReference
90 > const& other)
91 : m_outer_it(other.m_outer_it),
92 m_outer_end(other.m_outer_end),
93 m_inner_it(other.m_inner_it)
94 {
95 static const bool are_conv
20effc67 96 = std::is_convertible
7c673cae
FG
97 <
98 OtherOuterIterator, OuterIterator
99 >::value
20effc67 100 && std::is_convertible
7c673cae
FG
101 <
102 OtherInnerIterator, InnerIterator
103 >::value;
104
20effc67
TL
105 BOOST_GEOMETRY_STATIC_ASSERT((are_conv),
106 "Other iterators have to be convertible to member iterators.",
107 OtherOuterIterator, OtherInnerIterator);
7c673cae
FG
108 }
109
110 flatten_iterator& operator=(flatten_iterator const& other)
111 {
112 m_outer_it = other.m_outer_it;
113 m_outer_end = other.m_outer_end;
114 // avoid assigning an iterator having singular value
115 if ( other.m_outer_it != other.m_outer_end )
116 {
117 m_inner_it = other.m_inner_it;
118 }
119 return *this;
120 }
121
122private:
123 friend class boost::iterator_core_access;
124
125 template
126 <
127 typename Outer,
128 typename Inner,
129 typename V,
130 typename InnerBegin,
131 typename InnerEnd,
132 typename R
133 >
134 friend class flatten_iterator;
135
136 static inline bool empty(OuterIterator outer_it)
137 {
138 return AccessInnerBegin::apply(*outer_it)
139 == AccessInnerEnd::apply(*outer_it);
140 }
141
142 inline void advance_through_empty()
143 {
144 while ( m_outer_it != m_outer_end && empty(m_outer_it) )
145 {
146 ++m_outer_it;
147 }
148
149 if ( m_outer_it != m_outer_end )
150 {
151 m_inner_it = AccessInnerBegin::apply(*m_outer_it);
152 }
153 }
154
155 inline Reference dereference() const
156 {
157 BOOST_GEOMETRY_ASSERT( m_outer_it != m_outer_end );
158 BOOST_GEOMETRY_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
159 return *m_inner_it;
160 }
161
162
163 template
164 <
165 typename OtherOuterIterator,
166 typename OtherInnerIterator,
167 typename OtherValue,
168 typename OtherAccessInnerBegin,
169 typename OtherAccessInnerEnd,
170 typename OtherReference
171 >
172 inline bool equal(flatten_iterator
173 <
174 OtherOuterIterator,
175 OtherInnerIterator,
176 OtherValue,
177 OtherAccessInnerBegin,
178 OtherAccessInnerEnd,
179 OtherReference
180 > const& other) const
181 {
182 if ( m_outer_it != other.m_outer_it )
183 {
184 return false;
185 }
186
187 if ( m_outer_it == m_outer_end )
188 {
189 return true;
190 }
191
192 return m_inner_it == other.m_inner_it;
193 }
194
195 inline void increment()
196 {
197 BOOST_GEOMETRY_ASSERT( m_outer_it != m_outer_end );
198 BOOST_GEOMETRY_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
199
200 ++m_inner_it;
201 if ( m_inner_it == AccessInnerEnd::apply(*m_outer_it) )
202 {
203 ++m_outer_it;
204 advance_through_empty();
205 }
206 }
207
208 inline void decrement()
209 {
210 if ( m_outer_it == m_outer_end
211 || m_inner_it == AccessInnerBegin::apply(*m_outer_it) )
212 {
213 do
214 {
215 --m_outer_it;
216 }
217 while ( empty(m_outer_it) );
218 m_inner_it = AccessInnerEnd::apply(*m_outer_it);
219 }
220 --m_inner_it;
221 }
222};
223
224
225
226}} // namespace boost::geometry
227
228
229#endif // BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP