operators.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. // Copyright David Abrahams 2002.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef OPERATORS_DWA2002530_HPP
  6. # define OPERATORS_DWA2002530_HPP
  7. # include <boost/python/detail/prefix.hpp>
  8. # include <boost/python/def_visitor.hpp>
  9. # include <boost/python/converter/arg_to_python.hpp>
  10. # include <boost/python/detail/operator_id.hpp>
  11. # include <boost/python/detail/not_specified.hpp>
  12. # include <boost/python/back_reference.hpp>
  13. # include <boost/mpl/if.hpp>
  14. # include <boost/mpl/eval_if.hpp>
  15. # include <boost/python/self.hpp>
  16. # include <boost/python/other.hpp>
  17. # include <boost/lexical_cast.hpp>
  18. # include <boost/python/refcount.hpp>
  19. # include <boost/python/detail/unwrap_wrapper.hpp>
  20. # include <string>
  21. # include <complex>
  22. namespace boost { namespace python {
  23. namespace detail
  24. {
  25. // This is essentially the old v1 to_python(). It will be eliminated
  26. // once the public interface for to_python is settled on.
  27. template <class T>
  28. PyObject* convert_result(T const& x)
  29. {
  30. return converter::arg_to_python<T>(x).release();
  31. }
  32. // Operator implementation template declarations. The nested apply
  33. // declaration here keeps MSVC6 happy.
  34. template <operator_id> struct operator_l
  35. {
  36. template <class L, class R> struct apply;
  37. };
  38. template <operator_id> struct operator_r
  39. {
  40. template <class L, class R> struct apply;
  41. };
  42. template <operator_id> struct operator_1
  43. {
  44. template <class T> struct apply;
  45. };
  46. // MSVC6 doesn't want us to do this sort of inheritance on a nested
  47. // class template, so we use this layer of indirection to avoid
  48. // ::template<...> on the nested apply functions below
  49. template <operator_id id, class L, class R>
  50. struct operator_l_inner
  51. : operator_l<id>::template apply<L,R>
  52. {};
  53. template <operator_id id, class L, class R>
  54. struct operator_r_inner
  55. : operator_r<id>::template apply<L,R>
  56. {};
  57. template <operator_id id, class T>
  58. struct operator_1_inner
  59. : operator_1<id>::template apply<T>
  60. {};
  61. // Define three different binary_op templates which take care of
  62. // these cases:
  63. // self op self
  64. // self op R
  65. // L op self
  66. //
  67. // The inner apply metafunction is used to adjust the operator to
  68. // the class type being defined. Inheritance of the outer class is
  69. // simply used to provide convenient access to the operation's
  70. // name().
  71. // self op self
  72. template <operator_id id>
  73. struct binary_op : operator_l<id>
  74. {
  75. template <class T>
  76. struct apply : operator_l_inner<id,T,T>
  77. {
  78. };
  79. };
  80. // self op R
  81. template <operator_id id, class R>
  82. struct binary_op_l : operator_l<id>
  83. {
  84. template <class T>
  85. struct apply : operator_l_inner<id,T,R>
  86. {
  87. };
  88. };
  89. // L op self
  90. template <operator_id id, class L>
  91. struct binary_op_r : operator_r<id>
  92. {
  93. template <class T>
  94. struct apply : operator_r_inner<id,L,T>
  95. {
  96. };
  97. };
  98. template <operator_id id>
  99. struct unary_op : operator_1<id>
  100. {
  101. template <class T>
  102. struct apply : operator_1_inner<id,T>
  103. {
  104. };
  105. };
  106. // This type is what actually gets returned from operators used on
  107. // self_t
  108. template <operator_id id, class L = not_specified, class R = not_specified>
  109. struct operator_
  110. : def_visitor<operator_<id,L,R> >
  111. {
  112. private:
  113. template <class ClassT>
  114. void visit(ClassT& cl) const
  115. {
  116. typedef typename mpl::eval_if<
  117. is_same<L,self_t>
  118. , mpl::if_<
  119. is_same<R,self_t>
  120. , binary_op<id>
  121. , binary_op_l<
  122. id
  123. , BOOST_DEDUCED_TYPENAME unwrap_other<R>::type
  124. >
  125. >
  126. , mpl::if_<
  127. is_same<L,not_specified>
  128. , unary_op<id>
  129. , binary_op_r<
  130. id
  131. , BOOST_DEDUCED_TYPENAME unwrap_other<L>::type
  132. >
  133. >
  134. >::type generator;
  135. cl.def(
  136. generator::name()
  137. , &generator::template apply<
  138. BOOST_DEDUCED_TYPENAME ClassT::wrapped_type
  139. >::execute
  140. );
  141. }
  142. friend class python::def_visitor_access;
  143. };
  144. }
  145. # define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \
  146. namespace detail \
  147. { \
  148. template <> \
  149. struct operator_l<op_##id> \
  150. { \
  151. template <class L, class R> \
  152. struct apply \
  153. { \
  154. typedef typename unwrap_wrapper_<L>::type lhs; \
  155. typedef typename unwrap_wrapper_<R>::type rhs; \
  156. static PyObject* execute(lhs& l, rhs const& r) \
  157. { \
  158. return detail::convert_result(expr); \
  159. } \
  160. }; \
  161. static char const* name() { return "__" #id "__"; } \
  162. }; \
  163. \
  164. template <> \
  165. struct operator_r<op_##id> \
  166. { \
  167. template <class L, class R> \
  168. struct apply \
  169. { \
  170. typedef typename unwrap_wrapper_<L>::type lhs; \
  171. typedef typename unwrap_wrapper_<R>::type rhs; \
  172. static PyObject* execute(rhs& r, lhs const& l) \
  173. { \
  174. return detail::convert_result(expr); \
  175. } \
  176. }; \
  177. static char const* name() { return "__" #rid "__"; } \
  178. }; \
  179. }
  180. # define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \
  181. BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \
  182. namespace self_ns \
  183. { \
  184. template <class L, class R> \
  185. inline detail::operator_<detail::op_##id,L,R> \
  186. operator op(L const&, R const&) \
  187. { \
  188. return detail::operator_<detail::op_##id,L,R>(); \
  189. } \
  190. }
  191. BOOST_PYTHON_BINARY_OPERATOR(add, radd, +)
  192. BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -)
  193. BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *)
  194. #if PY_VERSION_HEX >= 0x03000000
  195. BOOST_PYTHON_BINARY_OPERATOR(truediv, rtruediv, /)
  196. #else
  197. BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /)
  198. #endif
  199. BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %)
  200. BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<)
  201. BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>)
  202. BOOST_PYTHON_BINARY_OPERATOR(and, rand, &)
  203. BOOST_PYTHON_BINARY_OPERATOR(xor, rxor, ^)
  204. BOOST_PYTHON_BINARY_OPERATOR(or, ror, |)
  205. BOOST_PYTHON_BINARY_OPERATOR(gt, lt, >)
  206. BOOST_PYTHON_BINARY_OPERATOR(ge, le, >=)
  207. BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <)
  208. BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=)
  209. BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==)
  210. BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=)
  211. # undef BOOST_PYTHON_BINARY_OPERATOR
  212. // pow isn't an operator in C++; handle it specially.
  213. BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r))
  214. # undef BOOST_PYTHON_BINARY_OPERATION
  215. namespace self_ns
  216. {
  217. # ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
  218. template <class L, class R>
  219. inline detail::operator_<detail::op_pow,L,R>
  220. pow(L const&, R const&)
  221. {
  222. return detail::operator_<detail::op_pow,L,R>();
  223. }
  224. # else
  225. // When there's no argument-dependent lookup, we need these
  226. // overloads to handle the case when everything is imported into the
  227. // global namespace. Note that the plain overload below does /not/
  228. // take const& arguments. This is needed by MSVC6 at least, or it
  229. // complains of ambiguities, since there's no partial ordering.
  230. inline detail::operator_<detail::op_pow,self_t,self_t>
  231. pow(self_t, self_t)
  232. {
  233. return detail::operator_<detail::op_pow,self_t,self_t>();
  234. }
  235. template <class R>
  236. inline detail::operator_<detail::op_pow,self_t,R>
  237. pow(self_t const&, R const&)
  238. {
  239. return detail::operator_<detail::op_pow,self_t,R>();
  240. }
  241. template <class L>
  242. inline detail::operator_<detail::op_pow,L,self_t>
  243. pow(L const&, self_t const&)
  244. {
  245. return detail::operator_<detail::op_pow,L,self_t>();
  246. }
  247. # endif
  248. }
  249. # define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \
  250. namespace detail \
  251. { \
  252. template <> \
  253. struct operator_l<op_##id> \
  254. { \
  255. template <class L, class R> \
  256. struct apply \
  257. { \
  258. typedef typename unwrap_wrapper_<L>::type lhs; \
  259. typedef typename unwrap_wrapper_<R>::type rhs; \
  260. static PyObject* \
  261. execute(back_reference<lhs&> l, rhs const& r) \
  262. { \
  263. l.get() op r; \
  264. return python::incref(l.source().ptr()); \
  265. } \
  266. }; \
  267. static char const* name() { return "__" #id "__"; } \
  268. }; \
  269. } \
  270. namespace self_ns \
  271. { \
  272. template <class R> \
  273. inline detail::operator_<detail::op_##id,self_t,R> \
  274. operator op(self_t const&, R const&) \
  275. { \
  276. return detail::operator_<detail::op_##id,self_t,R>(); \
  277. } \
  278. }
  279. BOOST_PYTHON_INPLACE_OPERATOR(iadd,+=)
  280. BOOST_PYTHON_INPLACE_OPERATOR(isub,-=)
  281. BOOST_PYTHON_INPLACE_OPERATOR(imul,*=)
  282. BOOST_PYTHON_INPLACE_OPERATOR(idiv,/=)
  283. BOOST_PYTHON_INPLACE_OPERATOR(imod,%=)
  284. BOOST_PYTHON_INPLACE_OPERATOR(ilshift,<<=)
  285. BOOST_PYTHON_INPLACE_OPERATOR(irshift,>>=)
  286. BOOST_PYTHON_INPLACE_OPERATOR(iand,&=)
  287. BOOST_PYTHON_INPLACE_OPERATOR(ixor,^=)
  288. BOOST_PYTHON_INPLACE_OPERATOR(ior,|=)
  289. # define BOOST_PYTHON_UNARY_OPERATOR(id, op, func_name) \
  290. namespace detail \
  291. { \
  292. template <> \
  293. struct operator_1<op_##id> \
  294. { \
  295. template <class T> \
  296. struct apply \
  297. { \
  298. typedef typename unwrap_wrapper_<T>::type self_t; \
  299. static PyObject* execute(self_t& x) \
  300. { \
  301. return detail::convert_result(op(x)); \
  302. } \
  303. }; \
  304. static char const* name() { return "__" #id "__"; } \
  305. }; \
  306. } \
  307. namespace self_ns \
  308. { \
  309. inline detail::operator_<detail::op_##id> \
  310. func_name(self_t const&) \
  311. { \
  312. return detail::operator_<detail::op_##id>(); \
  313. } \
  314. }
  315. # undef BOOST_PYTHON_INPLACE_OPERATOR
  316. BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-)
  317. BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+)
  318. BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs)
  319. BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~)
  320. #if PY_VERSION_HEX >= 0x03000000
  321. BOOST_PYTHON_UNARY_OPERATOR(bool, !!, operator!)
  322. #else
  323. BOOST_PYTHON_UNARY_OPERATOR(nonzero, !!, operator!)
  324. #endif
  325. BOOST_PYTHON_UNARY_OPERATOR(int, long, int_)
  326. BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
  327. BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)
  328. BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex<double>, complex_)
  329. BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast<std::string>, str)
  330. BOOST_PYTHON_UNARY_OPERATOR(repr, lexical_cast<std::string>, repr)
  331. # undef BOOST_PYTHON_UNARY_OPERATOR
  332. }} // namespace boost::python
  333. # ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
  334. using boost::python::self_ns::abs;
  335. using boost::python::self_ns::int_;
  336. using boost::python::self_ns::long_;
  337. using boost::python::self_ns::float_;
  338. using boost::python::self_ns::complex_;
  339. using boost::python::self_ns::str;
  340. using boost::python::self_ns::repr;
  341. using boost::python::self_ns::pow;
  342. # endif
  343. #endif // OPERATORS_DWA2002530_HPP