object_operators.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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 OBJECT_OPERATORS_DWA2002617_HPP
  6. # define OBJECT_OPERATORS_DWA2002617_HPP
  7. # include <boost/python/detail/prefix.hpp>
  8. # include <boost/python/object_core.hpp>
  9. # include <boost/python/call.hpp>
  10. # include <boost/iterator/detail/enable_if.hpp>
  11. # include <boost/mpl/bool.hpp>
  12. # include <boost/iterator/detail/config_def.hpp>
  13. namespace boost { namespace python { namespace api {
  14. template <class X>
  15. char is_object_operators_helper(object_operators<X> const*);
  16. typedef char (&no_type)[2];
  17. no_type is_object_operators_helper(...);
  18. template <class X> X* make_ptr();
  19. template <class L, class R = L>
  20. struct is_object_operators
  21. {
  22. enum {
  23. value
  24. = (sizeof(api::is_object_operators_helper(api::make_ptr<L>()))
  25. + sizeof(api::is_object_operators_helper(api::make_ptr<R>()))
  26. < 4
  27. )
  28. };
  29. typedef mpl::bool_<value> type;
  30. };
  31. # if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
  32. template <class L, class R, class T>
  33. struct enable_binary
  34. : boost::iterators::enable_if<is_object_operators<L,R>, T>
  35. {};
  36. # define BOOST_PYTHON_BINARY_RETURN(T) typename enable_binary<L,R,T>::type
  37. # else
  38. # define BOOST_PYTHON_BINARY_RETURN(T) T
  39. # endif
  40. template <class U>
  41. object object_operators<U>::operator()() const
  42. {
  43. object_cref2 f = *static_cast<U const*>(this);
  44. return call<object>(f.ptr());
  45. }
  46. template <class U>
  47. inline
  48. object_operators<U>::operator bool_type() const
  49. {
  50. object_cref2 x = *static_cast<U const*>(this);
  51. int is_true = PyObject_IsTrue(x.ptr());
  52. if (is_true < 0) throw_error_already_set();
  53. return is_true ? &object::ptr : 0;
  54. }
  55. template <class U>
  56. inline bool
  57. object_operators<U>::operator!() const
  58. {
  59. object_cref2 x = *static_cast<U const*>(this);
  60. int is_true = PyObject_IsTrue(x.ptr());
  61. if (is_true < 0) throw_error_already_set();
  62. return !is_true;
  63. }
  64. # define BOOST_PYTHON_COMPARE_OP(op, opid) \
  65. template <class L, class R> \
  66. BOOST_PYTHON_BINARY_RETURN(object) operator op(L const& l, R const& r) \
  67. { \
  68. return PyObject_RichCompare( \
  69. object(l).ptr(), object(r).ptr(), opid); \
  70. }
  71. # undef BOOST_PYTHON_COMPARE_OP
  72. # define BOOST_PYTHON_BINARY_OPERATOR(op) \
  73. BOOST_PYTHON_DECL object operator op(object const& l, object const& r); \
  74. template <class L, class R> \
  75. BOOST_PYTHON_BINARY_RETURN(object) operator op(L const& l, R const& r) \
  76. { \
  77. return object(l) op object(r); \
  78. }
  79. BOOST_PYTHON_BINARY_OPERATOR(>)
  80. BOOST_PYTHON_BINARY_OPERATOR(>=)
  81. BOOST_PYTHON_BINARY_OPERATOR(<)
  82. BOOST_PYTHON_BINARY_OPERATOR(<=)
  83. BOOST_PYTHON_BINARY_OPERATOR(==)
  84. BOOST_PYTHON_BINARY_OPERATOR(!=)
  85. BOOST_PYTHON_BINARY_OPERATOR(+)
  86. BOOST_PYTHON_BINARY_OPERATOR(-)
  87. BOOST_PYTHON_BINARY_OPERATOR(*)
  88. BOOST_PYTHON_BINARY_OPERATOR(/)
  89. BOOST_PYTHON_BINARY_OPERATOR(%)
  90. BOOST_PYTHON_BINARY_OPERATOR(<<)
  91. BOOST_PYTHON_BINARY_OPERATOR(>>)
  92. BOOST_PYTHON_BINARY_OPERATOR(&)
  93. BOOST_PYTHON_BINARY_OPERATOR(^)
  94. BOOST_PYTHON_BINARY_OPERATOR(|)
  95. # undef BOOST_PYTHON_BINARY_OPERATOR
  96. # define BOOST_PYTHON_INPLACE_OPERATOR(op) \
  97. BOOST_PYTHON_DECL object& operator op(object& l, object const& r); \
  98. template <class R> \
  99. object& operator op(object& l, R const& r) \
  100. { \
  101. return l op object(r); \
  102. }
  103. BOOST_PYTHON_INPLACE_OPERATOR(+=)
  104. BOOST_PYTHON_INPLACE_OPERATOR(-=)
  105. BOOST_PYTHON_INPLACE_OPERATOR(*=)
  106. BOOST_PYTHON_INPLACE_OPERATOR(/=)
  107. BOOST_PYTHON_INPLACE_OPERATOR(%=)
  108. BOOST_PYTHON_INPLACE_OPERATOR(<<=)
  109. BOOST_PYTHON_INPLACE_OPERATOR(>>=)
  110. BOOST_PYTHON_INPLACE_OPERATOR(&=)
  111. BOOST_PYTHON_INPLACE_OPERATOR(^=)
  112. BOOST_PYTHON_INPLACE_OPERATOR(|=)
  113. # undef BOOST_PYTHON_INPLACE_OPERATOR
  114. }}} // namespace boost::python
  115. #include <boost/iterator/detail/config_undef.hpp>
  116. #endif // OBJECT_OPERATORS_DWA2002617_HPP