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