special_ops.hpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*=============================================================================
  2. Phoenix V1.2.1
  3. Copyright (c) 2001-2002 Joel de Guzman
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #ifndef PHOENIX_SPECIAL_OPS_HPP
  8. #define PHOENIX_SPECIAL_OPS_HPP
  9. #include <boost/config.hpp>
  10. #ifdef BOOST_NO_STRINGSTREAM
  11. #include <strstream>
  12. #define PHOENIX_SSTREAM strstream
  13. #else
  14. #include <sstream>
  15. #define PHOENIX_SSTREAM stringstream
  16. #endif
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include <boost/spirit/home/classic/phoenix/operators.hpp>
  19. #include <iosfwd>
  20. #include <complex>
  21. ///////////////////////////////////////////////////////////////////////////////
  22. #if defined(_STLPORT_VERSION) && defined(__STL_USE_OWN_NAMESPACE)
  23. #define PHOENIX_STD _STLP_STD
  24. #define PHOENIX_NO_STD_NAMESPACE
  25. #else
  26. #define PHOENIX_STD std
  27. #endif
  28. ///////////////////////////////////////////////////////////////////////////////
  29. namespace phoenix
  30. {
  31. ///////////////////////////////////////////////////////////////////////////////
  32. //
  33. // The following specializations take into account the C++ standard
  34. // library components. There are a couple of issues that have to be
  35. // dealt with to enable lazy operator overloads for the standard
  36. // library classes.
  37. //
  38. // *iostream (e.g. cout, cin, strstream/ stringstream) uses non-
  39. // canonical shift operator overloads where the lhs is taken in
  40. // by reference.
  41. //
  42. // *I/O manipulators overloads for the RHS of the << and >>
  43. // operators.
  44. //
  45. // *STL iterators can be objects that conform to pointer semantics.
  46. // Some operators need to be specialized for these.
  47. //
  48. // *std::complex is given a rank (see rank class in operators.hpp)
  49. //
  50. ///////////////////////////////////////////////////////////////////////////////
  51. ///////////////////////////////////////////////////////////////////////////////
  52. //
  53. // specialization for rank<std::complex>
  54. //
  55. ///////////////////////////////////////////////////////////////////////////////
  56. template <typename T> struct rank<PHOENIX_STD::complex<T> >
  57. { static int const value = 170 + rank<T>::value; };
  58. ///////////////////////////////////////////////////////////////////////////////
  59. //
  60. // specializations for std::istream
  61. //
  62. ///////////////////////////////////////////////////////////////////////////////
  63. //////////////////////////////////
  64. template <typename T1>
  65. struct binary_operator<shift_r_op, PHOENIX_STD::istream, T1>
  66. {
  67. typedef PHOENIX_STD::istream& result_type;
  68. static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
  69. { return out >> rhs; }
  70. };
  71. //////////////////////////////////
  72. template <typename BaseT>
  73. inline typename impl::make_binary3
  74. <shift_r_op, variable<PHOENIX_STD::istream>, BaseT>::type
  75. operator>>(PHOENIX_STD::istream& _0, actor<BaseT> const& _1)
  76. {
  77. return impl::make_binary3
  78. <shift_r_op, variable<PHOENIX_STD::istream>, BaseT>
  79. ::construct(var(_0), _1);
  80. }
  81. ///////////////////////////////////////////////////////////////////////////////
  82. //
  83. // specializations for std::ostream
  84. //
  85. ///////////////////////////////////////////////////////////////////////////////
  86. //////////////////////////////////
  87. template <typename T1>
  88. struct binary_operator<shift_l_op, PHOENIX_STD::ostream, T1>
  89. {
  90. typedef PHOENIX_STD::ostream& result_type;
  91. static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
  92. { return out << rhs; }
  93. };
  94. //////////////////////////////////
  95. template <typename BaseT>
  96. inline typename impl::make_binary3
  97. <shift_l_op, variable<PHOENIX_STD::ostream>, BaseT>::type
  98. operator<<(PHOENIX_STD::ostream& _0, actor<BaseT> const& _1)
  99. {
  100. return impl::make_binary3
  101. <shift_l_op, variable<PHOENIX_STD::ostream>, BaseT>
  102. ::construct(var(_0), _1);
  103. }
  104. ///////////////////////////////////////////////////////////////////////////////
  105. //
  106. // specializations for std::strstream / stringstream
  107. //
  108. ///////////////////////////////////////////////////////////////////////////////
  109. template <typename T1>
  110. struct binary_operator<shift_r_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
  111. {
  112. typedef PHOENIX_STD::istream& result_type;
  113. static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
  114. { return out >> rhs; }
  115. };
  116. //////////////////////////////////
  117. template <typename BaseT>
  118. inline typename impl::make_binary3
  119. <shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
  120. operator>>(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
  121. {
  122. return impl::make_binary3
  123. <shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
  124. ::construct(var(_0), _1);
  125. }
  126. //////////////////////////////////
  127. template <typename T1>
  128. struct binary_operator<shift_l_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
  129. {
  130. typedef PHOENIX_STD::ostream& result_type;
  131. static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
  132. { return out << rhs; }
  133. };
  134. //////////////////////////////////
  135. template <typename BaseT>
  136. inline typename impl::make_binary3
  137. <shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
  138. operator<<(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
  139. {
  140. return impl::make_binary3
  141. <shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
  142. ::construct(var(_0), _1);
  143. }
  144. ///////////////////////////////////////////////////////////////////////////////
  145. //
  146. // I/O manipulator specializations
  147. //
  148. ///////////////////////////////////////////////////////////////////////////////
  149. typedef PHOENIX_STD::ios_base& (*iomanip_t)(PHOENIX_STD::ios_base&);
  150. typedef PHOENIX_STD::istream& (*imanip_t)(PHOENIX_STD::istream&);
  151. typedef PHOENIX_STD::ostream& (*omanip_t)(PHOENIX_STD::ostream&);
  152. #if defined(__BORLANDC__)
  153. ///////////////////////////////////////////////////////////////////////////////
  154. //
  155. // Borland does not like i/o manipulators functions such as endl to
  156. // be the rhs of a lazy << operator (Borland incorrectly reports
  157. // ambiguity). To get around the problem, we provide function
  158. // pointer versions of the same name with a single trailing
  159. // underscore.
  160. //
  161. // You can use the same trick for other i/o manipulators.
  162. // Alternatively, you can prefix the manipulator with a '&'
  163. // operator. Example:
  164. //
  165. // cout << arg1 << &endl
  166. //
  167. ///////////////////////////////////////////////////////////////////////////////
  168. imanip_t ws_ = &PHOENIX_STD::ws;
  169. iomanip_t dec_ = &PHOENIX_STD::dec;
  170. iomanip_t hex_ = &PHOENIX_STD::hex;
  171. iomanip_t oct_ = &PHOENIX_STD::oct;
  172. omanip_t endl_ = &PHOENIX_STD::endl;
  173. omanip_t ends_ = &PHOENIX_STD::ends;
  174. omanip_t flush_ = &PHOENIX_STD::flush;
  175. #else // __BORLANDC__
  176. ///////////////////////////////////////////////////////////////////////////////
  177. //
  178. // The following are overloads for I/O manipulators.
  179. //
  180. ///////////////////////////////////////////////////////////////////////////////
  181. template <typename BaseT>
  182. inline typename impl::make_binary1<shift_l_op, BaseT, imanip_t>::type
  183. operator>>(actor<BaseT> const& _0, imanip_t _1)
  184. {
  185. return impl::make_binary1<shift_l_op, BaseT, imanip_t>::construct(_0, _1);
  186. }
  187. //////////////////////////////////
  188. template <typename BaseT>
  189. inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
  190. operator>>(actor<BaseT> const& _0, iomanip_t _1)
  191. {
  192. return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
  193. }
  194. //////////////////////////////////
  195. template <typename BaseT>
  196. inline typename impl::make_binary1<shift_l_op, BaseT, omanip_t>::type
  197. operator<<(actor<BaseT> const& _0, omanip_t _1)
  198. {
  199. return impl::make_binary1<shift_l_op, BaseT, omanip_t>::construct(_0, _1);
  200. }
  201. //////////////////////////////////
  202. template <typename BaseT>
  203. inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
  204. operator<<(actor<BaseT> const& _0, iomanip_t _1)
  205. {
  206. return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
  207. }
  208. #endif // __BORLANDC__
  209. ///////////////////////////////////////////////////////////////////////////////
  210. //
  211. // specializations for stl iterators and containers
  212. //
  213. ///////////////////////////////////////////////////////////////////////////////
  214. template <typename T>
  215. struct unary_operator<dereference_op, T>
  216. {
  217. typedef typename T::reference result_type;
  218. static result_type eval(T const& iter)
  219. { return *iter; }
  220. };
  221. //////////////////////////////////
  222. template <typename T0, typename T1>
  223. struct binary_operator<index_op, T0, T1>
  224. {
  225. typedef typename T0::reference result_type;
  226. static result_type eval(T0& container, T1 const& index)
  227. { return container[index]; }
  228. };
  229. //////////////////////////////////
  230. template <typename T0, typename T1>
  231. struct binary_operator<index_op, T0 const, T1>
  232. {
  233. typedef typename T0::const_reference result_type;
  234. static result_type eval(T0 const& container, T1 const& index)
  235. { return container[index]; }
  236. };
  237. ///////////////////////////////////////////////////////////////////////////////
  238. } // namespace phoenix
  239. #undef PHOENIX_SSTREAM
  240. #undef PHOENIX_STD
  241. #endif