| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  | [section:counting Counting Iterator] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A `counting_iterator` adapts an object by adding an `operator*` that | 
					
						
							|  |  |  | returns the current value of the object. All other iterator operations | 
					
						
							|  |  |  | are forwarded to the adapted object. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [h2 Example] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This example fills an array with numbers and a second array with | 
					
						
							|  |  |  | pointers into the first array, using `counting_iterator` for both | 
					
						
							|  |  |  | tasks. Finally `indirect_iterator` is used to print out the numbers | 
					
						
							|  |  |  | into the first array via indirection through the second array. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int N = 7; | 
					
						
							|  |  |  |     std::vector<int> numbers; | 
					
						
							|  |  |  |     typedef std::vector<int>::iterator n_iter; | 
					
						
							|  |  |  |     std::copy(boost::counting_iterator<int>(0), | 
					
						
							| 
									
										
										
										
											2019-12-12 12:35:38 +03:00
										 |  |  |               boost::counting_iterator<int>(N), | 
					
						
							|  |  |  |               std::back_inserter(numbers)); | 
					
						
							| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     std::vector<std::vector<int>::iterator> pointers; | 
					
						
							|  |  |  |     std::copy(boost::make_counting_iterator(numbers.begin()), | 
					
						
							| 
									
										
										
										
											2019-12-12 12:35:38 +03:00
										 |  |  |         boost::make_counting_iterator(numbers.end()), | 
					
						
							|  |  |  |         std::back_inserter(pointers)); | 
					
						
							| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 12:35:38 +03:00
										 |  |  |     std::cout << "indirectly printing out the numbers from 0 to " | 
					
						
							|  |  |  |         << N << std::endl; | 
					
						
							| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  |     std::copy(boost::make_indirect_iterator(pointers.begin()), | 
					
						
							| 
									
										
										
										
											2019-12-12 12:35:38 +03:00
										 |  |  |         boost::make_indirect_iterator(pointers.end()), | 
					
						
							|  |  |  |         std::ostream_iterator<int>(std::cout, " ")); | 
					
						
							| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  |     std::cout << std::endl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The output is: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 12:35:38 +03:00
										 |  |  | [pre | 
					
						
							|  |  |  | indirectly printing out the numbers from 0 to 7 | 
					
						
							|  |  |  | 0 1 2 3 4 5 6 | 
					
						
							|  |  |  | ] | 
					
						
							| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 12:16:01 +03:00
										 |  |  | The source code for this example can be found [example_link counting_iterator_example.cpp..here]. | 
					
						
							| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | [h2 Reference] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [h3 Synopsis] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   template < | 
					
						
							|  |  |  |       class Incrementable | 
					
						
							|  |  |  |     , class CategoryOrTraversal = use_default | 
					
						
							|  |  |  |     , class Difference = use_default | 
					
						
							|  |  |  |   > | 
					
						
							|  |  |  |   class counting_iterator | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  |       typedef Incrementable value_type; | 
					
						
							|  |  |  |       typedef const Incrementable& reference; | 
					
						
							|  |  |  |       typedef const Incrementable* pointer; | 
					
						
							|  |  |  |       typedef /* see below */ difference_type; | 
					
						
							|  |  |  |       typedef /* see below */ iterator_category; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       counting_iterator(); | 
					
						
							|  |  |  |       counting_iterator(counting_iterator const& rhs); | 
					
						
							|  |  |  |       explicit counting_iterator(Incrementable x); | 
					
						
							|  |  |  |       Incrementable const& base() const; | 
					
						
							|  |  |  |       reference operator*() const; | 
					
						
							|  |  |  |       counting_iterator& operator++(); | 
					
						
							|  |  |  |       counting_iterator& operator--(); | 
					
						
							|  |  |  |   private: | 
					
						
							|  |  |  |       Incrementable m_inc; // exposition | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If the `Difference` argument is `use_default` then | 
					
						
							|  |  |  | `difference_type` is an unspecified signed integral | 
					
						
							|  |  |  | type. Otherwise `difference_type` is `Difference`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `iterator_category` is determined according to the following | 
					
						
							|  |  |  | algorithm: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    if (CategoryOrTraversal is not use_default) | 
					
						
							|  |  |  |        return CategoryOrTraversal | 
					
						
							|  |  |  |    else if (numeric_limits<Incrementable>::is_specialized) | 
					
						
							|  |  |  |        return |iterator-category|_\ ( | 
					
						
							|  |  |  |            random_access_traversal_tag, Incrementable, const Incrementable&) | 
					
						
							|  |  |  |    else | 
					
						
							|  |  |  |        return |iterator-category|_\ ( | 
					
						
							| 
									
										
										
										
											2019-12-12 12:35:38 +03:00
										 |  |  |             iterator_traversal<Incrementable>::type, | 
					
						
							| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  |             Incrementable, const Incrementable&) | 
					
						
							| 
									
										
										
										
											2019-12-12 12:35:38 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  | [blurb *Note:* implementers are encouraged to provide an implementation of | 
					
						
							|  |  |  |   `operator-` and a `difference_type` that avoids overflows in | 
					
						
							|  |  |  |   the cases where `std::numeric_limits<Incrementable>::is_specialized` | 
					
						
							|  |  |  |   is true.] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [h3 Requirements] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `Incrementable` argument shall be Copy Constructible and Assignable. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If `iterator_category` is convertible to `forward_iterator_tag` | 
					
						
							|  |  |  | or `forward_traversal_tag`, the following must be well-formed: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Incrementable i, j; | 
					
						
							|  |  |  |     ++i;         // pre-increment | 
					
						
							|  |  |  |     i == j;      // operator equal | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If `iterator_category` is convertible to | 
					
						
							|  |  |  | `bidirectional_iterator_tag` or `bidirectional_traversal_tag`, | 
					
						
							|  |  |  | the following expression must also be well-formed: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     --i | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If `iterator_category` is convertible to | 
					
						
							|  |  |  | `random_access_iterator_tag` or `random_access_traversal_tag`, | 
					
						
							|  |  |  | the following must must also be valid: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     counting_iterator::difference_type n; | 
					
						
							|  |  |  |     i += n; | 
					
						
							|  |  |  |     n = i - j; | 
					
						
							|  |  |  |     i < j; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [h3 Concepts] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Specializations of `counting_iterator` model Readable Lvalue | 
					
						
							|  |  |  | Iterator. In addition, they model the concepts corresponding to the | 
					
						
							|  |  |  | iterator tags to which their `iterator_category` is convertible. | 
					
						
							|  |  |  | Also, if `CategoryOrTraversal` is not `use_default` then | 
					
						
							|  |  |  | `counting_iterator` models the concept corresponding to the iterator | 
					
						
							|  |  |  | tag `CategoryOrTraversal`.  Otherwise, if | 
					
						
							|  |  |  | `numeric_limits<Incrementable>::is_specialized`, then | 
					
						
							|  |  |  | `counting_iterator` models Random Access Traversal Iterator. | 
					
						
							|  |  |  | Otherwise, `counting_iterator` models the same iterator traversal | 
					
						
							|  |  |  | concepts modeled by `Incrementable`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `counting_iterator<X,C1,D1>` is interoperable with | 
					
						
							|  |  |  | `counting_iterator<Y,C2,D2>` if and only if `X` is | 
					
						
							|  |  |  | interoperable with `Y`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [h3 Operations] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In addition to the operations required by the concepts modeled by | 
					
						
							|  |  |  | `counting_iterator`, `counting_iterator` provides the following | 
					
						
							|  |  |  | operations. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   counting_iterator(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 12:49:59 -04:00
										 |  |  | [*Requires: ] `Incrementable` is Default Constructible.[br] | 
					
						
							| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  | [*Effects: ] Default construct the member `m_inc`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   counting_iterator(counting_iterator const& rhs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [*Effects: ] Construct member `m_inc` from `rhs.m_inc`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   explicit counting_iterator(Incrementable x); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [*Effects: ] Construct member `m_inc` from `x`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   reference operator*() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [*Returns: ] `m_inc` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   counting_iterator& operator++(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 12:49:59 -04:00
										 |  |  | [*Effects: ] `++m_inc`[br] | 
					
						
							| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  | [*Returns: ] `*this` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   counting_iterator& operator--(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 12:49:59 -04:00
										 |  |  | [*Effects: ] `--m_inc`[br] | 
					
						
							| 
									
										
										
										
											2019-12-12 12:35:38 +03:00
										 |  |  | [*Returns: ] `*this` | 
					
						
							| 
									
										
										
										
											2005-09-13 22:42:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Incrementable const& base() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [*Returns: ] `m_inc` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 12:35:38 +03:00
										 |  |  | [endsect] |