Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/range/adaptor/strided.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
comparison
equal
deleted
inserted
replaced
100:793467b5e61c | 101:c530137014c0 |
---|---|
11 #ifndef BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED | 11 #ifndef BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED |
12 #define BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED | 12 #define BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED |
13 | 13 |
14 #include <boost/range/adaptor/argument_fwd.hpp> | 14 #include <boost/range/adaptor/argument_fwd.hpp> |
15 #include <boost/range/iterator_range.hpp> | 15 #include <boost/range/iterator_range.hpp> |
16 #include <boost/iterator/iterator_adaptor.hpp> | 16 #include <boost/iterator/iterator_facade.hpp> |
17 #include <iterator> | 17 #include <iterator> |
18 | 18 |
19 namespace boost | 19 namespace boost |
20 { | 20 { |
21 namespace range_detail | 21 namespace range_detail |
22 { | 22 { |
23 // strided_iterator for wrapping a forward traversal iterator | 23 // strided_iterator for wrapping a forward traversal iterator |
24 template<class BaseIterator, class Category> | 24 template<class BaseIterator, class Category> |
25 class strided_iterator | 25 class strided_iterator |
26 : public iterator_adaptor< | 26 : public iterator_facade< |
27 strided_iterator<BaseIterator, Category> | 27 strided_iterator<BaseIterator, Category> |
28 , BaseIterator | 28 , typename iterator_value<BaseIterator>::type |
29 , use_default | 29 , forward_traversal_tag |
30 , boost::forward_traversal_tag | 30 , typename iterator_reference<BaseIterator>::type |
31 , typename iterator_difference<BaseIterator>::type | |
31 > | 32 > |
32 { | 33 { |
33 friend class ::boost::iterator_core_access; | 34 friend class ::boost::iterator_core_access; |
34 | 35 |
35 typedef iterator_adaptor< | 36 typedef iterator_facade< |
36 strided_iterator<BaseIterator, Category> | 37 strided_iterator<BaseIterator, Category> |
37 , BaseIterator | 38 , typename iterator_value<BaseIterator>::type |
38 , use_default | 39 , forward_traversal_tag |
39 , boost::forward_traversal_tag | 40 , typename iterator_reference<BaseIterator>::type |
40 > super_t; | 41 , typename iterator_difference<BaseIterator>::type |
42 > super_t; | |
41 | 43 |
42 public: | 44 public: |
43 typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type; | 45 typedef typename super_t::difference_type difference_type; |
46 typedef typename super_t::reference reference; | |
44 typedef BaseIterator base_iterator; | 47 typedef BaseIterator base_iterator; |
48 typedef std::forward_iterator_tag iterator_category; | |
45 | 49 |
46 strided_iterator() | 50 strided_iterator() |
47 : m_last() | 51 : m_it() |
52 , m_last() | |
48 , m_stride() | 53 , m_stride() |
49 { | 54 { |
50 } | 55 } |
51 | 56 |
52 strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride) | 57 strided_iterator(base_iterator it, |
53 : super_t(it) | 58 base_iterator last, |
59 difference_type stride) | |
60 : m_it(it) | |
54 , m_last(last) | 61 , m_last(last) |
55 , m_stride(stride) | 62 , m_stride(stride) |
56 { | 63 { |
57 } | 64 } |
58 | 65 |
59 template<class OtherIterator> | 66 template<class OtherIterator> |
60 strided_iterator(const strided_iterator<OtherIterator, Category>& other, | 67 strided_iterator( |
61 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0) | 68 const strided_iterator<OtherIterator, Category>& other, |
62 : super_t(other) | 69 typename enable_if_convertible< |
70 OtherIterator, | |
71 base_iterator | |
72 >::type* = 0 | |
73 ) | |
74 : m_it(other.base()) | |
63 , m_last(other.base_end()) | 75 , m_last(other.base_end()) |
64 , m_stride(other.get_stride()) | 76 , m_stride(other.get_stride()) |
65 { | 77 { |
66 } | 78 } |
67 | 79 |
68 base_iterator base_end() const { return m_last; } | 80 base_iterator base() const |
69 difference_type get_stride() const { return m_stride; } | 81 { |
82 return m_it; | |
83 } | |
84 | |
85 base_iterator base_end() const | |
86 { | |
87 return m_last; | |
88 } | |
89 | |
90 difference_type get_stride() const | |
91 { | |
92 return m_stride; | |
93 } | |
70 | 94 |
71 private: | 95 private: |
72 void increment() | 96 void increment() |
73 { | 97 { |
74 base_iterator& it = this->base_reference(); | 98 for (difference_type i = 0; |
75 for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i) | 99 (m_it != m_last) && (i < m_stride); ++i) |
76 ++it; | 100 { |
77 } | 101 ++m_it; |
78 | 102 } |
103 } | |
104 | |
105 reference dereference() const | |
106 { | |
107 return *m_it; | |
108 } | |
109 | |
110 template<class OtherIterator> | |
111 bool equal( | |
112 const strided_iterator<OtherIterator, Category>& other, | |
113 typename enable_if_convertible< | |
114 OtherIterator, | |
115 base_iterator | |
116 >::type* = 0) const | |
117 { | |
118 return m_it == other.m_it; | |
119 } | |
120 | |
121 base_iterator m_it; | |
79 base_iterator m_last; | 122 base_iterator m_last; |
80 difference_type m_stride; | 123 difference_type m_stride; |
81 }; | 124 }; |
82 | 125 |
83 // strided_iterator for wrapping a bidirectional iterator | 126 // strided_iterator for wrapping a bidirectional iterator |
84 template<class BaseIterator> | 127 template<class BaseIterator> |
85 class strided_iterator<BaseIterator, bidirectional_traversal_tag> | 128 class strided_iterator<BaseIterator, bidirectional_traversal_tag> |
86 : public iterator_adaptor< | 129 : public iterator_facade< |
87 strided_iterator<BaseIterator, bidirectional_traversal_tag> | 130 strided_iterator<BaseIterator, bidirectional_traversal_tag> |
88 , BaseIterator | 131 , typename iterator_value<BaseIterator>::type |
89 , use_default | 132 , bidirectional_traversal_tag |
90 , bidirectional_traversal_tag | 133 , typename iterator_reference<BaseIterator>::type |
134 , typename iterator_difference<BaseIterator>::type | |
91 > | 135 > |
92 { | 136 { |
93 friend class ::boost::iterator_core_access; | 137 friend class ::boost::iterator_core_access; |
94 | 138 |
95 typedef iterator_adaptor< | 139 typedef iterator_facade< |
96 strided_iterator<BaseIterator, bidirectional_traversal_tag> | 140 strided_iterator<BaseIterator, bidirectional_traversal_tag> |
97 , BaseIterator | 141 , typename iterator_value<BaseIterator>::type |
98 , use_default | 142 , bidirectional_traversal_tag |
99 , bidirectional_traversal_tag | 143 , typename iterator_reference<BaseIterator>::type |
100 > super_t; | 144 , typename iterator_difference<BaseIterator>::type |
145 > super_t; | |
101 public: | 146 public: |
102 typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type; | 147 typedef typename super_t::difference_type difference_type; |
148 typedef typename super_t::reference reference; | |
103 typedef BaseIterator base_iterator; | 149 typedef BaseIterator base_iterator; |
150 typedef typename boost::make_unsigned<difference_type>::type | |
151 size_type; | |
152 typedef std::bidirectional_iterator_tag iterator_category; | |
104 | 153 |
105 strided_iterator() | 154 strided_iterator() |
106 : m_first() | 155 : m_it() |
107 , m_last() | 156 , m_offset() |
157 , m_index() | |
108 , m_stride() | 158 , m_stride() |
109 { | 159 { |
110 } | 160 } |
111 | 161 |
112 strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride) | 162 strided_iterator(base_iterator it, |
113 : super_t(it) | 163 size_type index, |
114 , m_first(first) | 164 difference_type stride) |
115 , m_last(last) | 165 : m_it(it) |
166 , m_offset() | |
167 , m_index(index) | |
116 , m_stride(stride) | 168 , m_stride(stride) |
117 { | 169 { |
170 if (stride && ((m_index % stride) != 0)) | |
171 m_index += (stride - (m_index % stride)); | |
118 } | 172 } |
119 | 173 |
120 template<class OtherIterator> | 174 template<class OtherIterator> |
121 strided_iterator(const strided_iterator<OtherIterator, bidirectional_traversal_tag>& other, | 175 strided_iterator( |
122 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0) | 176 const strided_iterator< |
123 : super_t(other.base()) | 177 OtherIterator, |
124 , m_first(other.base_begin()) | 178 bidirectional_traversal_tag |
125 , m_last(other.base_end()) | 179 >& other, |
180 typename enable_if_convertible< | |
181 OtherIterator, | |
182 base_iterator | |
183 >::type* = 0 | |
184 ) | |
185 : m_it(other.base()) | |
186 , m_offset(other.get_offset()) | |
187 , m_index(other.get_index()) | |
126 , m_stride(other.get_stride()) | 188 , m_stride(other.get_stride()) |
127 { | 189 { |
128 } | 190 } |
129 | 191 |
130 base_iterator base_begin() const { return m_first; } | 192 base_iterator base() const |
131 base_iterator base_end() const { return m_last; } | 193 { |
132 difference_type get_stride() const { return m_stride; } | 194 return m_it; |
195 } | |
196 | |
197 difference_type get_offset() const | |
198 { | |
199 return m_offset; | |
200 } | |
201 | |
202 size_type get_index() const | |
203 { | |
204 return m_index; | |
205 } | |
206 | |
207 difference_type get_stride() const | |
208 { | |
209 return m_stride; | |
210 } | |
133 | 211 |
134 private: | 212 private: |
135 void increment() | 213 void increment() |
136 { | 214 { |
137 base_iterator& it = this->base_reference(); | 215 m_offset += m_stride; |
138 for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i) | |
139 ++it; | |
140 } | 216 } |
141 | 217 |
142 void decrement() | 218 void decrement() |
143 { | 219 { |
144 base_iterator& it = this->base_reference(); | 220 m_offset -= m_stride; |
145 for (difference_type i = 0; (it != m_first) && (i < m_stride); ++i) | 221 } |
146 --it; | 222 |
147 } | 223 reference dereference() const |
148 | 224 { |
149 base_iterator m_first; | 225 update(); |
150 base_iterator m_last; | 226 return *m_it; |
227 } | |
228 | |
229 void update() const | |
230 { | |
231 std::advance(m_it, m_offset); | |
232 m_index += m_offset; | |
233 m_offset = 0; | |
234 } | |
235 | |
236 template<class OtherIterator> | |
237 bool equal( | |
238 const strided_iterator< | |
239 OtherIterator, | |
240 bidirectional_traversal_tag | |
241 >& other, | |
242 typename enable_if_convertible< | |
243 OtherIterator, | |
244 base_iterator | |
245 >::type* = 0) const | |
246 { | |
247 return (m_index + m_offset) == | |
248 (other.get_index() + other.get_offset()); | |
249 } | |
250 | |
251 mutable base_iterator m_it; | |
252 mutable difference_type m_offset; | |
253 mutable size_type m_index; | |
151 difference_type m_stride; | 254 difference_type m_stride; |
152 }; | 255 }; |
153 | 256 |
154 // strided_iterator implementation for wrapping a random access iterator | 257 // strided_iterator implementation for wrapping a random access iterator |
155 template<class BaseIterator> | 258 template<class BaseIterator> |
156 class strided_iterator<BaseIterator, random_access_traversal_tag> | 259 class strided_iterator<BaseIterator, random_access_traversal_tag> |
157 : public iterator_adaptor< | 260 : public iterator_facade< |
158 strided_iterator<BaseIterator, random_access_traversal_tag> | 261 strided_iterator<BaseIterator, random_access_traversal_tag> |
159 , BaseIterator | 262 , typename iterator_value<BaseIterator>::type |
160 , use_default | 263 , random_access_traversal_tag |
161 , random_access_traversal_tag | 264 , typename iterator_reference<BaseIterator>::type |
162 > | 265 , typename iterator_difference<BaseIterator>::type |
266 > | |
163 { | 267 { |
164 friend class ::boost::iterator_core_access; | 268 friend class ::boost::iterator_core_access; |
165 | 269 |
166 typedef iterator_adaptor< | 270 typedef iterator_facade< |
167 strided_iterator<BaseIterator, random_access_traversal_tag> | 271 strided_iterator<BaseIterator, random_access_traversal_tag> |
168 , BaseIterator | 272 , typename iterator_value<BaseIterator>::type |
169 , use_default | 273 , random_access_traversal_tag |
170 , random_access_traversal_tag | 274 , typename iterator_reference<BaseIterator>::type |
171 > super_t; | 275 , typename iterator_difference<BaseIterator>::type |
276 > super_t; | |
172 public: | 277 public: |
173 typedef BOOST_DEDUCED_TYPENAME super_t::difference_type difference_type; | 278 typedef typename super_t::difference_type difference_type; |
279 typedef typename super_t::reference reference; | |
174 typedef BaseIterator base_iterator; | 280 typedef BaseIterator base_iterator; |
281 typedef std::random_access_iterator_tag iterator_category; | |
175 | 282 |
176 strided_iterator() | 283 strided_iterator() |
177 : m_first() | 284 : m_it() |
178 , m_last() | 285 , m_first() |
179 , m_index(0) | 286 , m_index(0) |
180 , m_stride() | 287 , m_stride() |
181 { | 288 { |
182 } | 289 } |
183 | 290 |
184 strided_iterator(BaseIterator first, BaseIterator it, BaseIterator last, difference_type stride) | 291 strided_iterator( |
185 : super_t(it) | 292 base_iterator first, |
293 base_iterator it, | |
294 difference_type stride | |
295 ) | |
296 : m_it(it) | |
186 , m_first(first) | 297 , m_first(first) |
187 , m_last(last) | 298 , m_index(stride ? (it - first) : difference_type()) |
188 , m_index(stride ? (it - first) / stride : 0) | |
189 , m_stride(stride) | 299 , m_stride(stride) |
190 { | 300 { |
301 if (stride && ((m_index % stride) != 0)) | |
302 m_index += (stride - (m_index % stride)); | |
191 } | 303 } |
192 | 304 |
193 template<class OtherIterator> | 305 template<class OtherIterator> |
194 strided_iterator(const strided_iterator<OtherIterator, random_access_traversal_tag>& other, | 306 strided_iterator( |
195 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0) | 307 const strided_iterator< |
196 : super_t(other.base()) | 308 OtherIterator, |
309 random_access_traversal_tag | |
310 >& other, | |
311 typename enable_if_convertible< | |
312 OtherIterator, | |
313 base_iterator | |
314 >::type* = 0 | |
315 ) | |
316 : m_it(other.base()) | |
197 , m_first(other.base_begin()) | 317 , m_first(other.base_begin()) |
198 , m_last(other.base_end()) | |
199 , m_index(other.get_index()) | 318 , m_index(other.get_index()) |
200 , m_stride(other.get_stride()) | 319 , m_stride(other.get_stride()) |
201 { | 320 { |
202 } | 321 } |
203 | 322 |
204 base_iterator base_begin() const { return m_first; } | 323 base_iterator base_begin() const |
205 base_iterator base_end() const { return m_last; } | 324 { |
206 difference_type get_stride() const { return m_stride; } | 325 return m_first; |
207 difference_type get_index() const { return m_index; } | 326 } |
327 | |
328 base_iterator base() const | |
329 { | |
330 return m_it; | |
331 } | |
332 | |
333 difference_type get_stride() const | |
334 { | |
335 return m_stride; | |
336 } | |
337 | |
338 difference_type get_index() const | |
339 { | |
340 return m_index; | |
341 } | |
208 | 342 |
209 private: | 343 private: |
210 void increment() | 344 void increment() |
211 { | 345 { |
212 m_index += m_stride; | 346 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 } | 347 } |
218 | 348 |
219 void decrement() | 349 void decrement() |
220 { | 350 { |
221 m_index -= m_stride; | 351 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 } | 352 } |
227 | 353 |
228 void advance(difference_type offset) | 354 void advance(difference_type offset) |
229 { | 355 { |
230 offset *= m_stride; | 356 m_index += (m_stride * offset); |
231 m_index += offset; | 357 } |
232 if (m_index < 0) | 358 |
233 this->base_reference() = m_first; | 359 // Implementation detail: only update the actual underlying iterator |
234 else if (m_index > (m_last - m_first)) | 360 // at the point of dereference. This is done so that the increment |
235 this->base_reference() = m_last; | 361 // and decrement can overshoot the valid sequence as is required |
236 else | 362 // by striding. Since we can do all comparisons just with the index |
237 this->base_reference() = m_first + m_index; | 363 // simply, and all dereferences must be within the valid range. |
364 void update() const | |
365 { | |
366 m_it = m_first + m_index; | |
238 } | 367 } |
239 | 368 |
240 template<class OtherIterator> | 369 template<class OtherIterator> |
241 difference_type distance_to(const strided_iterator<OtherIterator, random_access_traversal_tag>& other, | 370 difference_type distance_to( |
242 BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0) const | 371 const strided_iterator< |
243 { | 372 OtherIterator, |
244 if (other.base() >= this->base()) | 373 random_access_traversal_tag |
245 return (other.base() - this->base() + (m_stride - 1)) / m_stride; | 374 >& other, |
246 return (other.base() - this->base() - (m_stride - 1)) / m_stride; | 375 typename enable_if_convertible< |
247 } | 376 OtherIterator, base_iterator>::type* = 0) const |
248 | 377 { |
249 bool equal(const strided_iterator& other) const | 378 BOOST_ASSERT((other.m_index - m_index) % m_stride == difference_type()); |
250 { | 379 return (other.m_index - m_index) / m_stride; |
251 return this->base() == other.base(); | 380 } |
381 | |
382 template<class OtherIterator> | |
383 bool equal( | |
384 const strided_iterator< | |
385 OtherIterator, | |
386 random_access_traversal_tag | |
387 >& other, | |
388 typename enable_if_convertible< | |
389 OtherIterator, base_iterator>::type* = 0) const | |
390 { | |
391 return m_index == other.m_index; | |
392 } | |
393 | |
394 reference dereference() const | |
395 { | |
396 update(); | |
397 return *m_it; | |
252 } | 398 } |
253 | 399 |
254 private: | 400 private: |
401 mutable base_iterator m_it; | |
255 base_iterator m_first; | 402 base_iterator m_first; |
256 base_iterator m_last; | |
257 difference_type m_index; | 403 difference_type m_index; |
258 difference_type m_stride; | 404 difference_type m_stride; |
259 }; | 405 }; |
260 | 406 |
261 template<class BaseIterator, class Difference> inline | 407 template<class Rng, class Difference> inline |
262 strided_iterator<BaseIterator, BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type> | 408 strided_iterator< |
263 make_strided_iterator(BaseIterator first, BaseIterator it, | 409 typename range_iterator<Rng>::type, |
264 BaseIterator last, Difference stride) | 410 forward_traversal_tag |
265 { | 411 > |
266 BOOST_ASSERT( stride >= 0 ); | 412 make_begin_strided_iterator( |
267 typedef BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type traversal_tag; | 413 Rng& rng, |
268 return strided_iterator<BaseIterator, traversal_tag>(first, it, last, stride); | 414 Difference stride, |
269 } | 415 forward_traversal_tag) |
270 | 416 { |
271 template< class Rng | 417 return strided_iterator< |
272 , class Category = BOOST_DEDUCED_TYPENAME iterator_traversal< | 418 typename range_iterator<Rng>::type, |
273 BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type | 419 forward_traversal_tag |
274 >::type | 420 >(boost::begin(rng), boost::end(rng), stride); |
275 > | 421 } |
422 | |
423 template<class Rng, class Difference> inline | |
424 strided_iterator< | |
425 typename range_iterator<const Rng>::type, | |
426 forward_traversal_tag | |
427 > | |
428 make_begin_strided_iterator( | |
429 const Rng& rng, | |
430 Difference stride, | |
431 forward_traversal_tag) | |
432 { | |
433 return strided_iterator< | |
434 typename range_iterator<const Rng>::type, | |
435 forward_traversal_tag | |
436 >(boost::begin(rng), boost::end(rng), stride); | |
437 } | |
438 | |
439 template<class Rng, class Difference> inline | |
440 strided_iterator< | |
441 typename range_iterator<Rng>::type, | |
442 forward_traversal_tag | |
443 > | |
444 make_end_strided_iterator( | |
445 Rng& rng, | |
446 Difference stride, | |
447 forward_traversal_tag) | |
448 { | |
449 return strided_iterator< | |
450 typename range_iterator<Rng>::type, | |
451 forward_traversal_tag | |
452 >(boost::end(rng), boost::end(rng), stride); | |
453 } | |
454 | |
455 template<class Rng, class Difference> inline | |
456 strided_iterator< | |
457 typename range_iterator<const Rng>::type, | |
458 forward_traversal_tag | |
459 > | |
460 make_end_strided_iterator( | |
461 const Rng& rng, | |
462 Difference stride, | |
463 forward_traversal_tag) | |
464 { | |
465 return strided_iterator< | |
466 typename range_iterator<const Rng>::type, | |
467 forward_traversal_tag | |
468 >(boost::end(rng), boost::end(rng), stride); | |
469 } | |
470 | |
471 template<class Rng, class Difference> inline | |
472 strided_iterator< | |
473 typename range_iterator<Rng>::type, | |
474 bidirectional_traversal_tag | |
475 > | |
476 make_begin_strided_iterator( | |
477 Rng& rng, | |
478 Difference stride, | |
479 bidirectional_traversal_tag) | |
480 { | |
481 typedef typename range_difference<Rng>::type difference_type; | |
482 | |
483 return strided_iterator< | |
484 typename range_iterator<Rng>::type, | |
485 bidirectional_traversal_tag | |
486 >(boost::begin(rng), difference_type(), stride); | |
487 } | |
488 | |
489 template<class Rng, class Difference> inline | |
490 strided_iterator< | |
491 typename range_iterator<const Rng>::type, | |
492 bidirectional_traversal_tag | |
493 > | |
494 make_begin_strided_iterator( | |
495 const Rng& rng, | |
496 Difference stride, | |
497 bidirectional_traversal_tag) | |
498 { | |
499 typedef typename range_difference<const Rng>::type difference_type; | |
500 | |
501 return strided_iterator< | |
502 typename range_iterator<const Rng>::type, | |
503 bidirectional_traversal_tag | |
504 >(boost::begin(rng), difference_type(), stride); | |
505 } | |
506 | |
507 template<class Rng, class Difference> inline | |
508 strided_iterator< | |
509 typename range_iterator<Rng>::type, | |
510 bidirectional_traversal_tag | |
511 > | |
512 make_end_strided_iterator( | |
513 Rng& rng, | |
514 Difference stride, | |
515 bidirectional_traversal_tag) | |
516 { | |
517 return strided_iterator< | |
518 typename range_iterator<Rng>::type, | |
519 bidirectional_traversal_tag | |
520 >(boost::end(rng), boost::size(rng), stride); | |
521 } | |
522 | |
523 template<class Rng, class Difference> inline | |
524 strided_iterator< | |
525 typename range_iterator<const Rng>::type, | |
526 bidirectional_traversal_tag | |
527 > | |
528 make_end_strided_iterator( | |
529 const Rng& rng, | |
530 Difference stride, | |
531 bidirectional_traversal_tag) | |
532 { | |
533 return strided_iterator< | |
534 typename range_iterator<const Rng>::type, | |
535 bidirectional_traversal_tag | |
536 >(boost::end(rng), boost::size(rng), stride); | |
537 } | |
538 | |
539 template<class Rng, class Difference> inline | |
540 strided_iterator< | |
541 typename range_iterator<Rng>::type, | |
542 random_access_traversal_tag | |
543 > | |
544 make_begin_strided_iterator( | |
545 Rng& rng, | |
546 Difference stride, | |
547 random_access_traversal_tag) | |
548 { | |
549 return strided_iterator< | |
550 typename range_iterator<Rng>::type, | |
551 random_access_traversal_tag | |
552 >(boost::begin(rng), boost::begin(rng), stride); | |
553 } | |
554 | |
555 template<class Rng, class Difference> inline | |
556 strided_iterator< | |
557 typename range_iterator<const Rng>::type, | |
558 random_access_traversal_tag | |
559 > | |
560 make_begin_strided_iterator( | |
561 const Rng& rng, | |
562 Difference stride, | |
563 random_access_traversal_tag) | |
564 { | |
565 return strided_iterator< | |
566 typename range_iterator<const Rng>::type, | |
567 random_access_traversal_tag | |
568 >(boost::begin(rng), boost::begin(rng), stride); | |
569 } | |
570 | |
571 template<class Rng, class Difference> inline | |
572 strided_iterator< | |
573 typename range_iterator<Rng>::type, | |
574 random_access_traversal_tag | |
575 > | |
576 make_end_strided_iterator( | |
577 Rng& rng, | |
578 Difference stride, | |
579 random_access_traversal_tag) | |
580 { | |
581 return strided_iterator< | |
582 typename range_iterator<Rng>::type, | |
583 random_access_traversal_tag | |
584 >(boost::begin(rng), boost::end(rng), stride); | |
585 } | |
586 | |
587 template<class Rng, class Difference> inline | |
588 strided_iterator< | |
589 typename range_iterator<const Rng>::type, | |
590 random_access_traversal_tag | |
591 > | |
592 make_end_strided_iterator( | |
593 const Rng& rng, | |
594 Difference stride, | |
595 random_access_traversal_tag) | |
596 { | |
597 return strided_iterator< | |
598 typename range_iterator<const Rng>::type, | |
599 random_access_traversal_tag | |
600 >(boost::begin(rng), boost::end(rng), stride); | |
601 } | |
602 | |
603 template< | |
604 class Rng, | |
605 class Category = | |
606 typename iterator_traversal< | |
607 typename range_iterator<Rng>::type | |
608 >::type | |
609 > | |
276 class strided_range | 610 class strided_range |
277 : public iterator_range< | 611 : public iterator_range< |
278 range_detail::strided_iterator< | 612 range_detail::strided_iterator< |
279 BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type, | 613 typename range_iterator<Rng>::type, |
280 Category | 614 Category |
281 > | 615 > |
282 > | 616 > |
283 { | 617 { |
284 typedef range_detail::strided_iterator< | 618 typedef range_detail::strided_iterator< |
285 BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type, | 619 typename range_iterator<Rng>::type, |
286 Category | 620 Category |
287 > iter_type; | 621 > iter_type; |
288 typedef iterator_range<iter_type> super_t; | 622 typedef iterator_range<iter_type> super_t; |
289 public: | 623 public: |
290 template<class Difference> | 624 template<class Difference> |
291 strided_range(Difference stride, Rng& rng) | 625 strided_range(Difference stride, Rng& rng) |
292 : super_t(make_strided_iterator(boost::begin(rng), boost::begin(rng), boost::end(rng), stride), | 626 : super_t( |
293 make_strided_iterator(boost::begin(rng), boost::end(rng), boost::end(rng), stride)) | 627 range_detail::make_begin_strided_iterator( |
628 rng, stride, | |
629 typename iterator_traversal< | |
630 typename range_iterator<Rng>::type | |
631 >::type()), | |
632 range_detail::make_end_strided_iterator( | |
633 rng, stride, | |
634 typename iterator_traversal< | |
635 typename range_iterator<Rng>::type | |
636 >::type())) | |
294 { | 637 { |
295 BOOST_ASSERT( stride >= 0 ); | 638 BOOST_ASSERT( stride >= 0 ); |
296 } | 639 } |
297 }; | 640 }; |
298 | 641 |
299 template<class Difference> | 642 template<class Difference> |
300 class strided_holder : public holder<Difference> | 643 class strided_holder : public holder<Difference> |
301 { | 644 { |
302 public: | 645 public: |
303 explicit strided_holder(Difference value) : holder<Difference>(value) {} | 646 explicit strided_holder(Difference value) |
647 : holder<Difference>(value) | |
648 { | |
649 } | |
304 }; | 650 }; |
305 | 651 |
306 template<class Rng, class Difference> | 652 template<class Rng, class Difference> |
307 inline strided_range<Rng> | 653 inline strided_range<Rng> |
308 operator|(Rng& rng, const strided_holder<Difference>& stride) | 654 operator|(Rng& rng, const strided_holder<Difference>& stride) |
325 { | 671 { |
326 | 672 |
327 namespace | 673 namespace |
328 { | 674 { |
329 const range_detail::forwarder<range_detail::strided_holder> | 675 const range_detail::forwarder<range_detail::strided_holder> |
330 strided = range_detail::forwarder<range_detail::strided_holder>(); | 676 strided = range_detail::forwarder< |
677 range_detail::strided_holder>(); | |
331 } | 678 } |
332 | 679 |
333 template<class Range, class Difference> | 680 template<class Range, class Difference> |
334 inline strided_range<Range> | 681 inline strided_range<Range> |
335 stride(Range& rng, Difference step) | 682 stride(Range& rng, Difference step) |