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