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/assert.hpp> 13 #include <boost/mpl/if.hpp> 14 #include <boost/function_types/is_function_pointer.hpp> 15 #include <boost/function_types/is_function_reference.hpp> 16 #include <boost/function_types/result_type.hpp> 17 #include <boost/iterator/iterator_facade.hpp> 18 #include <boost/none.hpp> 19 #include <boost/optional/optional.hpp> 20 21 namespace boost { 22 23 namespace iterators { 24 25 namespace impl { 26 27 template <class Function, class Input> 28 class function_input_iterator 29 : public iterator_facade< 30 function_input_iterator<Function, Input>, 31 typename Function::result_type, 32 single_pass_traversal_tag, 33 typename Function::result_type const & 34 > 35 { 36 public: function_input_iterator()37 function_input_iterator() {} function_input_iterator(Function & f_,Input state_=Input ())38 function_input_iterator(Function & f_, Input state_ = Input()) 39 : f(&f_), state(state_) {} 40 increment()41 void increment() { 42 if(value) 43 value = none; 44 else 45 (*f)(); 46 ++state; 47 } 48 49 typename Function::result_type const & dereference() const50 dereference() const { 51 return (value ? value : value = (*f)()).get(); 52 } 53 equal(function_input_iterator const & other) const54 bool equal(function_input_iterator const & other) const { 55 return f == other.f && state == other.state; 56 } 57 58 private: 59 Function * f; 60 Input state; 61 mutable optional<typename Function::result_type> value; 62 }; 63 64 template <class Function, class Input> 65 class function_pointer_input_iterator 66 : public iterator_facade< 67 function_pointer_input_iterator<Function, Input>, 68 typename function_types::result_type<Function>::type, 69 single_pass_traversal_tag, 70 typename function_types::result_type<Function>::type const & 71 > 72 { 73 public: function_pointer_input_iterator()74 function_pointer_input_iterator() {} function_pointer_input_iterator(Function & f_,Input state_=Input ())75 function_pointer_input_iterator(Function &f_, Input state_ = Input()) 76 : f(f_), state(state_) {} 77 increment()78 void increment() { 79 if(value) 80 value = none; 81 else 82 (*f)(); 83 ++state; 84 } 85 86 typename function_types::result_type<Function>::type const & dereference() const87 dereference() const { 88 return (value ? value : value = (*f)()).get(); 89 } 90 equal(function_pointer_input_iterator const & other) const91 bool equal(function_pointer_input_iterator const & other) const { 92 return f == other.f && state == other.state; 93 } 94 95 private: 96 Function f; 97 Input state; 98 mutable optional<typename function_types::result_type<Function>::type> value; 99 }; 100 101 template <class Function, class Input> 102 class function_reference_input_iterator 103 : public function_pointer_input_iterator<Function*,Input> 104 { 105 public: function_reference_input_iterator(Function & f_,Input state_=Input ())106 function_reference_input_iterator(Function & f_, Input state_ = Input()) 107 : function_pointer_input_iterator<Function*,Input>(&f_, state_) 108 {} 109 }; 110 111 } // namespace impl 112 113 template <class Function, class Input> 114 class function_input_iterator 115 : public mpl::if_< 116 function_types::is_function_pointer<Function>, 117 impl::function_pointer_input_iterator<Function,Input>, 118 typename mpl::if_< 119 function_types::is_function_reference<Function>, 120 impl::function_reference_input_iterator<Function,Input>, 121 impl::function_input_iterator<Function,Input> 122 >::type 123 >::type 124 { 125 typedef typename mpl::if_< 126 function_types::is_function_pointer<Function>, 127 impl::function_pointer_input_iterator<Function,Input>, 128 typename mpl::if_< 129 function_types::is_function_reference<Function>, 130 impl::function_reference_input_iterator<Function,Input>, 131 impl::function_input_iterator<Function,Input> 132 >::type 133 >::type base_type; 134 public: function_input_iterator(Function & f,Input i)135 function_input_iterator(Function & f, Input i) 136 : base_type(f, i) {} 137 }; 138 139 template <class Function, class Input> 140 inline function_input_iterator<Function, Input> make_function_input_iterator(Function & f,Input state)141 make_function_input_iterator(Function & f, Input state) { 142 typedef function_input_iterator<Function, Input> result_t; 143 return result_t(f, state); 144 } 145 146 template <class Function, class Input> 147 inline function_input_iterator<Function*, Input> make_function_input_iterator(Function * f,Input state)148 make_function_input_iterator(Function * f, Input state) { 149 typedef function_input_iterator<Function*, Input> result_t; 150 return result_t(f, state); 151 } 152 153 struct infinite { operator ++boost::iterators::infinite154 infinite & operator++() { return *this; } operator ++boost::iterators::infinite155 infinite & operator++(int) { return *this; } operator ==boost::iterators::infinite156 bool operator==(infinite &) const { return false; }; operator ==boost::iterators::infinite157 bool operator==(infinite const &) const { return false; }; 158 }; 159 160 } // namespace iterators 161 162 using iterators::function_input_iterator; 163 using iterators::make_function_input_iterator; 164 using iterators::infinite; 165 166 } // namespace boost 167 168 #endif 169 170