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