Chris@16
|
1 // Copyright 2009 (C) Dean Michael Berris <me@deanberris.com>
|
Chris@16
|
2 // Copyright 2012 (C) Google, Inc.
|
Chris@16
|
3 // Copyright 2012 (C) Jeffrey Lee Hellrung, Jr.
|
Chris@16
|
4 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
5 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 //
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_FUNCTION_INPUT_ITERATOR
|
Chris@16
|
10 #define BOOST_FUNCTION_INPUT_ITERATOR
|
Chris@16
|
11
|
Chris@16
|
12 #include <boost/assert.hpp>
|
Chris@16
|
13 #include <boost/mpl/if.hpp>
|
Chris@16
|
14 #include <boost/function_types/is_function_pointer.hpp>
|
Chris@16
|
15 #include <boost/function_types/is_function_reference.hpp>
|
Chris@16
|
16 #include <boost/function_types/result_type.hpp>
|
Chris@16
|
17 #include <boost/iterator/iterator_facade.hpp>
|
Chris@16
|
18 #include <boost/none.hpp>
|
Chris@16
|
19 #include <boost/optional/optional.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 namespace boost {
|
Chris@16
|
22
|
Chris@101
|
23 namespace iterators {
|
Chris@101
|
24
|
Chris@16
|
25 namespace impl {
|
Chris@16
|
26
|
Chris@16
|
27 template <class Function, class Input>
|
Chris@16
|
28 class function_input_iterator
|
Chris@16
|
29 : public iterator_facade<
|
Chris@16
|
30 function_input_iterator<Function, Input>,
|
Chris@16
|
31 typename Function::result_type,
|
Chris@16
|
32 single_pass_traversal_tag,
|
Chris@16
|
33 typename Function::result_type const &
|
Chris@16
|
34 >
|
Chris@16
|
35 {
|
Chris@16
|
36 public:
|
Chris@16
|
37 function_input_iterator() {}
|
Chris@101
|
38 function_input_iterator(Function & f_, Input state_ = Input())
|
Chris@16
|
39 : f(&f_), state(state_) {}
|
Chris@16
|
40
|
Chris@16
|
41 void increment() {
|
Chris@16
|
42 if(value)
|
Chris@16
|
43 value = none;
|
Chris@16
|
44 else
|
Chris@16
|
45 (*f)();
|
Chris@16
|
46 ++state;
|
Chris@16
|
47 }
|
Chris@16
|
48
|
Chris@101
|
49 typename Function::result_type const &
|
Chris@16
|
50 dereference() const {
|
Chris@16
|
51 return (value ? value : value = (*f)()).get();
|
Chris@16
|
52 }
|
Chris@16
|
53
|
Chris@16
|
54 bool equal(function_input_iterator const & other) const {
|
Chris@16
|
55 return f == other.f && state == other.state;
|
Chris@16
|
56 }
|
Chris@16
|
57
|
Chris@16
|
58 private:
|
Chris@16
|
59 Function * f;
|
Chris@16
|
60 Input state;
|
Chris@16
|
61 mutable optional<typename Function::result_type> value;
|
Chris@16
|
62 };
|
Chris@16
|
63
|
Chris@16
|
64 template <class Function, class Input>
|
Chris@16
|
65 class function_pointer_input_iterator
|
Chris@16
|
66 : public iterator_facade<
|
Chris@16
|
67 function_pointer_input_iterator<Function, Input>,
|
Chris@16
|
68 typename function_types::result_type<Function>::type,
|
Chris@16
|
69 single_pass_traversal_tag,
|
Chris@16
|
70 typename function_types::result_type<Function>::type const &
|
Chris@16
|
71 >
|
Chris@16
|
72 {
|
Chris@16
|
73 public:
|
Chris@16
|
74 function_pointer_input_iterator() {}
|
Chris@16
|
75 function_pointer_input_iterator(Function &f_, Input state_ = Input())
|
Chris@16
|
76 : f(f_), state(state_) {}
|
Chris@16
|
77
|
Chris@16
|
78 void increment() {
|
Chris@16
|
79 if(value)
|
Chris@16
|
80 value = none;
|
Chris@16
|
81 else
|
Chris@16
|
82 (*f)();
|
Chris@16
|
83 ++state;
|
Chris@16
|
84 }
|
Chris@16
|
85
|
Chris@16
|
86 typename function_types::result_type<Function>::type const &
|
Chris@16
|
87 dereference() const {
|
Chris@16
|
88 return (value ? value : value = (*f)()).get();
|
Chris@16
|
89 }
|
Chris@16
|
90
|
Chris@16
|
91 bool equal(function_pointer_input_iterator const & other) const {
|
Chris@16
|
92 return f == other.f && state == other.state;
|
Chris@16
|
93 }
|
Chris@16
|
94
|
Chris@16
|
95 private:
|
Chris@16
|
96 Function f;
|
Chris@16
|
97 Input state;
|
Chris@16
|
98 mutable optional<typename function_types::result_type<Function>::type> value;
|
Chris@16
|
99 };
|
Chris@16
|
100
|
Chris@16
|
101 template <class Function, class Input>
|
Chris@16
|
102 class function_reference_input_iterator
|
Chris@16
|
103 : public function_pointer_input_iterator<Function*,Input>
|
Chris@16
|
104 {
|
Chris@16
|
105 public:
|
Chris@16
|
106 function_reference_input_iterator(Function & f_, Input state_ = Input())
|
Chris@16
|
107 : function_pointer_input_iterator<Function*,Input>(&f_, state_)
|
Chris@16
|
108 {}
|
Chris@16
|
109 };
|
Chris@16
|
110
|
Chris@16
|
111 } // namespace impl
|
Chris@16
|
112
|
Chris@16
|
113 template <class Function, class Input>
|
Chris@101
|
114 class function_input_iterator
|
Chris@16
|
115 : public mpl::if_<
|
Chris@16
|
116 function_types::is_function_pointer<Function>,
|
Chris@16
|
117 impl::function_pointer_input_iterator<Function,Input>,
|
Chris@16
|
118 typename mpl::if_<
|
Chris@16
|
119 function_types::is_function_reference<Function>,
|
Chris@16
|
120 impl::function_reference_input_iterator<Function,Input>,
|
Chris@16
|
121 impl::function_input_iterator<Function,Input>
|
Chris@16
|
122 >::type
|
Chris@16
|
123 >::type
|
Chris@16
|
124 {
|
Chris@16
|
125 typedef typename mpl::if_<
|
Chris@16
|
126 function_types::is_function_pointer<Function>,
|
Chris@16
|
127 impl::function_pointer_input_iterator<Function,Input>,
|
Chris@16
|
128 typename mpl::if_<
|
Chris@16
|
129 function_types::is_function_reference<Function>,
|
Chris@16
|
130 impl::function_reference_input_iterator<Function,Input>,
|
Chris@16
|
131 impl::function_input_iterator<Function,Input>
|
Chris@16
|
132 >::type
|
Chris@16
|
133 >::type base_type;
|
Chris@16
|
134 public:
|
Chris@16
|
135 function_input_iterator(Function & f, Input i)
|
Chris@16
|
136 : base_type(f, i) {}
|
Chris@16
|
137 };
|
Chris@16
|
138
|
Chris@16
|
139 template <class Function, class Input>
|
Chris@16
|
140 inline function_input_iterator<Function, Input>
|
Chris@16
|
141 make_function_input_iterator(Function & f, Input state) {
|
Chris@16
|
142 typedef function_input_iterator<Function, Input> result_t;
|
Chris@16
|
143 return result_t(f, state);
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 template <class Function, class Input>
|
Chris@16
|
147 inline function_input_iterator<Function*, Input>
|
Chris@16
|
148 make_function_input_iterator(Function * f, Input state) {
|
Chris@16
|
149 typedef function_input_iterator<Function*, Input> result_t;
|
Chris@16
|
150 return result_t(f, state);
|
Chris@16
|
151 }
|
Chris@16
|
152
|
Chris@16
|
153 struct infinite {
|
Chris@16
|
154 infinite & operator++() { return *this; }
|
Chris@16
|
155 infinite & operator++(int) { return *this; }
|
Chris@16
|
156 bool operator==(infinite &) const { return false; };
|
Chris@16
|
157 bool operator==(infinite const &) const { return false; };
|
Chris@16
|
158 };
|
Chris@101
|
159
|
Chris@101
|
160 } // namespace iterators
|
Chris@101
|
161
|
Chris@101
|
162 using iterators::function_input_iterator;
|
Chris@101
|
163 using iterators::make_function_input_iterator;
|
Chris@101
|
164 using iterators::infinite;
|
Chris@101
|
165
|
Chris@101
|
166 } // namespace boost
|
Chris@16
|
167
|
Chris@16
|
168 #endif
|
Chris@16
|
169
|