1 /*=============================================================================
3 Copyright (c) 2001-2002 Joel de Guzman
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
11 #include <boost/config.hpp>
12 #ifdef BOOST_NO_STRINGSTREAM
14 #define PHOENIX_SSTREAM strstream
17 #define PHOENIX_SSTREAM stringstream
20 ///////////////////////////////////////////////////////////////////////////////
21 #include <boost/spirit/home/classic/phoenix/operators.hpp>
24 ///////////////////////////////////////////////////////////////////////////////
25 #if defined(_STLPORT_VERSION) && defined(__STL_USE_OWN_NAMESPACE)
26 #define PHOENIX_STD _STLP_STD
27 #define PHOENIX_NO_STD_NAMESPACE
29 #define PHOENIX_STD std
32 ///////////////////////////////////////////////////////////////////////////////
33 //#if !defined(PHOENIX_NO_STD_NAMESPACE)
38 template<typename T> class complex;
40 //#if !defined(PHOENIX_NO_STD_NAMESPACE)
44 ///////////////////////////////////////////////////////////////////////////////
48 ///////////////////////////////////////////////////////////////////////////////
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
55 // *iostream (e.g. cout, cin, strstream/ stringstream) uses non-
56 // canonical shift operator overloads where the lhs is taken in
59 // *I/O manipulators overloads for the RHS of the << and >>
62 // *STL iterators can be objects that conform to pointer semantics.
63 // Some operators need to be specialized for these.
65 // *std::complex is given a rank (see rank class in operators.hpp)
67 ///////////////////////////////////////////////////////////////////////////////
69 ///////////////////////////////////////////////////////////////////////////////
71 // specialization for rank<std::complex>
73 ///////////////////////////////////////////////////////////////////////////////
74 template <typename T> struct rank<PHOENIX_STD::complex<T> >
75 { static int const value = 170 + rank<T>::value; };
77 ///////////////////////////////////////////////////////////////////////////////
79 // specializations for std::istream
81 ///////////////////////////////////////////////////////////////////////////////
83 //////////////////////////////////
84 template <typename T1>
85 struct binary_operator<shift_r_op, PHOENIX_STD::istream, T1>
87 typedef PHOENIX_STD::istream& result_type;
88 static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
89 { return out >> rhs; }
92 //////////////////////////////////
93 template <typename BaseT>
94 inline typename impl::make_binary3
95 <shift_r_op, variable<PHOENIX_STD::istream>, BaseT>::type
96 operator>>(PHOENIX_STD::istream& _0, actor<BaseT> const& _1)
98 return impl::make_binary3
99 <shift_r_op, variable<PHOENIX_STD::istream>, BaseT>
100 ::construct(var(_0), _1);
103 ///////////////////////////////////////////////////////////////////////////////
105 // specializations for std::ostream
107 ///////////////////////////////////////////////////////////////////////////////
109 //////////////////////////////////
110 template <typename T1>
111 struct binary_operator<shift_l_op, PHOENIX_STD::ostream, T1>
113 typedef PHOENIX_STD::ostream& result_type;
114 static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
115 { return out << rhs; }
118 //////////////////////////////////
119 template <typename BaseT>
120 inline typename impl::make_binary3
121 <shift_l_op, variable<PHOENIX_STD::ostream>, BaseT>::type
122 operator<<(PHOENIX_STD::ostream& _0, actor<BaseT> const& _1)
124 return impl::make_binary3
125 <shift_l_op, variable<PHOENIX_STD::ostream>, BaseT>
126 ::construct(var(_0), _1);
129 ///////////////////////////////////////////////////////////////////////////////
131 // specializations for std::strstream / stringstream
133 ///////////////////////////////////////////////////////////////////////////////
134 template <typename T1>
135 struct binary_operator<shift_r_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
137 typedef PHOENIX_STD::istream& result_type;
138 static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
139 { return out >> rhs; }
142 //////////////////////////////////
143 template <typename BaseT>
144 inline typename impl::make_binary3
145 <shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
146 operator>>(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
148 return impl::make_binary3
149 <shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
150 ::construct(var(_0), _1);
153 //////////////////////////////////
154 template <typename T1>
155 struct binary_operator<shift_l_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
157 typedef PHOENIX_STD::ostream& result_type;
158 static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
159 { return out << rhs; }
162 //////////////////////////////////
163 template <typename BaseT>
164 inline typename impl::make_binary3
165 <shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
166 operator<<(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
168 return impl::make_binary3
169 <shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
170 ::construct(var(_0), _1);
173 ///////////////////////////////////////////////////////////////////////////////
175 // I/O manipulator specializations
177 ///////////////////////////////////////////////////////////////////////////////
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&);
183 #if defined(__BORLANDC__)
185 ///////////////////////////////////////////////////////////////////////////////
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
193 // You can use the same trick for other i/o manipulators.
194 // Alternatively, you can prefix the manipulator with a '&'
195 // operator. Example:
197 // cout << arg1 << &endl
199 ///////////////////////////////////////////////////////////////////////////////
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;
209 #else // __BORLANDC__
211 ///////////////////////////////////////////////////////////////////////////////
213 // The following are overloads for I/O manipulators.
215 ///////////////////////////////////////////////////////////////////////////////
216 template <typename BaseT>
217 inline typename impl::make_binary1<shift_l_op, BaseT, imanip_t>::type
218 operator>>(actor<BaseT> const& _0, imanip_t _1)
220 return impl::make_binary1<shift_l_op, BaseT, imanip_t>::construct(_0, _1);
223 //////////////////////////////////
224 template <typename BaseT>
225 inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
226 operator>>(actor<BaseT> const& _0, iomanip_t _1)
228 return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
231 //////////////////////////////////
232 template <typename BaseT>
233 inline typename impl::make_binary1<shift_l_op, BaseT, omanip_t>::type
234 operator<<(actor<BaseT> const& _0, omanip_t _1)
236 return impl::make_binary1<shift_l_op, BaseT, omanip_t>::construct(_0, _1);
239 //////////////////////////////////
240 template <typename BaseT>
241 inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
242 operator<<(actor<BaseT> const& _0, iomanip_t _1)
244 return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
247 #endif // __BORLANDC__
249 ///////////////////////////////////////////////////////////////////////////////
251 // specializations for stl iterators and containers
253 ///////////////////////////////////////////////////////////////////////////////
254 template <typename T>
255 struct unary_operator<dereference_op, T>
257 typedef typename T::reference result_type;
258 static result_type eval(T const& iter)
262 //////////////////////////////////
263 template <typename T0, typename T1>
264 struct binary_operator<index_op, T0, T1>
266 typedef typename T0::reference result_type;
267 static result_type eval(T0& container, T1 const& index)
268 { return container[index]; }
271 //////////////////////////////////
272 template <typename T0, typename T1>
273 struct binary_operator<index_op, T0 const, T1>
275 typedef typename T0::const_reference result_type;
276 static result_type eval(T0 const& container, T1 const& index)
277 { return container[index]; }
280 ///////////////////////////////////////////////////////////////////////////////
281 } // namespace phoenix
283 #undef PHOENIX_SSTREAM