]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED) | |
12 | #define 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 { | |
57 | 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: | |
78 | inner() | |
79 | : data(0) | |
80 | {} | |
81 | ||
82 | inner(FunctorT const &x) | |
83 | : data(new Data(x)) | |
84 | {} | |
85 | ||
86 | inner(inner const &x) | |
87 | : data(x.data) | |
88 | {} | |
89 | ||
90 | void destroy() | |
91 | { | |
92 | delete data; | |
93 | data = 0; | |
94 | } | |
95 | ||
96 | bool same_input(inner const &x) const | |
97 | { | |
98 | return data == x.data; | |
99 | } | |
100 | ||
101 | void swap(inner &x) | |
102 | { | |
103 | boost::spirit::classic::impl::mp_swap(data, x.data); | |
104 | } | |
105 | ||
106 | 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: | |
115 | reference get_input() const | |
116 | { | |
117 | ensure_initialized(); | |
118 | return data->curtok; | |
119 | } | |
120 | ||
121 | void advance_input() | |
122 | { | |
123 | BOOST_ASSERT(0 != data); | |
124 | data->curtok = (data->ftor)(); | |
125 | data->was_initialized = true; | |
126 | } | |
127 | ||
128 | bool input_at_eof() const | |
129 | { | |
130 | ensure_initialized(); | |
131 | return !data || data->curtok == data->ftor.eof; | |
132 | } | |
133 | ||
134 | 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(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED) |