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)