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