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