Skip to content

Commit d88e6bf

Browse files
committed
object_core.hpp - use detail/is_xxx to generate template identifiers
object_operators.hpp - use SFINAE to prevent ADL from finding generalized operators inappropriately [SVN r19377]
1 parent a3cdacd commit d88e6bf

2 files changed

Lines changed: 47 additions & 32 deletions

File tree

include/boost/python/object_core.hpp

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
# include <boost/preprocessor/iterate.hpp>
2727
# include <boost/preprocessor/debug/line.hpp>
28+
# include <boost/python/detail/is_xxx.hpp>
2829

2930
namespace boost { namespace python {
3031

@@ -60,31 +61,7 @@ namespace api
6061
//
6162
// is_proxy -- proxy type detection
6263
//
63-
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
64-
template <class T>
65-
struct is_proxy
66-
{
67-
BOOST_STATIC_CONSTANT(bool, value = false);
68-
};
69-
template <class T>
70-
struct is_proxy<proxy<T> >
71-
{
72-
BOOST_STATIC_CONSTANT(bool, value = true);
73-
};
74-
# else
75-
typedef char yes_proxy;
76-
typedef char (&no_proxy)[2];
77-
template <class T>
78-
yes_proxy is_proxy_helper(boost::type<proxy<T> >*);
79-
no_proxy is_proxy_helper(...);
80-
template <class T>
81-
struct is_proxy
82-
{
83-
BOOST_STATIC_CONSTANT(
84-
bool, value = (sizeof(is_proxy_helper((boost::type<T>*)0))
85-
== sizeof(yes_proxy)));
86-
};
87-
# endif
64+
BOOST_PYTHON_IS_XXX_DEF(proxy, boost::python::api::proxy, 1)
8865

8966
template <class T> struct object_initializer;
9067

include/boost/python/object_operators.hpp

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,45 @@
1010

1111
# include <boost/python/object_core.hpp>
1212
# include <boost/python/call.hpp>
13+
# include <boost/iterator/detail/enable_if.hpp>
14+
# include <boost/mpl/bool.hpp>
15+
16+
# include <boost/iterator/detail/config_def.hpp>
1317

1418
namespace boost { namespace python { namespace api {
1519

20+
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
21+
22+
template <class X> char
23+
is_object_operators_helper(object_operators<X> const&);
24+
25+
typedef char (&no_type)[2];
26+
no_type is_object_operators_helper(...);
27+
28+
template <class X> X& make();
29+
30+
template <class L, class R>
31+
struct is_object_operators
32+
{
33+
enum {
34+
value
35+
= (sizeof(api::is_object_operators_helper(api::make<L>()))
36+
+ sizeof(api::is_object_operators_helper(api::make<R>()))
37+
< 4
38+
)
39+
};
40+
typedef mpl::bool_<value> type;
41+
};
42+
43+
template <class L, class R, class T>
44+
struct enable_binary
45+
: boost::iterators::enable_if<is_object_operators<L,R>, T>
46+
{};
47+
# define BOOST_PYTHON_BINARY_RETURN(T) typename enable_binary<L,R,T>::type
48+
# else
49+
# define BOOST_PYTHON_BINARY_RETURN(T) T
50+
# endif
51+
1652
template <class U>
1753
object object_operators<U>::operator()() const
1854
{
@@ -37,12 +73,12 @@ object_operators<U>::operator!() const
3773
return !PyObject_IsTrue(x.ptr());
3874
}
3975

40-
# define BOOST_PYTHON_COMPARE_OP(op, opid) \
41-
template <class L, class R> \
42-
bool operator op(L const& l, R const& r) \
43-
{ \
44-
return PyObject_RichCompareBool( \
45-
object(l).ptr(), object(r).ptr(), opid); \
76+
# define BOOST_PYTHON_COMPARE_OP(op, opid) \
77+
template <class L, class R> \
78+
BOOST_PYTHON_BINARY_RETURN(bool) operator op(L const& l, R const& r) \
79+
{ \
80+
return PyObject_RichCompareBool( \
81+
object(l).ptr(), object(r).ptr(), opid); \
4682
}
4783
BOOST_PYTHON_COMPARE_OP(>, Py_GT)
4884
BOOST_PYTHON_COMPARE_OP(>=, Py_GE)
@@ -55,7 +91,7 @@ BOOST_PYTHON_COMPARE_OP(!=, Py_NE)
5591
# define BOOST_PYTHON_BINARY_OPERATOR(op) \
5692
BOOST_PYTHON_DECL object operator op(object const& l, object const& r); \
5793
template <class L, class R> \
58-
object operator op(L const& l, R const& r) \
94+
BOOST_PYTHON_BINARY_RETURN(object) operator op(L const& l, R const& r) \
5995
{ \
6096
return object(l) op object(r); \
6197
}
@@ -93,4 +129,6 @@ BOOST_PYTHON_INPLACE_OPERATOR(|=)
93129

94130
}}} // namespace boost::python
95131

132+
#include <boost/iterator/detail/config_undef.hpp>
133+
96134
#endif // OBJECT_OPERATORS_DWA2002617_HPP

0 commit comments

Comments
 (0)