Chris@16: /*============================================================================= Chris@16: Phoenix V1.2.1 Chris@16: Copyright (c) 2001-2002 Joel de Guzman Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #ifndef PHOENIX_SPECIAL_OPS_HPP Chris@16: #define PHOENIX_SPECIAL_OPS_HPP Chris@16: Chris@16: #include Chris@16: #ifdef BOOST_NO_STRINGSTREAM Chris@16: #include Chris@16: #define PHOENIX_SSTREAM strstream Chris@16: #else Chris@16: #include Chris@16: #define PHOENIX_SSTREAM stringstream Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: #include Chris@16: #include Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: #if defined(_STLPORT_VERSION) && defined(__STL_USE_OWN_NAMESPACE) Chris@16: #define PHOENIX_STD _STLP_STD Chris@16: #define PHOENIX_NO_STD_NAMESPACE Chris@16: #else Chris@16: #define PHOENIX_STD std Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: //#if !defined(PHOENIX_NO_STD_NAMESPACE) Chris@16: namespace PHOENIX_STD Chris@16: { Chris@16: //#endif Chris@16: Chris@16: template class complex; Chris@16: Chris@16: //#if !defined(PHOENIX_NO_STD_NAMESPACE) Chris@16: } Chris@16: //#endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace phoenix Chris@16: { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The following specializations take into account the C++ standard Chris@16: // library components. There are a couple of issues that have to be Chris@16: // dealt with to enable lazy operator overloads for the standard Chris@16: // library classes. Chris@16: // Chris@16: // *iostream (e.g. cout, cin, strstream/ stringstream) uses non- Chris@16: // canonical shift operator overloads where the lhs is taken in Chris@16: // by reference. Chris@16: // Chris@16: // *I/O manipulators overloads for the RHS of the << and >> Chris@16: // operators. Chris@16: // Chris@16: // *STL iterators can be objects that conform to pointer semantics. Chris@16: // Some operators need to be specialized for these. Chris@16: // Chris@16: // *std::complex is given a rank (see rank class in operators.hpp) Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // specialization for rank Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template struct rank > Chris@16: { static int const value = 170 + rank::value; }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // specializations for std::istream Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator Chris@16: { Chris@16: typedef PHOENIX_STD::istream& result_type; Chris@16: static result_type eval(PHOENIX_STD::istream& out, T1& rhs) Chris@16: { return out >> rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3 Chris@101: , BaseT>::type Chris@101: operator>>(PHOENIX_STD::istream& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3 Chris@101: , BaseT> Chris@16: ::construct(var(_0), _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // specializations for std::ostream Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator Chris@16: { Chris@16: typedef PHOENIX_STD::ostream& result_type; Chris@16: static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs) Chris@16: { return out << rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3 Chris@101: , BaseT>::type Chris@101: operator<<(PHOENIX_STD::ostream& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3 Chris@101: , BaseT> Chris@16: ::construct(var(_0), _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // specializations for std::strstream / stringstream Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct binary_operator Chris@16: { Chris@16: typedef PHOENIX_STD::istream& result_type; Chris@16: static result_type eval(PHOENIX_STD::istream& out, T1& rhs) Chris@16: { return out >> rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3 Chris@16: , BaseT>::type Chris@16: operator>>(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3 Chris@16: , BaseT> Chris@16: ::construct(var(_0), _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator Chris@16: { Chris@16: typedef PHOENIX_STD::ostream& result_type; Chris@16: static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs) Chris@16: { return out << rhs; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary3 Chris@16: , BaseT>::type Chris@16: operator<<(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor const& _1) Chris@16: { Chris@16: return impl::make_binary3 Chris@16: , BaseT> Chris@16: ::construct(var(_0), _1); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // I/O manipulator specializations Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: typedef PHOENIX_STD::ios_base& (*iomanip_t)(PHOENIX_STD::ios_base&); Chris@16: typedef PHOENIX_STD::istream& (*imanip_t)(PHOENIX_STD::istream&); Chris@16: typedef PHOENIX_STD::ostream& (*omanip_t)(PHOENIX_STD::ostream&); Chris@16: Chris@16: #if defined(__BORLANDC__) Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // Borland does not like i/o manipulators functions such as endl to Chris@16: // be the rhs of a lazy << operator (Borland incorrectly reports Chris@16: // ambiguity). To get around the problem, we provide function Chris@16: // pointer versions of the same name with a single trailing Chris@16: // underscore. Chris@16: // Chris@16: // You can use the same trick for other i/o manipulators. Chris@16: // Alternatively, you can prefix the manipulator with a '&' Chris@16: // operator. Example: Chris@16: // Chris@16: // cout << arg1 << &endl Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: imanip_t ws_ = &PHOENIX_STD::ws; Chris@16: iomanip_t dec_ = &PHOENIX_STD::dec; Chris@16: iomanip_t hex_ = &PHOENIX_STD::hex; Chris@16: iomanip_t oct_ = &PHOENIX_STD::oct; Chris@16: omanip_t endl_ = &PHOENIX_STD::endl; Chris@16: omanip_t ends_ = &PHOENIX_STD::ends; Chris@16: omanip_t flush_ = &PHOENIX_STD::flush; Chris@16: Chris@16: #else // __BORLANDC__ Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The following are overloads for I/O manipulators. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator>>(actor const& _0, imanip_t _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator>>(actor const& _0, iomanip_t _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator<<(actor const& _0, omanip_t _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: inline typename impl::make_binary1::type Chris@16: operator<<(actor const& _0, iomanip_t _1) Chris@16: { Chris@16: return impl::make_binary1::construct(_0, _1); Chris@16: } Chris@16: Chris@16: #endif // __BORLANDC__ Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // specializations for stl iterators and containers Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct unary_operator Chris@16: { Chris@16: typedef typename T::reference result_type; Chris@16: static result_type eval(T const& iter) Chris@16: { return *iter; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator Chris@16: { Chris@16: typedef typename T0::reference result_type; Chris@16: static result_type eval(T0& container, T1 const& index) Chris@16: { return container[index]; } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: template Chris@16: struct binary_operator Chris@16: { Chris@16: typedef typename T0::const_reference result_type; Chris@16: static result_type eval(T0 const& container, T1 const& index) Chris@16: { return container[index]; } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: } // namespace phoenix Chris@16: Chris@16: #undef PHOENIX_SSTREAM Chris@16: #undef PHOENIX_STD Chris@16: #endif