]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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> | |
51 | 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 | |
60 | 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 | |
70 | 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 |