mirror of
				https://github.com/boostorg/iterator.git
				synced 2025-10-31 08:21:37 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			194 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			194 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| [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),
 | |
|               boost::counting_iterator<int>(N),
 | |
|               std::back_inserter(numbers));
 | |
| 
 | |
|     std::vector<std::vector<int>::iterator> pointers;
 | |
|     std::copy(boost::make_counting_iterator(numbers.begin()),
 | |
|         boost::make_counting_iterator(numbers.end()),
 | |
|         std::back_inserter(pointers));
 | |
| 
 | |
|     std::cout << "indirectly printing out the numbers from 0 to "
 | |
|         << N << std::endl;
 | |
|     std::copy(boost::make_indirect_iterator(pointers.begin()),
 | |
|         boost::make_indirect_iterator(pointers.end()),
 | |
|         std::ostream_iterator<int>(std::cout, " "));
 | |
|     std::cout << std::endl;
 | |
| 
 | |
| 
 | |
| The output is:
 | |
| 
 | |
| [pre
 | |
| indirectly printing out the numbers from 0 to 7
 | |
| 0 1 2 3 4 5 6
 | |
| ]
 | |
| 
 | |
| The source code for this example can be found [example_link counting_iterator_example.cpp..here].
 | |
| 
 | |
| [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|_\ (
 | |
|             iterator_traversal<Incrementable>::type,
 | |
|             Incrementable, const Incrementable&)
 | |
| 
 | |
| [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();
 | |
| 
 | |
| [*Requires: ] `Incrementable` is Default Constructible.[br]
 | |
| [*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++();
 | |
| 
 | |
| [*Effects: ] `++m_inc`[br]
 | |
| [*Returns: ] `*this`
 | |
| 
 | |
| 
 | |
|   counting_iterator& operator--();
 | |
| 
 | |
| [*Effects: ] `--m_inc`[br]
 | |
| [*Returns: ] `*this`
 | |
| 
 | |
| 
 | |
|   Incrementable const& base() const;
 | |
| 
 | |
| [*Returns: ] `m_inc`
 | |
| 
 | |
| 
 | |
| [endsect]
 |