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: |
37 | function_input_iterator() {} |
38 | function_input_iterator(Function & f_, Input state_ = Input()) |
39 | : f(&f_), state(state_) {} |
40 | |
41 | void increment() { |
42 | if(value) |
43 | value = none; |
44 | else |
45 | (*f)(); |
46 | ++state; |
47 | } |
48 | |
49 | typename Function::result_type const & |
50 | dereference() const { |
51 | return (value ? value : value = (*f)()).get(); |
52 | } |
53 | |
54 | 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: |
74 | function_pointer_input_iterator() {} |
75 | function_pointer_input_iterator(Function &f_, Input state_ = Input()) |
76 | : f(f_), state(state_) {} |
77 | |
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 & |
87 | dereference() const { |
88 | return (value ? value : value = (*f)()).get(); |
89 | } |
90 | |
91 | 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: |
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: |
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> |
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> |
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 { |
154 | infinite & operator++() { return *this; } |
155 | infinite & operator++(int) { return *this; } |
156 | bool operator==(infinite &) const { return false; }; |
157 | 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 | |