function_input_iterator.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // Copyright 2009 (C) Dean Michael Berris <[email protected]>
  2. // Copyright 2012 (C) Google, Inc.
  3. // Copyright 2012 (C) Jeffrey Lee Hellrung, Jr.
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. #ifndef BOOST_FUNCTION_INPUT_ITERATOR
  9. #define BOOST_FUNCTION_INPUT_ITERATOR
  10. #include <boost/config.hpp>
  11. #include <boost/assert.hpp>
  12. #include <boost/core/addressof.hpp>
  13. #include <boost/mpl/if.hpp>
  14. #include <boost/function_types/is_function_pointer.hpp>
  15. #include <boost/function_types/result_type.hpp>
  16. #include <boost/iterator/iterator_facade.hpp>
  17. #include <boost/none.hpp>
  18. #include <boost/optional/optional.hpp>
  19. #include <boost/utility/result_of.hpp>
  20. #ifdef BOOST_RESULT_OF_USE_TR1
  21. #include <boost/type_traits/is_function.hpp>
  22. #endif
  23. namespace boost {
  24. namespace iterators {
  25. namespace impl {
  26. // Computes the return type of an lvalue-call with an empty argument,
  27. // i.e. decltype(declval<F&>()()). F should be a nullary lvalue-callable
  28. // or function.
  29. template <class F>
  30. struct result_of_nullary_lvalue_call
  31. {
  32. typedef typename result_of<
  33. #ifdef BOOST_RESULT_OF_USE_TR1
  34. typename mpl::if_<is_function<F>, F&, F>::type()
  35. #else
  36. F&()
  37. #endif
  38. >::type type;
  39. };
  40. template <class Function, class Input>
  41. class function_input_iterator
  42. : public iterator_facade<
  43. function_input_iterator<Function, Input>,
  44. typename result_of_nullary_lvalue_call<Function>::type,
  45. single_pass_traversal_tag,
  46. typename result_of_nullary_lvalue_call<Function>::type const &
  47. >
  48. {
  49. public:
  50. function_input_iterator() {}
  51. function_input_iterator(Function & f_, Input state_ = Input())
  52. : f(boost::addressof(f_)), state(state_) {}
  53. void increment() {
  54. if(value)
  55. value = none;
  56. else
  57. (*f)();
  58. ++state;
  59. }
  60. typename result_of_nullary_lvalue_call<Function>::type const &
  61. dereference() const {
  62. return (value ? value : value = (*f)()).get();
  63. }
  64. bool equal(function_input_iterator const & other) const {
  65. return f == other.f && state == other.state;
  66. }
  67. private:
  68. Function * f;
  69. Input state;
  70. mutable optional<typename result_of_nullary_lvalue_call<Function>::type> value;
  71. };
  72. template <class Function, class Input>
  73. class function_pointer_input_iterator
  74. : public iterator_facade<
  75. function_pointer_input_iterator<Function, Input>,
  76. typename function_types::result_type<Function>::type,
  77. single_pass_traversal_tag,
  78. typename function_types::result_type<Function>::type const &
  79. >
  80. {
  81. public:
  82. function_pointer_input_iterator() {}
  83. function_pointer_input_iterator(Function &f_, Input state_ = Input())
  84. : f(f_), state(state_) {}
  85. void increment() {
  86. if(value)
  87. value = none;
  88. else
  89. (*f)();
  90. ++state;
  91. }
  92. typename function_types::result_type<Function>::type const &
  93. dereference() const {
  94. return (value ? value : value = (*f)()).get();
  95. }
  96. bool equal(function_pointer_input_iterator const & other) const {
  97. return f == other.f && state == other.state;
  98. }
  99. private:
  100. Function f;
  101. Input state;
  102. mutable optional<typename function_types::result_type<Function>::type> value;
  103. };
  104. } // namespace impl
  105. template <class Function, class Input>
  106. class function_input_iterator
  107. : public mpl::if_<
  108. function_types::is_function_pointer<Function>,
  109. impl::function_pointer_input_iterator<Function,Input>,
  110. impl::function_input_iterator<Function,Input>
  111. >::type
  112. {
  113. typedef typename mpl::if_<
  114. function_types::is_function_pointer<Function>,
  115. impl::function_pointer_input_iterator<Function,Input>,
  116. impl::function_input_iterator<Function,Input>
  117. >::type base_type;
  118. public:
  119. function_input_iterator(Function & f, Input i)
  120. : base_type(f, i) {}
  121. };
  122. template <class Function, class Input>
  123. inline function_input_iterator<Function, Input>
  124. make_function_input_iterator(Function & f, Input state) {
  125. typedef function_input_iterator<Function, Input> result_t;
  126. return result_t(f, state);
  127. }
  128. template <class Function, class Input>
  129. inline function_input_iterator<Function*, Input>
  130. make_function_input_iterator(Function * f, Input state) {
  131. typedef function_input_iterator<Function*, Input> result_t;
  132. return result_t(f, state);
  133. }
  134. struct infinite {
  135. infinite & operator++() { return *this; }
  136. infinite & operator++(int) { return *this; }
  137. bool operator==(infinite &) const { return false; };
  138. bool operator==(infinite const &) const { return false; };
  139. };
  140. } // namespace iterators
  141. using iterators::function_input_iterator;
  142. using iterators::make_function_input_iterator;
  143. using iterators::infinite;
  144. } // namespace boost
  145. #endif