transform_iterator.qbk 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. [section:transform Transform Iterator]
  2. The transform iterator adapts an iterator by modifying the
  3. `operator*` to apply a function object to the result of
  4. dereferencing the iterator and returning the result.
  5. [h2 Example]
  6. This is a simple example of using the transform_iterators class to
  7. generate iterators that multiply (or add to) the value returned by
  8. dereferencing the iterator. It would be cooler to use lambda library
  9. in this example.
  10. int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
  11. const int N = sizeof(x)/sizeof(int);
  12. typedef boost::binder1st< std::multiplies<int> > Function;
  13. typedef boost::transform_iterator<Function, int*> doubling_iterator;
  14. doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
  15. i_end(x + N, boost::bind1st(std::multiplies<int>(), 2));
  16. std::cout << "multiplying the array by 2:" << std::endl;
  17. while (i != i_end)
  18. std::cout << *i++ << " ";
  19. std::cout << std::endl;
  20. std::cout << "adding 4 to each element in the array:" << std::endl;
  21. std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
  22. boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
  23. std::ostream_iterator<int>(std::cout, " "));
  24. std::cout << std::endl;
  25. The output is:
  26. multiplying the array by 2:
  27. 2 4 6 8 10 12 14 16
  28. adding 4 to each element in the array:
  29. 5 6 7 8 9 10 11 12
  30. The source code for this example can be found
  31. [@../example/transform_iterator_example.cpp here].
  32. [h2 Reference]
  33. [h3 Synopsis]
  34. template <class UnaryFunction,
  35. class Iterator,
  36. class Reference = use_default,
  37. class Value = use_default>
  38. class transform_iterator
  39. {
  40. public:
  41. typedef /* see below */ value_type;
  42. typedef /* see below */ reference;
  43. typedef /* see below */ pointer;
  44. typedef iterator_traits<Iterator>::difference_type difference_type;
  45. typedef /* see below */ iterator_category;
  46. transform_iterator();
  47. transform_iterator(Iterator const& x, UnaryFunction f);
  48. template<class F2, class I2, class R2, class V2>
  49. transform_iterator(
  50. transform_iterator<F2, I2, R2, V2> const& t
  51. , typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
  52. , typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
  53. );
  54. UnaryFunction functor() const;
  55. Iterator const& base() const;
  56. reference operator*() const;
  57. transform_iterator& operator++();
  58. transform_iterator& operator--();
  59. private:
  60. Iterator m_iterator; // exposition only
  61. UnaryFunction m_f; // exposition only
  62. };
  63. If `Reference` is `use_default` then the `reference` member of
  64. `transform_iterator` is[br]
  65. `result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
  66. Otherwise, `reference` is `Reference`.
  67. If `Value` is `use_default` then the `value_type` member is
  68. `remove_cv<remove_reference<reference> >::type`. Otherwise,
  69. `value_type` is `Value`.
  70. If `Iterator` models Readable Lvalue Iterator and if `Iterator`
  71. models Random Access Traversal Iterator, then `iterator_category` is
  72. convertible to `random_access_iterator_tag`. Otherwise, if
  73. `Iterator` models Bidirectional Traversal Iterator, then
  74. `iterator_category` is convertible to
  75. `bidirectional_iterator_tag`. Otherwise `iterator_category` is
  76. convertible to `forward_iterator_tag`. If `Iterator` does not
  77. model Readable Lvalue Iterator then `iterator_category` is
  78. convertible to `input_iterator_tag`.
  79. [h3 Requirements]
  80. The type `UnaryFunction` must be Assignable, Copy Constructible, and
  81. the expression `f(*i)` must be valid where `f` is a const object of
  82. type `UnaryFunction`, `i` is an object of type `Iterator`, and
  83. where the type of `f(*i)` must be
  84. `result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
  85. The argument `Iterator` shall model Readable Iterator.
  86. [h3 Concepts]
  87. The resulting `transform_iterator` models the most refined of the
  88. following that is also modeled by `Iterator`.
  89. * Writable Lvalue Iterator if `transform_iterator::reference` is a non-const reference.
  90. * Readable Lvalue Iterator if `transform_iterator::reference` is a const reference.
  91. * Readable Iterator otherwise.
  92. The `transform_iterator` models the most refined standard traversal
  93. concept that is modeled by the `Iterator` argument.
  94. If `transform_iterator` is a model of Readable Lvalue Iterator then
  95. it models the following original iterator concepts depending on what
  96. the `Iterator` argument models.
  97. [table Category
  98. [[If `Iterator` models][then `transform_iterator` models]]
  99. [[Single Pass Iterator][Input Iterator]]
  100. [[Forward Traversal Iterator][Forward Iterator]]
  101. [[Bidirectional Traversal Iterator][Bidirectional Iterator]]
  102. [[Random Access Traversal Iterator][Random Access Iterator]]
  103. ]
  104. If `transform_iterator` models Writable Lvalue Iterator then it is a
  105. mutable iterator (as defined in the old iterator requirements).
  106. `transform_iterator<F1, X, R1, V1>` is interoperable with
  107. `transform_iterator<F2, Y, R2, V2>` if and only if `X` is
  108. interoperable with `Y`.
  109. [h3 Operations]
  110. In addition to the operations required by the [link iterator.specialized.transform.concepts concepts] modeled by
  111. `transform_iterator`, `transform_iterator` provides the following
  112. operations:
  113. transform_iterator();
  114. [*Returns: ] An instance of `transform_iterator` with `m_f`
  115. and `m_iterator` default constructed.
  116. transform_iterator(Iterator const& x, UnaryFunction f);
  117. [*Returns: ] An instance of `transform_iterator` with `m_f`
  118. initialized to `f` and `m_iterator` initialized to `x`.
  119. template<class F2, class I2, class R2, class V2>
  120. transform_iterator(
  121. transform_iterator<F2, I2, R2, V2> const& t
  122. , typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
  123. , typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
  124. );
  125. [*Returns: ] An instance of `transform_iterator` with `m_f`
  126. initialized to `t.functor()` and `m_iterator` initialized to
  127. `t.base()`.[br]
  128. [*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.
  129. UnaryFunction functor() const;
  130. [*Returns: ] `m_f`
  131. Iterator const& base() const;
  132. [*Returns: ] `m_iterator`
  133. reference operator*() const;
  134. [*Returns: ] `m_f(*m_iterator)`
  135. transform_iterator& operator++();
  136. [*Effects: ] `++m_iterator`[br]
  137. [*Returns: ] `*this`
  138. transform_iterator& operator--();
  139. [*Effects: ] `--m_iterator`[br]
  140. [*Returns: ] `*this`
  141. [endsect]