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