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 
83 //////////////////////////////////
84 template <typename T1>
85 struct binary_operator<shift_r_op, PHOENIX_STD::istream, T1>
86 {
87     typedef PHOENIX_STD::istream& result_type;
evalphoenix::binary_operator88     static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
89     { return out >> rhs; }
90 };
91 
92 //////////////////////////////////
93 template <typename BaseT>
94 inline typename impl::make_binary3
95     <shift_r_op, variable<PHOENIX_STD::istream>, BaseT>::type
operator >>(PHOENIX_STD::istream & _0,actor<BaseT> const & _1)96 operator>>(PHOENIX_STD::istream& _0, actor<BaseT> const& _1)
97 {
98     return impl::make_binary3
99     <shift_r_op, variable<PHOENIX_STD::istream>, BaseT>
100     ::construct(var(_0), _1);
101 }
102 
103 ///////////////////////////////////////////////////////////////////////////////
104 //
105 //  specializations for std::ostream
106 //
107 ///////////////////////////////////////////////////////////////////////////////
108 
109 //////////////////////////////////
110 template <typename T1>
111 struct binary_operator<shift_l_op, PHOENIX_STD::ostream, T1>
112 {
113     typedef PHOENIX_STD::ostream& result_type;
evalphoenix::binary_operator114     static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
115     { return out << rhs; }
116 };
117 
118 //////////////////////////////////
119 template <typename BaseT>
120 inline typename impl::make_binary3
121     <shift_l_op, variable<PHOENIX_STD::ostream>, BaseT>::type
operator <<(PHOENIX_STD::ostream & _0,actor<BaseT> const & _1)122 operator<<(PHOENIX_STD::ostream& _0, actor<BaseT> const& _1)
123 {
124     return impl::make_binary3
125     <shift_l_op, variable<PHOENIX_STD::ostream>, BaseT>
126     ::construct(var(_0), _1);
127 }
128 
129 ///////////////////////////////////////////////////////////////////////////////
130 //
131 //  specializations for std::strstream / stringstream
132 //
133 ///////////////////////////////////////////////////////////////////////////////
134 template <typename T1>
135 struct binary_operator<shift_r_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
136 {
137     typedef PHOENIX_STD::istream& result_type;
evalphoenix::binary_operator138     static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
139     { return out >> rhs; }
140 };
141 
142 //////////////////////////////////
143 template <typename BaseT>
144 inline typename impl::make_binary3
145     <shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
operator >>(PHOENIX_STD::PHOENIX_SSTREAM & _0,actor<BaseT> const & _1)146 operator>>(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
147 {
148     return impl::make_binary3
149     <shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
150     ::construct(var(_0), _1);
151 }
152 
153 //////////////////////////////////
154 template <typename T1>
155 struct binary_operator<shift_l_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
156 {
157     typedef PHOENIX_STD::ostream& result_type;
evalphoenix::binary_operator158     static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
159     { return out << rhs; }
160 };
161 
162 //////////////////////////////////
163 template <typename BaseT>
164 inline typename impl::make_binary3
165     <shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
operator <<(PHOENIX_STD::PHOENIX_SSTREAM & _0,actor<BaseT> const & _1)166 operator<<(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
167 {
168     return impl::make_binary3
169     <shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
170     ::construct(var(_0), _1);
171 }
172 
173 ///////////////////////////////////////////////////////////////////////////////
174 //
175 //      I/O manipulator specializations
176 //
177 ///////////////////////////////////////////////////////////////////////////////
178 
179 typedef PHOENIX_STD::ios_base&  (*iomanip_t)(PHOENIX_STD::ios_base&);
180 typedef PHOENIX_STD::istream&   (*imanip_t)(PHOENIX_STD::istream&);
181 typedef PHOENIX_STD::ostream&   (*omanip_t)(PHOENIX_STD::ostream&);
182 
183 #if defined(__BORLANDC__)
184 
185 ///////////////////////////////////////////////////////////////////////////////
186 //
187 //      Borland does not like i/o manipulators functions such as endl to
188 //      be the rhs of a lazy << operator (Borland incorrectly reports
189 //      ambiguity). To get around the problem, we provide function
190 //      pointer versions of the same name with a single trailing
191 //      underscore.
192 //
193 //      You can use the same trick for other i/o manipulators.
194 //      Alternatively, you can prefix the manipulator with a '&'
195 //      operator. Example:
196 //
197 //          cout << arg1 << &endl
198 //
199 ///////////////////////////////////////////////////////////////////////////////
200 
201 imanip_t    ws_     = &PHOENIX_STD::ws;
202 iomanip_t   dec_    = &PHOENIX_STD::dec;
203 iomanip_t   hex_    = &PHOENIX_STD::hex;
204 iomanip_t   oct_    = &PHOENIX_STD::oct;
205 omanip_t    endl_   = &PHOENIX_STD::endl;
206 omanip_t    ends_   = &PHOENIX_STD::ends;
207 omanip_t    flush_  = &PHOENIX_STD::flush;
208 
209 #else // __BORLANDC__
210 
211 ///////////////////////////////////////////////////////////////////////////////
212 //
213 //      The following are overloads for I/O manipulators.
214 //
215 ///////////////////////////////////////////////////////////////////////////////
216 template <typename BaseT>
217 inline typename impl::make_binary1<shift_l_op, BaseT, imanip_t>::type
operator >>(actor<BaseT> const & _0,imanip_t _1)218 operator>>(actor<BaseT> const& _0, imanip_t _1)
219 {
220     return impl::make_binary1<shift_l_op, BaseT, imanip_t>::construct(_0, _1);
221 }
222 
223 //////////////////////////////////
224 template <typename BaseT>
225 inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
operator >>(actor<BaseT> const & _0,iomanip_t _1)226 operator>>(actor<BaseT> const& _0, iomanip_t _1)
227 {
228     return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
229 }
230 
231 //////////////////////////////////
232 template <typename BaseT>
233 inline typename impl::make_binary1<shift_l_op, BaseT, omanip_t>::type
operator <<(actor<BaseT> const & _0,omanip_t _1)234 operator<<(actor<BaseT> const& _0, omanip_t _1)
235 {
236     return impl::make_binary1<shift_l_op, BaseT, omanip_t>::construct(_0, _1);
237 }
238 
239 //////////////////////////////////
240 template <typename BaseT>
241 inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
operator <<(actor<BaseT> const & _0,iomanip_t _1)242 operator<<(actor<BaseT> const& _0, iomanip_t _1)
243 {
244     return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
245 }
246 
247 #endif // __BORLANDC__
248 
249 ///////////////////////////////////////////////////////////////////////////////
250 //
251 //  specializations for stl iterators and containers
252 //
253 ///////////////////////////////////////////////////////////////////////////////
254 template <typename T>
255 struct unary_operator<dereference_op, T>
256 {
257     typedef typename T::reference result_type;
evalphoenix::unary_operator258     static result_type eval(T const& iter)
259     { return *iter; }
260 };
261 
262 //////////////////////////////////
263 template <typename T0, typename T1>
264 struct binary_operator<index_op, T0, T1>
265 {
266     typedef typename T0::reference result_type;
evalphoenix::binary_operator267     static result_type eval(T0& container, T1 const& index)
268     { return container[index]; }
269 };
270 
271 //////////////////////////////////
272 template <typename T0, typename T1>
273 struct binary_operator<index_op, T0 const, T1>
274 {
275     typedef typename T0::const_reference result_type;
evalphoenix::binary_operator276     static result_type eval(T0 const& container, T1 const& index)
277     { return container[index]; }
278 };
279 
280 ///////////////////////////////////////////////////////////////////////////////
281 }   //  namespace phoenix
282 
283 #undef PHOENIX_SSTREAM
284 #undef PHOENIX_STD
285 #endif
286