function_input_iterator.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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_ITERATOR_FUNCTION_INPUT_ITERATOR_HPP_INCLUDED_
  9. #define BOOST_ITERATOR_FUNCTION_INPUT_ITERATOR_HPP_INCLUDED_
  10. #include <memory>
  11. #include <type_traits>
  12. #include <boost/iterator/iterator_facade.hpp>
  13. #include <boost/iterator/iterator_categories.hpp>
  14. #include <boost/iterator/detail/type_traits/conjunction.hpp>
  15. #include <boost/optional/optional.hpp>
  16. namespace boost {
  17. namespace iterators {
  18. template< typename Function, typename Input >
  19. class function_input_iterator;
  20. namespace detail {
  21. template< typename Function, typename Input >
  22. using function_input_iterator_facade_base_t = iterator_facade<
  23. iterators::function_input_iterator< Function, Input >,
  24. decltype(std::declval< Function& >()()),
  25. single_pass_traversal_tag,
  26. decltype(std::declval< Function& >()()) const&
  27. >;
  28. template< typename Function, typename Input >
  29. class function_object_input_iterator :
  30. public function_input_iterator_facade_base_t< Function, Input >
  31. {
  32. private:
  33. using base_type = function_input_iterator_facade_base_t< Function, Input >;
  34. protected:
  35. using function_arg_type = Function&;
  36. public:
  37. using value_type = typename base_type::value_type;
  38. public:
  39. function_object_input_iterator(function_arg_type f, Input state) :
  40. m_f(std::addressof(f)), m_state(state)
  41. {}
  42. protected:
  43. typename std::add_pointer< Function >::type m_f;
  44. Input m_state;
  45. mutable optional< value_type > m_value;
  46. };
  47. template< typename Function, typename Input >
  48. class function_pointer_input_iterator :
  49. public function_input_iterator_facade_base_t< Function, Input >
  50. {
  51. private:
  52. using base_type = function_input_iterator_facade_base_t< Function, Input >;
  53. protected:
  54. using function_arg_type = Function;
  55. public:
  56. using value_type = typename base_type::value_type;
  57. public:
  58. function_pointer_input_iterator(function_arg_type f, Input state) :
  59. m_f(f), m_state(state)
  60. {}
  61. protected:
  62. Function m_f;
  63. Input m_state;
  64. mutable optional< value_type > m_value;
  65. };
  66. template< typename Function, typename Input >
  67. using function_input_iterator_base_t = typename std::conditional<
  68. detail::conjunction<
  69. std::is_pointer< Function >,
  70. std::is_function< typename std::remove_pointer< Function >::type >
  71. >::value,
  72. detail::function_pointer_input_iterator< Function, Input >,
  73. detail::function_object_input_iterator< Function, Input >
  74. >::type;
  75. } // namespace detail
  76. template< typename Function, typename Input >
  77. class function_input_iterator :
  78. public detail::function_input_iterator_base_t< Function, Input >
  79. {
  80. private:
  81. using base_type = detail::function_input_iterator_base_t< Function, Input >;
  82. using function_arg_type = typename base_type::function_arg_type;
  83. public:
  84. using reference = typename base_type::reference;
  85. public:
  86. function_input_iterator(function_arg_type f, Input i) :
  87. base_type(f, i)
  88. {}
  89. void increment()
  90. {
  91. if (this->m_value)
  92. this->m_value.reset();
  93. else
  94. (*this->m_f)();
  95. ++this->m_state;
  96. }
  97. reference dereference() const
  98. {
  99. if (!this->m_value)
  100. this->m_value = (*this->m_f)();
  101. return this->m_value.get();
  102. }
  103. bool equal(function_input_iterator const& other) const
  104. {
  105. return this->m_f == other.m_f && this->m_state == other.m_state;
  106. }
  107. };
  108. template< typename Function, typename Input >
  109. inline function_input_iterator< Function, Input > make_function_input_iterator(Function& f, Input state)
  110. {
  111. return function_input_iterator< Function, Input >(f, state);
  112. }
  113. template< typename Function, typename Input >
  114. inline function_input_iterator< Function*, Input > make_function_input_iterator(Function* f, Input state)
  115. {
  116. return function_input_iterator< Function*, Input >(f, state);
  117. }
  118. struct infinite
  119. {
  120. infinite& operator++() { return *this; }
  121. infinite& operator++(int) { return *this; }
  122. bool operator==(infinite&) const { return false; };
  123. bool operator==(infinite const&) const { return false; };
  124. };
  125. } // namespace iterators
  126. using iterators::function_input_iterator;
  127. using iterators::make_function_input_iterator;
  128. using iterators::infinite;
  129. } // namespace boost
  130. #endif // BOOST_ITERATOR_FUNCTION_INPUT_ITERATOR_HPP_INCLUDED_