function_input_iterator.rst 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. :Author:
  2. `Dean Michael Berris <mailto:me@deanberris.com>`_
  3. :License:
  4. Distributed under the Boost Software License, Version 1.0
  5. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. :Copyright:
  7. Copyright 2012 Google, Inc.
  8. Function Input Iterator
  9. =======================
  10. The Function Input Iterator allows for creating iterators that encapsulate
  11. a nullary function object and a state object which tracks the number of times
  12. the iterator has been incremented. A Function Input Iterator models the
  13. `InputIterator`_ concept and is useful for creating bounded input iterators.
  14. .. _InputIterator: http://www.sgi.com/tech/stl/InputIterator.html
  15. The Function Input Iterator takes a function that models the Generator_ concept
  16. (which is basically a nullary or 0-arity function object). The first dereference
  17. of the iterator at a given position invokes the generator function and stores
  18. and returns the result; subsequent dereferences at the same position simply
  19. return the same stored result. Incrementing the iterator places it at a new
  20. position, hence a subsequent dereference will generate a new value via another
  21. invokation of the generator function. This ensures the generator function is
  22. invoked precisely when the iterator is requested to return a (new) value.
  23. .. _Generator: http://www.sgi.com/tech/stl/Generator.html
  24. The Function Input Iterator encapsulates a state object which models the
  25. `Incrementable Concept`_ and the EqualityComparable_ Concept. These concepts are
  26. described below as:
  27. .. _EqualityComparable: http://www.sgi.com/tech/stl/EqualityComparable.html
  28. Incrementable Concept
  29. ---------------------
  30. A type models the Incrementable Concept when it supports the pre- and post-
  31. increment operators. For a given object ``i`` with type ``I``, the following
  32. constructs should be valid:
  33. ========= ================= ===========
  34. Construct Description Return Type
  35. -----------------------------------------
  36. i++ Post-increment i. I
  37. ++i Pre-increment i. I&
  38. ========= ================= ===========
  39. NOTE: An Incrementable type should also be DefaultConstructible_.
  40. .. _DefaultConstructible: http://www.sgi.com/tech/stl/DefaultConstructible.html
  41. Synopsis
  42. --------
  43. ::
  44. namespace {
  45. template <class Function, class State>
  46. class function_input_iterator;
  47. template <class Function, class State>
  48. typename function_input_iterator<Function, State>
  49. make_function_input_iterator(Function & f, State s);
  50. struct infinite;
  51. }
  52. Function Input Iterator Class
  53. -----------------------------
  54. The class Function Input Iterator class takes two template parameters
  55. ``Function`` and ``State``. These two template parameters tell the
  56. Function Input Iterator the type of the function to encapsulate and
  57. the type of the internal state value to hold.
  58. The ``State`` parameter is important in cases where you want to
  59. control the type of the counter which determines whether two iterators
  60. are at the same state. This allows for creating a pair of iterators which
  61. bound the range of the invocations of the encapsulated functions.
  62. Examples
  63. --------
  64. The following example shows how we use the function input iterator class
  65. in cases where we want to create bounded (lazy) generated ranges.
  66. ::
  67. struct generator {
  68. typedef int result_type;
  69. generator() { srand(time(0)); }
  70. result_type operator() () const {
  71. return rand();
  72. }
  73. };
  74. int main(int argc, char * argv[]) {
  75. generator f;
  76. copy(
  77. make_function_input_iterator(f, 0),
  78. make_function_input_iterator(f, 10),
  79. ostream_iterator<int>(cout, " ")
  80. );
  81. return 0;
  82. }
  83. Here we can see that we've bounded the number of invocations using an ``int``
  84. that counts from ``0`` to ``10``. Say we want to create an endless stream
  85. of random numbers and encapsulate that in a pair of integers, we can do
  86. it with the ``boost::infinite`` helper class.
  87. ::
  88. copy(
  89. make_function_input_iterator(f,infinite()),
  90. make_function_input_iterator(f,infinite()),
  91. ostream_iterator<int>(cout, " ")
  92. );
  93. Above, instead of creating a huge vector we rely on the STL copy algorithm
  94. to traverse the function input iterator and call the function object f
  95. as it increments the iterator. The special property of ``boost::infinite``
  96. is that equating two instances always yield false -- and that incrementing
  97. an instance of ``boost::infinite`` doesn't do anything. This is an efficient
  98. way of stating that the iterator range provided by two iterators with an
  99. encapsulated infinite state will definitely be infinite.