• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Boost.Wave: A Standard compliant C++ preprocessor library
3 
4     http://www.boost.org/
5 
6     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
7     Software License, Version 1.0. (See accompanying file
8     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 
11 #if !defined(BOOST_FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)
12 #define BOOST_FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED
13 
14 #include <boost/assert.hpp>
15 #include <boost/spirit/include/classic_multi_pass.hpp>
16 #include <boost/wave/wave_config.hpp>
17 
18 // this must occur after all of the includes and before any code appears
19 #ifdef BOOST_HAS_ABI_HEADERS
20 #include BOOST_ABI_PREFIX
21 #endif
22 
23 ///////////////////////////////////////////////////////////////////////////////
24 namespace boost {
25 namespace wave {
26 namespace util {
27 
28 ///////////////////////////////////////////////////////////////////////////////
29 //
30 //  class functor_input
31 //
32 //      Implementation of the InputPolicy used by multi_pass
33 //      functor_input gets tokens from a functor
34 //      Note: the functor must have a typedef for result_type
35 //            It also must have a static variable of type result_type defined
36 //            to represent eof that is called eof.
37 //
38 //      This functor input policy template is essentially the same as the
39 //      predefined multi_pass functor_input policy. The difference is,
40 //      that the first token is not read at initialization time, but only
41 //      just before returning the first token. Additionally it does not
42 //      call operator new() twice but only once.
43 //
44 ///////////////////////////////////////////////////////////////////////////////
45 struct functor_input {
46 
47     template <typename FunctorT>
48     class inner {
49     private:
50         typedef typename FunctorT::result_type result_type;
51 
52     public:
53         typedef result_type value_type;
54 
55     private:
56         struct Data {
Databoost::wave::util::functor_input::inner::Data57             Data(FunctorT const &ftor_)
58             :   ftor(ftor_), was_initialized(false)
59             {}
60 
61             FunctorT ftor;
62             value_type curtok;
63             bool was_initialized;
64         };
65 
66        // Needed by compilers not implementing the resolution to DR45. For
67        // reference, see
68        // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
69 
70        friend struct Data;
71 
72     public:
73         typedef std::ptrdiff_t difference_type;
74         typedef result_type *pointer;
75         typedef result_type &reference;
76 
77     protected:
inner()78         inner()
79         :   data(0)
80         {}
81 
inner(FunctorT const & x)82         inner(FunctorT const &x)
83         :   data(new Data(x))
84         {}
85 
inner(inner const & x)86         inner(inner const &x)
87         :   data(x.data)
88         {}
89 
destroy()90         void destroy()
91         {
92             delete data;
93             data = 0;
94         }
95 
same_input(inner const & x) const96         bool same_input(inner const &x) const
97         {
98             return data == x.data;
99         }
100 
swap(inner & x)101         void swap(inner &x)
102         {
103             boost::spirit::classic::impl::mp_swap(data, x.data);
104         }
105 
ensure_initialized() const106         void ensure_initialized() const
107         {
108             if (data && !data->was_initialized) {
109                 data->curtok = (data->ftor)();    // get the first token
110                 data->was_initialized = true;
111             }
112         }
113 
114     public:
get_input() const115         reference get_input() const
116         {
117             ensure_initialized();
118             return data->curtok;
119         }
120 
advance_input()121         void advance_input()
122         {
123             BOOST_ASSERT(0 != data);
124             data->curtok = (data->ftor)();
125             data->was_initialized = true;
126         }
127 
input_at_eof() const128         bool input_at_eof() const
129         {
130             ensure_initialized();
131             return !data || data->curtok == data->ftor.eof;
132         }
133 
get_functor() const134         FunctorT& get_functor() const
135         {
136             BOOST_ASSERT(0 != data);
137             return data->ftor;
138         }
139 
140     private:
141         mutable Data *data;
142     };
143 };
144 
145 ///////////////////////////////////////////////////////////////////////////////
146 }   // namespace util
147 }   // namespace wave
148 }   // namespace boost
149 
150 // the suffix header occurs after all of the code
151 #ifdef BOOST_HAS_ABI_HEADERS
152 #include BOOST_ABI_SUFFIX
153 #endif
154 
155 #endif // !defined(BOOST_FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)
156