counting_iterator.qbk 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. [section:counting Counting Iterator]
  2. A `counting_iterator` adapts an object by adding an `operator*` that
  3. returns the current value of the object. All other iterator operations
  4. are forwarded to the adapted object.
  5. [h2 Example]
  6. This example fills an array with numbers and a second array with
  7. pointers into the first array, using `counting_iterator` for both
  8. tasks. Finally `indirect_iterator` is used to print out the numbers
  9. into the first array via indirection through the second array.
  10. int N = 7;
  11. std::vector<int> numbers;
  12. typedef std::vector<int>::iterator n_iter;
  13. std::copy(boost::counting_iterator<int>(0),
  14. boost::counting_iterator<int>(N),
  15. std::back_inserter(numbers));
  16. std::vector<std::vector<int>::iterator> pointers;
  17. std::copy(boost::make_counting_iterator(numbers.begin()),
  18. boost::make_counting_iterator(numbers.end()),
  19. std::back_inserter(pointers));
  20. std::cout << "indirectly printing out the numbers from 0 to "
  21. << N << std::endl;
  22. std::copy(boost::make_indirect_iterator(pointers.begin()),
  23. boost::make_indirect_iterator(pointers.end()),
  24. std::ostream_iterator<int>(std::cout, " "));
  25. std::cout << std::endl;
  26. The output is:
  27. indirectly printing out the numbers from 0 to 7
  28. 0 1 2 3 4 5 6
  29. The source code for this example can be found [@../example/counting_iterator_example.cpp here].
  30. [h2 Reference]
  31. [h3 Synopsis]
  32. template <
  33. class Incrementable
  34. , class CategoryOrTraversal = use_default
  35. , class Difference = use_default
  36. >
  37. class counting_iterator
  38. {
  39. public:
  40. typedef Incrementable value_type;
  41. typedef const Incrementable& reference;
  42. typedef const Incrementable* pointer;
  43. typedef /* see below */ difference_type;
  44. typedef /* see below */ iterator_category;
  45. counting_iterator();
  46. counting_iterator(counting_iterator const& rhs);
  47. explicit counting_iterator(Incrementable x);
  48. Incrementable const& base() const;
  49. reference operator*() const;
  50. counting_iterator& operator++();
  51. counting_iterator& operator--();
  52. private:
  53. Incrementable m_inc; // exposition
  54. };
  55. If the `Difference` argument is `use_default` then
  56. `difference_type` is an unspecified signed integral
  57. type. Otherwise `difference_type` is `Difference`.
  58. `iterator_category` is determined according to the following
  59. algorithm:
  60. if (CategoryOrTraversal is not use_default)
  61. return CategoryOrTraversal
  62. else if (numeric_limits<Incrementable>::is_specialized)
  63. return |iterator-category|_\ (
  64. random_access_traversal_tag, Incrementable, const Incrementable&)
  65. else
  66. return |iterator-category|_\ (
  67. iterator_traversal<Incrementable>::type,
  68. Incrementable, const Incrementable&)
  69. [blurb *Note:* implementers are encouraged to provide an implementation of
  70. `operator-` and a `difference_type` that avoids overflows in
  71. the cases where `std::numeric_limits<Incrementable>::is_specialized`
  72. is true.]
  73. [h3 Requirements]
  74. The `Incrementable` argument shall be Copy Constructible and Assignable.
  75. If `iterator_category` is convertible to `forward_iterator_tag`
  76. or `forward_traversal_tag`, the following must be well-formed:
  77. Incrementable i, j;
  78. ++i; // pre-increment
  79. i == j; // operator equal
  80. If `iterator_category` is convertible to
  81. `bidirectional_iterator_tag` or `bidirectional_traversal_tag`,
  82. the following expression must also be well-formed:
  83. --i
  84. If `iterator_category` is convertible to
  85. `random_access_iterator_tag` or `random_access_traversal_tag`,
  86. the following must must also be valid:
  87. counting_iterator::difference_type n;
  88. i += n;
  89. n = i - j;
  90. i < j;
  91. [h3 Concepts]
  92. Specializations of `counting_iterator` model Readable Lvalue
  93. Iterator. In addition, they model the concepts corresponding to the
  94. iterator tags to which their `iterator_category` is convertible.
  95. Also, if `CategoryOrTraversal` is not `use_default` then
  96. `counting_iterator` models the concept corresponding to the iterator
  97. tag `CategoryOrTraversal`. Otherwise, if
  98. `numeric_limits<Incrementable>::is_specialized`, then
  99. `counting_iterator` models Random Access Traversal Iterator.
  100. Otherwise, `counting_iterator` models the same iterator traversal
  101. concepts modeled by `Incrementable`.
  102. `counting_iterator<X,C1,D1>` is interoperable with
  103. `counting_iterator<Y,C2,D2>` if and only if `X` is
  104. interoperable with `Y`.
  105. [h3 Operations]
  106. In addition to the operations required by the concepts modeled by
  107. `counting_iterator`, `counting_iterator` provides the following
  108. operations.
  109. counting_iterator();
  110. [*Requires: ] `Incrementable` is Default Constructible.[br]
  111. [*Effects: ] Default construct the member `m_inc`.
  112. counting_iterator(counting_iterator const& rhs);
  113. [*Effects: ] Construct member `m_inc` from `rhs.m_inc`.
  114. explicit counting_iterator(Incrementable x);
  115. [*Effects: ] Construct member `m_inc` from `x`.
  116. reference operator*() const;
  117. [*Returns: ] `m_inc`
  118. counting_iterator& operator++();
  119. [*Effects: ] `++m_inc`[br]
  120. [*Returns: ] `*this`
  121. counting_iterator& operator--();
  122. [*Effects: ] `--m_inc`[br]
  123. [*Returns: ] `*this`
  124. Incrementable const& base() const;
  125. [*Returns: ] `m_inc`
  126. [endsect]