Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/range/adaptor/strided.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Boost.Range library | |
2 // | |
3 // Copyright Neil Groves 2007. Use, modification and | |
4 // distribution is subject to the Boost Software License, Version | |
5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
6 // http://www.boost.org/LICENSE_1_0.txt) | |
7 // | |
8 // | |
9 // For more information, see http://www.boost.org/libs/range/ | |
10 // | |
11 #ifndef BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED | |
12 #define BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED | |
13 | |
14 #include <boost/range/adaptor/argument_fwd.hpp> | |
15 #include <boost/range/iterator_range.hpp> | |
16 #include <boost/iterator/iterator_adaptor.hpp> | |
17 #include <iterator> | |
18 | |
19 namespace boost | |
20 { | |
21 namespace range_detail | |
22 { | |
23 // strided_iterator for wrapping a forward traversal iterator | |
24 template<class BaseIterator, class Category> | |
25 class strided_iterator | |
26 : public iterator_adaptor< | |
27 strided_iterator<BaseIterator, Category> | |
28 , BaseIterator | |
29 , use_default | |
30 , boost::forward_traversal_tag | |
31 > | |
32 { | |
33 friend class ::boost::iterator_core_access; | |
34 | |
35 typedef iterator_adaptor< | |
36 strided_iterator<BaseIterator, Category> | |
37 , BaseIterator | |
38 , use_default | |
39 , boost::forward_traversal_tag | |
40 > super_t; | |
41 | |
42 public: | |
43 typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type; | |
44 typedef BaseIterator base_iterator; | |
45 | |
46 strided_iterator() | |
47 : m_last() | |
48 , m_stride() | |
49 { | |
50 } | |
51 | |
52 strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride) | |
53 : super_t(it) | |
54 , m_last(last) | |
55 , m_stride(stride) | |
56 { | |
57 } | |
58 | |
59 template<class OtherIterator> | |
60 strided_iterator(const strided_iterator<OtherIterator, Category>& other, | |
61 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0) | |
62 : super_t(other) | |
63 , m_last(other.base_end()) | |
64 , m_stride(other.get_stride()) | |
65 { | |
66 } | |
67 | |
68 base_iterator base_end() const { return m_last; } | |
69 difference_type get_stride() const { return m_stride; } | |
70 | |
71 private: | |
72 void increment() | |
73 { | |
74 base_iterator& it = this->base_reference(); | |
75 for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i) | |
76 ++it; | |
77 } | |
78 | |
79 base_iterator m_last; | |
80 difference_type m_stride; | |
81 }; | |
82 | |
83 // strided_iterator for wrapping a bidirectional iterator | |
84 template<class BaseIterator> | |
85 class strided_iterator<BaseIterator, bidirectional_traversal_tag> | |
86 : public iterator_adaptor< | |
87 strided_iterator<BaseIterator, bidirectional_traversal_tag> | |
88 , BaseIterator | |
89 , use_default | |
90 , bidirectional_traversal_tag | |
91 > | |
92 { | |
93 friend class ::boost::iterator_core_access; | |
94 | |
95 typedef iterator_adaptor< | |
96 strided_iterator<BaseIterator, bidirectional_traversal_tag> | |
97 , BaseIterator | |
98 , use_default | |
99 , bidirectional_traversal_tag | |
100 > super_t; | |
101 public: | |
102 typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type; | |
103 typedef BaseIterator base_iterator; | |
104 | |
105 strided_iterator() | |
106 : m_first() | |
107 , m_last() | |
108 , m_stride() | |
109 { | |
110 } | |
111 | |
112 strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride) | |
113 : super_t(it) | |
114 , m_first(first) | |
115 , m_last(last) | |
116 , m_stride(stride) | |
117 { | |
118 } | |
119 | |
120 template<class OtherIterator> | |
121 strided_iterator(const strided_iterator<OtherIterator, bidirectional_traversal_tag>& other, | |
122 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0) | |
123 : super_t(other.base()) | |
124 , m_first(other.base_begin()) | |
125 , m_last(other.base_end()) | |
126 , m_stride(other.get_stride()) | |
127 { | |
128 } | |
129 | |
130 base_iterator base_begin() const { return m_first; } | |
131 base_iterator base_end() const { return m_last; } | |
132 difference_type get_stride() const { return m_stride; } | |
133 | |
134 private: | |
135 void increment() | |
136 { | |
137 base_iterator& it = this->base_reference(); | |
138 for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i) | |
139 ++it; | |
140 } | |
141 | |
142 void decrement() | |
143 { | |
144 base_iterator& it = this->base_reference(); | |
145 for (difference_type i = 0; (it != m_first) && (i < m_stride); ++i) | |
146 --it; | |
147 } | |
148 | |
149 base_iterator m_first; | |
150 base_iterator m_last; | |
151 difference_type m_stride; | |
152 }; | |
153 | |
154 // strided_iterator implementation for wrapping a random access iterator | |
155 template<class BaseIterator> | |
156 class strided_iterator<BaseIterator, random_access_traversal_tag> | |
157 : public iterator_adaptor< | |
158 strided_iterator<BaseIterator, random_access_traversal_tag> | |
159 , BaseIterator | |
160 , use_default | |
161 , random_access_traversal_tag | |
162 > | |
163 { | |
164 friend class ::boost::iterator_core_access; | |
165 | |
166 typedef iterator_adaptor< | |
167 strided_iterator<BaseIterator, random_access_traversal_tag> | |
168 , BaseIterator | |
169 , use_default | |
170 , random_access_traversal_tag | |
171 > super_t; | |
172 public: | |
173 typedef BOOST_DEDUCED_TYPENAME super_t::difference_type difference_type; | |
174 typedef BaseIterator base_iterator; | |
175 | |
176 strided_iterator() | |
177 : m_first() | |
178 , m_last() | |
179 , m_index(0) | |
180 , m_stride() | |
181 { | |
182 } | |
183 | |
184 strided_iterator(BaseIterator first, BaseIterator it, BaseIterator last, difference_type stride) | |
185 : super_t(it) | |
186 , m_first(first) | |
187 , m_last(last) | |
188 , m_index(stride ? (it - first) / stride : 0) | |
189 , m_stride(stride) | |
190 { | |
191 } | |
192 | |
193 template<class OtherIterator> | |
194 strided_iterator(const strided_iterator<OtherIterator, random_access_traversal_tag>& other, | |
195 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0) | |
196 : super_t(other.base()) | |
197 , m_first(other.base_begin()) | |
198 , m_last(other.base_end()) | |
199 , m_index(other.get_index()) | |
200 , m_stride(other.get_stride()) | |
201 { | |
202 } | |
203 | |
204 base_iterator base_begin() const { return m_first; } | |
205 base_iterator base_end() const { return m_last; } | |
206 difference_type get_stride() const { return m_stride; } | |
207 difference_type get_index() const { return m_index; } | |
208 | |
209 private: | |
210 void increment() | |
211 { | |
212 m_index += m_stride; | |
213 if (m_index < (m_last - m_first)) | |
214 this->base_reference() = m_first + m_index; | |
215 else | |
216 this->base_reference() = m_last; | |
217 } | |
218 | |
219 void decrement() | |
220 { | |
221 m_index -= m_stride; | |
222 if (m_index >= 0) | |
223 this->base_reference() = m_first + m_index; | |
224 else | |
225 this->base_reference() = m_first; | |
226 } | |
227 | |
228 void advance(difference_type offset) | |
229 { | |
230 offset *= m_stride; | |
231 m_index += offset; | |
232 if (m_index < 0) | |
233 this->base_reference() = m_first; | |
234 else if (m_index > (m_last - m_first)) | |
235 this->base_reference() = m_last; | |
236 else | |
237 this->base_reference() = m_first + m_index; | |
238 } | |
239 | |
240 template<class OtherIterator> | |
241 difference_type distance_to(const strided_iterator<OtherIterator, random_access_traversal_tag>& other, | |
242 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0) const | |
243 { | |
244 if (other.base() >= this->base()) | |
245 return (other.base() - this->base() + (m_stride - 1)) / m_stride; | |
246 return (other.base() - this->base() - (m_stride - 1)) / m_stride; | |
247 } | |
248 | |
249 bool equal(const strided_iterator& other) const | |
250 { | |
251 return this->base() == other.base(); | |
252 } | |
253 | |
254 private: | |
255 base_iterator m_first; | |
256 base_iterator m_last; | |
257 difference_type m_index; | |
258 difference_type m_stride; | |
259 }; | |
260 | |
261 template<class BaseIterator, class Difference> inline | |
262 strided_iterator<BaseIterator, BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type> | |
263 make_strided_iterator(BaseIterator first, BaseIterator it, | |
264 BaseIterator last, Difference stride) | |
265 { | |
266 BOOST_ASSERT( stride >= 0 ); | |
267 typedef BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type traversal_tag; | |
268 return strided_iterator<BaseIterator, traversal_tag>(first, it, last, stride); | |
269 } | |
270 | |
271 template< class Rng | |
272 , class Category = BOOST_DEDUCED_TYPENAME iterator_traversal< | |
273 BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type | |
274 >::type | |
275 > | |
276 class strided_range | |
277 : public iterator_range< | |
278 range_detail::strided_iterator< | |
279 BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type, | |
280 Category | |
281 > | |
282 > | |
283 { | |
284 typedef range_detail::strided_iterator< | |
285 BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type, | |
286 Category | |
287 > iter_type; | |
288 typedef iterator_range<iter_type> super_t; | |
289 public: | |
290 template<class Difference> | |
291 strided_range(Difference stride, Rng& rng) | |
292 : super_t(make_strided_iterator(boost::begin(rng), boost::begin(rng), boost::end(rng), stride), | |
293 make_strided_iterator(boost::begin(rng), boost::end(rng), boost::end(rng), stride)) | |
294 { | |
295 BOOST_ASSERT( stride >= 0 ); | |
296 } | |
297 }; | |
298 | |
299 template<class Difference> | |
300 class strided_holder : public holder<Difference> | |
301 { | |
302 public: | |
303 explicit strided_holder(Difference value) : holder<Difference>(value) {} | |
304 }; | |
305 | |
306 template<class Rng, class Difference> | |
307 inline strided_range<Rng> | |
308 operator|(Rng& rng, const strided_holder<Difference>& stride) | |
309 { | |
310 return strided_range<Rng>(stride.val, rng); | |
311 } | |
312 | |
313 template<class Rng, class Difference> | |
314 inline strided_range<const Rng> | |
315 operator|(const Rng& rng, const strided_holder<Difference>& stride) | |
316 { | |
317 return strided_range<const Rng>(stride.val, rng); | |
318 } | |
319 | |
320 } // namespace range_detail | |
321 | |
322 using range_detail::strided_range; | |
323 | |
324 namespace adaptors | |
325 { | |
326 | |
327 namespace | |
328 { | |
329 const range_detail::forwarder<range_detail::strided_holder> | |
330 strided = range_detail::forwarder<range_detail::strided_holder>(); | |
331 } | |
332 | |
333 template<class Range, class Difference> | |
334 inline strided_range<Range> | |
335 stride(Range& rng, Difference step) | |
336 { | |
337 return strided_range<Range>(step, rng); | |
338 } | |
339 | |
340 template<class Range, class Difference> | |
341 inline strided_range<const Range> | |
342 stride(const Range& rng, Difference step) | |
343 { | |
344 return strided_range<const Range>(step, rng); | |
345 } | |
346 | |
347 } // namespace 'adaptors' | |
348 } // namespace 'boost' | |
349 | |
350 #endif |