annotate DEPENDENCIES/generic/include/boost/range/adaptor/strided.hpp @ 133:4acb5d8d80b6 tip

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