Skip to content

Commit c12ffa2

Browse files
committed
beginning of object support
[SVN r14157]
1 parent 0b5937a commit c12ffa2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1893
-177
lines changed

Jamfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ dll bpl
2727
src/converter/builtin_converters.cpp
2828
src/converter/callback.cpp
2929
src/object/iterator.cpp
30+
src/object_protocol.cpp
3031
:
3132
$(BOOST_PYTHON_V2_PROPERTIES)
3233
<define>BOOST_PYTHON_SOURCE
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright David Abrahams 2002. Permission to copy, use,
2+
// modify, sell and distribute this software is granted provided this
3+
// copyright notice appears in all copies. This software is provided
4+
// "as is" without express or implied warranty, and with no claim as
5+
// to its suitability for any purpose.
6+
#ifndef BASE_TYPE_TRAITS_DWA2002614_HPP
7+
# define BASE_TYPE_TRAITS_DWA2002614_HPP
8+
9+
namespace boost { namespace python {
10+
11+
namespace detail
12+
{
13+
struct unspecialized {};
14+
}
15+
16+
// Derive from unspecialized so we can detect whether traits are
17+
// specialized
18+
template <class T> struct base_type_traits
19+
: detail::unspecialized
20+
{};
21+
22+
template <>
23+
struct base_type_traits<PyObject>
24+
{
25+
typedef PyObject type;
26+
};
27+
28+
template <>
29+
struct base_type_traits<PyTypeObject>
30+
{
31+
typedef PyObject type;
32+
};
33+
34+
}} // namespace boost::python
35+
36+
#endif // BASE_TYPE_TRAITS_DWA2002614_HPP

include/boost/python/cast.hpp

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,13 @@
99
# include <boost/python/detail/wrap_python.hpp>
1010
# include <boost/type_traits/same_traits.hpp>
1111
# include <boost/type.hpp>
12+
# include <boost/python/base_type_traits.hpp>
13+
# include <boost/python/detail/convertible.hpp>
1214

1315
namespace boost { namespace python {
1416

15-
template <class T> struct base_type_traits;
16-
17-
template <>
18-
struct base_type_traits<PyObject>
19-
{
20-
typedef PyObject type;
21-
};
22-
23-
template <>
24-
struct base_type_traits<PyTypeObject>
25-
{
26-
typedef PyObject type;
27-
};
28-
2917
namespace detail
3018
{
31-
typedef char* yes_convertible;
32-
typedef int* no_convertible;
33-
34-
typedef char* yes_python_object;
35-
typedef int* no_python_object;
36-
37-
template <class Target>
38-
struct convertible
39-
{
40-
static inline yes_convertible check(Target) { return 0; }
41-
static inline no_convertible check(...) { return 0; }
42-
};
43-
4419
template <class Target>
4520
inline Target* upcast(Target* p, yes_convertible)
4621
{

include/boost/python/converter/arg_to_python.hpp

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010
# include <boost/python/converter/to_python_function.hpp>
1111
# include <boost/python/converter/pointee_to_python_function.hpp>
1212
# include <boost/python/converter/arg_to_python_base.hpp>
13+
# include <boost/python/converter/object_manager.hpp>
1314
# include <boost/python/to_python_indirect.hpp>
15+
# include <boost/type_traits/cv_traits.hpp>
16+
# include <boost/python/detail/convertible.hpp>
17+
# include <boost/python/base_type_traits.hpp>
1418
// Bring in specializations
1519
# include <boost/python/converter/builtin_converters.hpp>
1620

@@ -51,9 +55,27 @@ namespace detail
5155
static PyObject* get_object(Ptr p);
5256
};
5357

58+
// Convert types that manage a Python object to_python
59+
template <class T>
60+
struct object_manager_arg_to_python
61+
{
62+
object_manager_arg_to_python(T const& x) : m_src(x) {}
63+
64+
PyObject* get() const
65+
{
66+
return python::upcast<PyObject>(converter::get_managed_object(m_src));
67+
}
68+
69+
private:
70+
T const& m_src;
71+
};
72+
5473
template <class T>
5574
struct select_arg_to_python
5675
{
76+
BOOST_STATIC_CONSTANT(
77+
bool, manager = is_object_manager<T>::value);
78+
5779
BOOST_STATIC_CONSTANT(
5880
bool, ptr = is_pointer<T>::value);
5981

@@ -67,15 +89,19 @@ namespace detail
6789
typedef typename unwrap_pointer<T>::type unwrapped_ptr;
6890

6991
typedef typename mpl::select_type<
70-
ptr
71-
, pointer_deep_arg_to_python<T>
92+
manager
93+
, object_manager_arg_to_python<T>
7294
, typename mpl::select_type<
73-
ptr_wrapper
74-
, pointer_shallow_arg_to_python<unwrapped_ptr>
95+
ptr
96+
, pointer_deep_arg_to_python<T>
7597
, typename mpl::select_type<
76-
ref_wrapper
77-
, reference_arg_to_python<unwrapped_referent>
78-
, value_arg_to_python<T>
98+
ptr_wrapper
99+
, pointer_shallow_arg_to_python<unwrapped_ptr>
100+
, typename mpl::select_type<
101+
ref_wrapper
102+
, reference_arg_to_python<unwrapped_referent>
103+
, value_arg_to_python<T>
104+
>::type
79105
>::type
80106
>::type
81107
>::type type;
@@ -108,6 +134,39 @@ struct arg_to_python
108134
//
109135
namespace detail
110136
{
137+
// reject_raw_object_ptr -- cause a compile-time error if the user
138+
// should pass a raw Python object pointer
139+
using python::detail::yes_convertible;
140+
using python::detail::no_convertible;
141+
using python::detail::unspecialized;
142+
143+
template <class T> struct cannot_convert_raw_PyObject;
144+
145+
template <class T, class Convertibility>
146+
struct reject_raw_object_helper
147+
{
148+
static void error(Convertibility)
149+
{
150+
cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
151+
}
152+
static void error(...) {}
153+
};
154+
155+
template <class T>
156+
inline void reject_raw_object_ptr(T*)
157+
{
158+
reject_raw_object_helper<T,yes_convertible>::error(
159+
python::detail::convertible<PyObject const volatile*>::check((T*)0));
160+
161+
typedef typename remove_cv<T>::type value_type;
162+
163+
reject_raw_object_helper<T,no_convertible>::error(
164+
python::detail::convertible<unspecialized*>::check(
165+
(base_type_traits<value_type>*)0
166+
));
167+
}
168+
// ---------
169+
111170
template <class T>
112171
inline value_arg_to_python<T>::value_arg_to_python(T const& x)
113172
: arg_to_python_base(&x, to_python_function<T>::value)
@@ -118,6 +177,7 @@ namespace detail
118177
inline pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr x)
119178
: arg_to_python_base(x, pointee_to_python_function<Ptr>::value)
120179
{
180+
detail::reject_raw_object_ptr((Ptr)0);
121181
}
122182

123183
template <class T>
@@ -131,14 +191,16 @@ namespace detail
131191

132192
template <class T>
133193
inline reference_arg_to_python<T>::reference_arg_to_python(T& x)
134-
: handle<>(get_object(x))
194+
: handle<>(reference_arg_to_python<T>::get_object(x))
135195
{
136196
}
137197

138198
template <class Ptr>
139199
inline pointer_shallow_arg_to_python<Ptr>::pointer_shallow_arg_to_python(Ptr x)
140-
: handle<>(get_object(x))
141-
{}
200+
: handle<>(pointer_shallow_arg_to_python<Ptr>::get_object(x))
201+
{
202+
detail::reject_raw_object_ptr((Ptr)0);
203+
}
142204

143205
template <class Ptr>
144206
inline PyObject* pointer_shallow_arg_to_python<Ptr>::get_object(Ptr x)

include/boost/python/converter/arg_to_python_base.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,18 @@ namespace boost { namespace python { namespace converter {
1313

1414
namespace detail
1515
{
16-
struct BOOST_PYTHON_DECL arg_to_python_base : handle<>
16+
struct BOOST_PYTHON_DECL arg_to_python_base
17+
# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140
18+
: handle<>
19+
# endif
1720
{
1821
arg_to_python_base(void const volatile* source, to_python_function_t);
22+
# if defined(BOOST_MSVC) && _MSC_FULL_VER == 13102140
23+
PyObject* get() const { return m_ptr.get(); }
24+
PyObject* release() { return m_ptr.release(); }
25+
private:
26+
handle<> m_ptr;
27+
# endif
1928
};
2029
}
2130

include/boost/python/converter/builtin_converters.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x))
105105
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x))
106106
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x))
107107
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x))
108-
BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(PyObject*, converter::do_arg_to_python(x))
109108
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, PyComplex_FromDoubles(x.real(), x.imag()))
110109
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, PyComplex_FromDoubles(x.real(), x.imag()))
111110
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, PyComplex_FromDoubles(x.real(), x.imag()))

include/boost/python/converter/from_python.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#error obsolete
12
// Copyright David Abrahams 2002. Permission to copy, use,
23
// modify, sell and distribute this software is granted provided this
34
// copyright notice appears in all copies. This software is provided

0 commit comments

Comments
 (0)