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