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
21namespace boost {
22
23namespace 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
162using iterators::function_input_iterator;
163using iterators::make_function_input_iterator;
164using iterators::infinite;
165
166} // namespace boost
167
168#endif
169
170

source code of boost/boost/iterator/function_input_iterator.hpp