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 9 #ifndef BOOST_FUNCTION_INPUT_ITERATOR 10 #define BOOST_FUNCTION_INPUT_ITERATOR 11 12 #include <boost/config.hpp> 13 #include <boost/assert.hpp> 14 #include <boost/core/addressof.hpp> 15 #include <boost/mpl/if.hpp> 16 #include <boost/function_types/is_function_pointer.hpp> 17 #include <boost/function_types/result_type.hpp> 18 #include <boost/iterator/iterator_facade.hpp> 19 #include <boost/none.hpp> 20 #include <boost/optional/optional.hpp> 21 #include <boost/utility/result_of.hpp> 22 23 #ifdef BOOST_RESULT_OF_USE_TR1 24 #include <boost/type_traits/is_function.hpp> 25 #endif 26 27 namespace boost { 28 29 namespace iterators { 30 31 namespace impl { 32 33 // Computes the return type of an lvalue-call with an empty argument, 34 // i.e. decltype(declval<F&>()()). F should be a nullary lvalue-callable 35 // or function. 36 template <class F> 37 struct result_of_nullary_lvalue_call 38 { 39 typedef typename result_of< 40 #ifdef BOOST_RESULT_OF_USE_TR1 41 typename mpl::if_<is_function<F>, F&, F>::type() 42 #else 43 F&() 44 #endif 45 >::type type; 46 }; 47 48 template <class Function, class Input> 49 class function_input_iterator 50 : public iterator_facade< 51 function_input_iterator<Function, Input>, 52 typename result_of_nullary_lvalue_call<Function>::type, 53 single_pass_traversal_tag, 54 typename result_of_nullary_lvalue_call<Function>::type const & 55 > 56 { 57 public: function_input_iterator()58 function_input_iterator() {} function_input_iterator(Function & f_,Input state_=Input ())59 function_input_iterator(Function & f_, Input state_ = Input()) 60 : f(boost::addressof(f_)), state(state_) {} 61 increment()62 void increment() { 63 if(value) 64 value = none; 65 else 66 (*f)(); 67 ++state; 68 } 69 70 typename result_of_nullary_lvalue_call<Function>::type const & dereference() const71 dereference() const { 72 return (value ? value : value = (*f)()).get(); 73 } 74 equal(function_input_iterator const & other) const75 bool equal(function_input_iterator const & other) const { 76 return f == other.f && state == other.state; 77 } 78 79 private: 80 Function * f; 81 Input state; 82 mutable optional<typename result_of_nullary_lvalue_call<Function>::type> value; 83 }; 84 85 template <class Function, class Input> 86 class function_pointer_input_iterator 87 : public iterator_facade< 88 function_pointer_input_iterator<Function, Input>, 89 typename function_types::result_type<Function>::type, 90 single_pass_traversal_tag, 91 typename function_types::result_type<Function>::type const & 92 > 93 { 94 public: function_pointer_input_iterator()95 function_pointer_input_iterator() {} function_pointer_input_iterator(Function & f_,Input state_=Input ())96 function_pointer_input_iterator(Function &f_, Input state_ = Input()) 97 : f(f_), state(state_) {} 98 increment()99 void increment() { 100 if(value) 101 value = none; 102 else 103 (*f)(); 104 ++state; 105 } 106 107 typename function_types::result_type<Function>::type const & dereference() const108 dereference() const { 109 return (value ? value : value = (*f)()).get(); 110 } 111 equal(function_pointer_input_iterator const & other) const112 bool equal(function_pointer_input_iterator const & other) const { 113 return f == other.f && state == other.state; 114 } 115 116 private: 117 Function f; 118 Input state; 119 mutable optional<typename function_types::result_type<Function>::type> value; 120 }; 121 122 } // namespace impl 123 124 template <class Function, class Input> 125 class function_input_iterator 126 : public mpl::if_< 127 function_types::is_function_pointer<Function>, 128 impl::function_pointer_input_iterator<Function,Input>, 129 impl::function_input_iterator<Function,Input> 130 >::type 131 { 132 typedef typename mpl::if_< 133 function_types::is_function_pointer<Function>, 134 impl::function_pointer_input_iterator<Function,Input>, 135 impl::function_input_iterator<Function,Input> 136 >::type base_type; 137 public: function_input_iterator(Function & f,Input i)138 function_input_iterator(Function & f, Input i) 139 : base_type(f, i) {} 140 }; 141 142 template <class Function, class Input> 143 inline function_input_iterator<Function, Input> make_function_input_iterator(Function & f,Input state)144 make_function_input_iterator(Function & f, Input state) { 145 typedef function_input_iterator<Function, Input> result_t; 146 return result_t(f, state); 147 } 148 149 template <class Function, class Input> 150 inline function_input_iterator<Function*, Input> make_function_input_iterator(Function * f,Input state)151 make_function_input_iterator(Function * f, Input state) { 152 typedef function_input_iterator<Function*, Input> result_t; 153 return result_t(f, state); 154 } 155 156 struct infinite { operator ++boost::iterators::infinite157 infinite & operator++() { return *this; } operator ++boost::iterators::infinite158 infinite & operator++(int) { return *this; } operator ==boost::iterators::infinite159 bool operator==(infinite &) const { return false; }; operator ==boost::iterators::infinite160 bool operator==(infinite const &) const { return false; }; 161 }; 162 163 } // namespace iterators 164 165 using iterators::function_input_iterator; 166 using iterators::make_function_input_iterator; 167 using iterators::infinite; 168 169 } // namespace boost 170 171 #endif 172 173