function_input_iterator.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright 2009 (C) Dean Michael Berris <me@deanberris.com>
  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/assert.hpp>
  11. #include <boost/mpl/if.hpp>
  12. #include <boost/function_types/is_function_pointer.hpp>
  13. #include <boost/function_types/is_function_reference.hpp>
  14. #include <boost/function_types/result_type.hpp>
  15. #include <boost/iterator/iterator_facade.hpp>
  16. #include <boost/none.hpp>
  17. #include <boost/optional/optional.hpp>
  18. namespace boost {
  19. namespace impl {
  20. template <class Function, class Input>
  21. class function_input_iterator
  22. : public iterator_facade<
  23. function_input_iterator<Function, Input>,
  24. typename Function::result_type,
  25. single_pass_traversal_tag,
  26. typename Function::result_type const &
  27. >
  28. {
  29. public:
  30. function_input_iterator() {}
  31. function_input_iterator(Function & f_, Input state_ = Input())
  32. : f(&f_), state(state_) {}
  33. void increment() {
  34. if(value)
  35. value = none;
  36. else
  37. (*f)();
  38. ++state;
  39. }
  40. typename Function::result_type const &
  41. dereference() const {
  42. return (value ? value : value = (*f)()).get();
  43. }
  44. bool equal(function_input_iterator const & other) const {
  45. return f == other.f && state == other.state;
  46. }
  47. private:
  48. Function * f;
  49. Input state;
  50. mutable optional<typename Function::result_type> value;
  51. };
  52. template <class Function, class Input>
  53. class function_pointer_input_iterator
  54. : public iterator_facade<
  55. function_pointer_input_iterator<Function, Input>,
  56. typename function_types::result_type<Function>::type,
  57. single_pass_traversal_tag,
  58. typename function_types::result_type<Function>::type const &
  59. >
  60. {
  61. public:
  62. function_pointer_input_iterator() {}
  63. function_pointer_input_iterator(Function &f_, Input state_ = Input())
  64. : f(f_), state(state_) {}
  65. void increment() {
  66. if(value)
  67. value = none;
  68. else
  69. (*f)();
  70. ++state;
  71. }
  72. typename function_types::result_type<Function>::type const &
  73. dereference() const {
  74. return (value ? value : value = (*f)()).get();
  75. }
  76. bool equal(function_pointer_input_iterator const & other) const {
  77. return f == other.f && state == other.state;
  78. }
  79. private:
  80. Function f;
  81. Input state;
  82. mutable optional<typename function_types::result_type<Function>::type> value;
  83. };
  84. template <class Function, class Input>
  85. class function_reference_input_iterator
  86. : public function_pointer_input_iterator<Function*,Input>
  87. {
  88. public:
  89. function_reference_input_iterator(Function & f_, Input state_ = Input())
  90. : function_pointer_input_iterator<Function*,Input>(&f_, state_)
  91. {}
  92. };
  93. } // namespace impl
  94. template <class Function, class Input>
  95. class function_input_iterator
  96. : public mpl::if_<
  97. function_types::is_function_pointer<Function>,
  98. impl::function_pointer_input_iterator<Function,Input>,
  99. typename mpl::if_<
  100. function_types::is_function_reference<Function>,
  101. impl::function_reference_input_iterator<Function,Input>,
  102. impl::function_input_iterator<Function,Input>
  103. >::type
  104. >::type
  105. {
  106. typedef typename mpl::if_<
  107. function_types::is_function_pointer<Function>,
  108. impl::function_pointer_input_iterator<Function,Input>,
  109. typename mpl::if_<
  110. function_types::is_function_reference<Function>,
  111. impl::function_reference_input_iterator<Function,Input>,
  112. impl::function_input_iterator<Function,Input>
  113. >::type
  114. >::type base_type;
  115. public:
  116. function_input_iterator(Function & f, Input i)
  117. : base_type(f, i) {}
  118. };
  119. template <class Function, class Input>
  120. inline function_input_iterator<Function, Input>
  121. make_function_input_iterator(Function & f, Input state) {
  122. typedef function_input_iterator<Function, Input> result_t;
  123. return result_t(f, state);
  124. }
  125. template <class Function, class Input>
  126. inline function_input_iterator<Function*, Input>
  127. make_function_input_iterator(Function * f, Input state) {
  128. typedef function_input_iterator<Function*, Input> result_t;
  129. return result_t(f, state);
  130. }
  131. struct infinite {
  132. infinite & operator++() { return *this; }
  133. infinite & operator++(int) { return *this; }
  134. bool operator==(infinite &) const { return false; };
  135. bool operator==(infinite const &) const { return false; };
  136. };
  137. }
  138. #endif