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