Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Phoenix V1.2.1
|
Chris@16
|
3 Copyright (c) 2001-2002 Joel de Guzman
|
Chris@16
|
4
|
Chris@16
|
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 ==============================================================================*/
|
Chris@16
|
8 #ifndef PHOENIX_SPECIAL_OPS_HPP
|
Chris@16
|
9 #define PHOENIX_SPECIAL_OPS_HPP
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/config.hpp>
|
Chris@16
|
12 #ifdef BOOST_NO_STRINGSTREAM
|
Chris@16
|
13 #include <strstream>
|
Chris@16
|
14 #define PHOENIX_SSTREAM strstream
|
Chris@16
|
15 #else
|
Chris@16
|
16 #include <sstream>
|
Chris@16
|
17 #define PHOENIX_SSTREAM stringstream
|
Chris@16
|
18 #endif
|
Chris@16
|
19
|
Chris@16
|
20 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
21 #include <boost/spirit/home/classic/phoenix/operators.hpp>
|
Chris@16
|
22 #include <iosfwd>
|
Chris@16
|
23
|
Chris@16
|
24 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
25 #if defined(_STLPORT_VERSION) && defined(__STL_USE_OWN_NAMESPACE)
|
Chris@16
|
26 #define PHOENIX_STD _STLP_STD
|
Chris@16
|
27 #define PHOENIX_NO_STD_NAMESPACE
|
Chris@16
|
28 #else
|
Chris@16
|
29 #define PHOENIX_STD std
|
Chris@16
|
30 #endif
|
Chris@16
|
31
|
Chris@16
|
32 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
33 //#if !defined(PHOENIX_NO_STD_NAMESPACE)
|
Chris@16
|
34 namespace PHOENIX_STD
|
Chris@16
|
35 {
|
Chris@16
|
36 //#endif
|
Chris@16
|
37
|
Chris@16
|
38 template<typename T> class complex;
|
Chris@16
|
39
|
Chris@16
|
40 //#if !defined(PHOENIX_NO_STD_NAMESPACE)
|
Chris@16
|
41 }
|
Chris@16
|
42 //#endif
|
Chris@16
|
43
|
Chris@16
|
44 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
45 namespace phoenix
|
Chris@16
|
46 {
|
Chris@16
|
47
|
Chris@16
|
48 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
49 //
|
Chris@16
|
50 // The following specializations take into account the C++ standard
|
Chris@16
|
51 // library components. There are a couple of issues that have to be
|
Chris@16
|
52 // dealt with to enable lazy operator overloads for the standard
|
Chris@16
|
53 // library classes.
|
Chris@16
|
54 //
|
Chris@16
|
55 // *iostream (e.g. cout, cin, strstream/ stringstream) uses non-
|
Chris@16
|
56 // canonical shift operator overloads where the lhs is taken in
|
Chris@16
|
57 // by reference.
|
Chris@16
|
58 //
|
Chris@16
|
59 // *I/O manipulators overloads for the RHS of the << and >>
|
Chris@16
|
60 // operators.
|
Chris@16
|
61 //
|
Chris@16
|
62 // *STL iterators can be objects that conform to pointer semantics.
|
Chris@16
|
63 // Some operators need to be specialized for these.
|
Chris@16
|
64 //
|
Chris@16
|
65 // *std::complex is given a rank (see rank class in operators.hpp)
|
Chris@16
|
66 //
|
Chris@16
|
67 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
68
|
Chris@16
|
69 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
70 //
|
Chris@16
|
71 // specialization for rank<std::complex>
|
Chris@16
|
72 //
|
Chris@16
|
73 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
74 template <typename T> struct rank<PHOENIX_STD::complex<T> >
|
Chris@16
|
75 { static int const value = 170 + rank<T>::value; };
|
Chris@16
|
76
|
Chris@16
|
77 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
78 //
|
Chris@16
|
79 // specializations for std::istream
|
Chris@16
|
80 //
|
Chris@16
|
81 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
82
|
Chris@16
|
83 //////////////////////////////////
|
Chris@16
|
84 template <typename T1>
|
Chris@16
|
85 struct binary_operator<shift_r_op, PHOENIX_STD::istream, T1>
|
Chris@16
|
86 {
|
Chris@16
|
87 typedef PHOENIX_STD::istream& result_type;
|
Chris@16
|
88 static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
|
Chris@16
|
89 { return out >> rhs; }
|
Chris@16
|
90 };
|
Chris@16
|
91
|
Chris@16
|
92 //////////////////////////////////
|
Chris@16
|
93 template <typename BaseT>
|
Chris@16
|
94 inline typename impl::make_binary3
|
Chris@101
|
95 <shift_r_op, variable<PHOENIX_STD::istream>, BaseT>::type
|
Chris@101
|
96 operator>>(PHOENIX_STD::istream& _0, actor<BaseT> const& _1)
|
Chris@16
|
97 {
|
Chris@16
|
98 return impl::make_binary3
|
Chris@101
|
99 <shift_r_op, variable<PHOENIX_STD::istream>, BaseT>
|
Chris@16
|
100 ::construct(var(_0), _1);
|
Chris@16
|
101 }
|
Chris@16
|
102
|
Chris@16
|
103 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
104 //
|
Chris@16
|
105 // specializations for std::ostream
|
Chris@16
|
106 //
|
Chris@16
|
107 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
108
|
Chris@16
|
109 //////////////////////////////////
|
Chris@16
|
110 template <typename T1>
|
Chris@16
|
111 struct binary_operator<shift_l_op, PHOENIX_STD::ostream, T1>
|
Chris@16
|
112 {
|
Chris@16
|
113 typedef PHOENIX_STD::ostream& result_type;
|
Chris@16
|
114 static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
|
Chris@16
|
115 { return out << rhs; }
|
Chris@16
|
116 };
|
Chris@16
|
117
|
Chris@16
|
118 //////////////////////////////////
|
Chris@16
|
119 template <typename BaseT>
|
Chris@16
|
120 inline typename impl::make_binary3
|
Chris@101
|
121 <shift_l_op, variable<PHOENIX_STD::ostream>, BaseT>::type
|
Chris@101
|
122 operator<<(PHOENIX_STD::ostream& _0, actor<BaseT> const& _1)
|
Chris@16
|
123 {
|
Chris@16
|
124 return impl::make_binary3
|
Chris@101
|
125 <shift_l_op, variable<PHOENIX_STD::ostream>, BaseT>
|
Chris@16
|
126 ::construct(var(_0), _1);
|
Chris@16
|
127 }
|
Chris@16
|
128
|
Chris@16
|
129 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
130 //
|
Chris@16
|
131 // specializations for std::strstream / stringstream
|
Chris@16
|
132 //
|
Chris@16
|
133 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
134 template <typename T1>
|
Chris@16
|
135 struct binary_operator<shift_r_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
|
Chris@16
|
136 {
|
Chris@16
|
137 typedef PHOENIX_STD::istream& result_type;
|
Chris@16
|
138 static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
|
Chris@16
|
139 { return out >> rhs; }
|
Chris@16
|
140 };
|
Chris@16
|
141
|
Chris@16
|
142 //////////////////////////////////
|
Chris@16
|
143 template <typename BaseT>
|
Chris@16
|
144 inline typename impl::make_binary3
|
Chris@16
|
145 <shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
|
Chris@16
|
146 operator>>(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
|
Chris@16
|
147 {
|
Chris@16
|
148 return impl::make_binary3
|
Chris@16
|
149 <shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
|
Chris@16
|
150 ::construct(var(_0), _1);
|
Chris@16
|
151 }
|
Chris@16
|
152
|
Chris@16
|
153 //////////////////////////////////
|
Chris@16
|
154 template <typename T1>
|
Chris@16
|
155 struct binary_operator<shift_l_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
|
Chris@16
|
156 {
|
Chris@16
|
157 typedef PHOENIX_STD::ostream& result_type;
|
Chris@16
|
158 static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
|
Chris@16
|
159 { return out << rhs; }
|
Chris@16
|
160 };
|
Chris@16
|
161
|
Chris@16
|
162 //////////////////////////////////
|
Chris@16
|
163 template <typename BaseT>
|
Chris@16
|
164 inline typename impl::make_binary3
|
Chris@16
|
165 <shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
|
Chris@16
|
166 operator<<(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
|
Chris@16
|
167 {
|
Chris@16
|
168 return impl::make_binary3
|
Chris@16
|
169 <shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
|
Chris@16
|
170 ::construct(var(_0), _1);
|
Chris@16
|
171 }
|
Chris@16
|
172
|
Chris@16
|
173 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
174 //
|
Chris@16
|
175 // I/O manipulator specializations
|
Chris@16
|
176 //
|
Chris@16
|
177 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
178
|
Chris@16
|
179 typedef PHOENIX_STD::ios_base& (*iomanip_t)(PHOENIX_STD::ios_base&);
|
Chris@16
|
180 typedef PHOENIX_STD::istream& (*imanip_t)(PHOENIX_STD::istream&);
|
Chris@16
|
181 typedef PHOENIX_STD::ostream& (*omanip_t)(PHOENIX_STD::ostream&);
|
Chris@16
|
182
|
Chris@16
|
183 #if defined(__BORLANDC__)
|
Chris@16
|
184
|
Chris@16
|
185 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
186 //
|
Chris@16
|
187 // Borland does not like i/o manipulators functions such as endl to
|
Chris@16
|
188 // be the rhs of a lazy << operator (Borland incorrectly reports
|
Chris@16
|
189 // ambiguity). To get around the problem, we provide function
|
Chris@16
|
190 // pointer versions of the same name with a single trailing
|
Chris@16
|
191 // underscore.
|
Chris@16
|
192 //
|
Chris@16
|
193 // You can use the same trick for other i/o manipulators.
|
Chris@16
|
194 // Alternatively, you can prefix the manipulator with a '&'
|
Chris@16
|
195 // operator. Example:
|
Chris@16
|
196 //
|
Chris@16
|
197 // cout << arg1 << &endl
|
Chris@16
|
198 //
|
Chris@16
|
199 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
200
|
Chris@16
|
201 imanip_t ws_ = &PHOENIX_STD::ws;
|
Chris@16
|
202 iomanip_t dec_ = &PHOENIX_STD::dec;
|
Chris@16
|
203 iomanip_t hex_ = &PHOENIX_STD::hex;
|
Chris@16
|
204 iomanip_t oct_ = &PHOENIX_STD::oct;
|
Chris@16
|
205 omanip_t endl_ = &PHOENIX_STD::endl;
|
Chris@16
|
206 omanip_t ends_ = &PHOENIX_STD::ends;
|
Chris@16
|
207 omanip_t flush_ = &PHOENIX_STD::flush;
|
Chris@16
|
208
|
Chris@16
|
209 #else // __BORLANDC__
|
Chris@16
|
210
|
Chris@16
|
211 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
212 //
|
Chris@16
|
213 // The following are overloads for I/O manipulators.
|
Chris@16
|
214 //
|
Chris@16
|
215 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
216 template <typename BaseT>
|
Chris@16
|
217 inline typename impl::make_binary1<shift_l_op, BaseT, imanip_t>::type
|
Chris@16
|
218 operator>>(actor<BaseT> const& _0, imanip_t _1)
|
Chris@16
|
219 {
|
Chris@16
|
220 return impl::make_binary1<shift_l_op, BaseT, imanip_t>::construct(_0, _1);
|
Chris@16
|
221 }
|
Chris@16
|
222
|
Chris@16
|
223 //////////////////////////////////
|
Chris@16
|
224 template <typename BaseT>
|
Chris@16
|
225 inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
|
Chris@16
|
226 operator>>(actor<BaseT> const& _0, iomanip_t _1)
|
Chris@16
|
227 {
|
Chris@16
|
228 return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
|
Chris@16
|
229 }
|
Chris@16
|
230
|
Chris@16
|
231 //////////////////////////////////
|
Chris@16
|
232 template <typename BaseT>
|
Chris@16
|
233 inline typename impl::make_binary1<shift_l_op, BaseT, omanip_t>::type
|
Chris@16
|
234 operator<<(actor<BaseT> const& _0, omanip_t _1)
|
Chris@16
|
235 {
|
Chris@16
|
236 return impl::make_binary1<shift_l_op, BaseT, omanip_t>::construct(_0, _1);
|
Chris@16
|
237 }
|
Chris@16
|
238
|
Chris@16
|
239 //////////////////////////////////
|
Chris@16
|
240 template <typename BaseT>
|
Chris@16
|
241 inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
|
Chris@16
|
242 operator<<(actor<BaseT> const& _0, iomanip_t _1)
|
Chris@16
|
243 {
|
Chris@16
|
244 return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
|
Chris@16
|
245 }
|
Chris@16
|
246
|
Chris@16
|
247 #endif // __BORLANDC__
|
Chris@16
|
248
|
Chris@16
|
249 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
250 //
|
Chris@16
|
251 // specializations for stl iterators and containers
|
Chris@16
|
252 //
|
Chris@16
|
253 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
254 template <typename T>
|
Chris@16
|
255 struct unary_operator<dereference_op, T>
|
Chris@16
|
256 {
|
Chris@16
|
257 typedef typename T::reference result_type;
|
Chris@16
|
258 static result_type eval(T const& iter)
|
Chris@16
|
259 { return *iter; }
|
Chris@16
|
260 };
|
Chris@16
|
261
|
Chris@16
|
262 //////////////////////////////////
|
Chris@16
|
263 template <typename T0, typename T1>
|
Chris@16
|
264 struct binary_operator<index_op, T0, T1>
|
Chris@16
|
265 {
|
Chris@16
|
266 typedef typename T0::reference result_type;
|
Chris@16
|
267 static result_type eval(T0& container, T1 const& index)
|
Chris@16
|
268 { return container[index]; }
|
Chris@16
|
269 };
|
Chris@16
|
270
|
Chris@16
|
271 //////////////////////////////////
|
Chris@16
|
272 template <typename T0, typename T1>
|
Chris@16
|
273 struct binary_operator<index_op, T0 const, T1>
|
Chris@16
|
274 {
|
Chris@16
|
275 typedef typename T0::const_reference result_type;
|
Chris@16
|
276 static result_type eval(T0 const& container, T1 const& index)
|
Chris@16
|
277 { return container[index]; }
|
Chris@16
|
278 };
|
Chris@16
|
279
|
Chris@16
|
280 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
281 } // namespace phoenix
|
Chris@16
|
282
|
Chris@16
|
283 #undef PHOENIX_SSTREAM
|
Chris@16
|
284 #undef PHOENIX_STD
|
Chris@16
|
285 #endif
|