Skip to content

Commit f5df393

Browse files
committed
Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
1 parent bf33b54 commit f5df393

Some content is hidden

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

43 files changed

+918
-144
lines changed

include/boost/python/converter/as_to_python_function.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ struct as_to_python_function
3939
// but c'est la vie.
4040
return ToPython::convert(*const_cast<T*>(static_cast<T const*>(x)));
4141
}
42+
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
43+
static PyTypeObject const * get_pytype() { return ToPython::get_pytype(); }
44+
#endif
4245
};
4346

4447
}}} // namespace boost::python::converter

include/boost/python/converter/builtin_converters.hpp

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,18 @@ namespace detail
4747
}
4848

4949
// Use expr to create the PyObject corresponding to x
50-
# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr) \
50+
# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr, pytype)\
5151
template <> struct to_python_value<T&> \
5252
: detail::builtin_to_python \
5353
{ \
5454
inline PyObject* operator()(T const& x) const \
5555
{ \
5656
return (expr); \
5757
} \
58+
inline PyTypeObject const* get_pytype() const \
59+
{ \
60+
return (pytype); \
61+
} \
5862
}; \
5963
template <> struct to_python_value<T const&> \
6064
: detail::builtin_to_python \
@@ -63,6 +67,10 @@ namespace detail
6367
{ \
6468
return (expr); \
6569
} \
70+
inline PyTypeObject const* get_pytype() const \
71+
{ \
72+
return (pytype); \
73+
} \
6674
};
6775

6876
# define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \
@@ -77,25 +85,25 @@ namespace detail
7785
}
7886

7987
// Specialize argument and return value converters for T using expr
80-
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
81-
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr) \
88+
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr, pytype) \
89+
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr, pytype) \
8290
BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
8391

8492
// Specialize converters for signed and unsigned T to Python Int
8593
# define BOOST_PYTHON_TO_INT(T) \
86-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x)) \
94+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x), &PyInt_Type) \
8795
BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
8896
unsigned T \
8997
, static_cast<unsigned long>(x) > static_cast<unsigned long>( \
9098
(std::numeric_limits<long>::max)()) \
9199
? ::PyLong_FromUnsignedLong(x) \
92-
: ::PyInt_FromLong(x))
100+
: ::PyInt_FromLong(x), &PyInt_Type)
93101

94102
// Bool is not signed.
95103
#if PY_VERSION_HEX >= 0x02030000
96-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x))
104+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x), &PyBool_Type)
97105
#else
98-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x))
106+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x), &PyInt_Type)
99107
#endif
100108

101109
// note: handles signed char and unsigned char, but not char (see below)
@@ -108,25 +116,25 @@ BOOST_PYTHON_TO_INT(long)
108116
// using Python's macro instead of Boost's - we don't seem to get the
109117
// config right all the time.
110118
# ifdef HAVE_LONG_LONG
111-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x))
112-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x))
119+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyInt_Type)
120+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyInt_Type)
113121
# endif
114122

115123
# undef BOOST_TO_PYTHON_INT
116124

117-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x))
118-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x))
119-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())))
125+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyString_Type)
126+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyString_Type)
127+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
120128
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
121-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())))
129+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
122130
# endif
123-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x))
124-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x))
125-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x))
126-
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x))
127-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()))
128-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
129-
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
131+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x), &PyFloat_Type)
132+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x), &PyFloat_Type)
133+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x), &PyFloat_Type)
134+
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x), 0)
135+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
136+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
137+
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
130138

131139
# undef BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE
132140
# undef BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE

include/boost/python/converter/pyobject_traits.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ struct pyobject_traits<PyObject>
1818
// All objects are convertible to PyObject
1919
static bool check(PyObject*) { return true; }
2020
static PyObject* checked_downcast(PyObject* x) { return x; }
21+
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
22+
static PyTypeObject const* get_pytype() { return 0; }
23+
#endif
2124
};
2225

2326
//

include/boost/python/converter/pyobject_type.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ BOOST_PYTHON_DECL PyObject* checked_downcast_impl(PyObject*, PyTypeObject*);
1414
// Used as a base class for specializations which need to provide
1515
// Python type checking capability.
1616
template <class Object, PyTypeObject* pytype>
17-
struct pyobject_type
17+
struct pyobject_type
1818
{
1919
static bool check(PyObject* x)
2020
{
@@ -27,6 +27,9 @@ struct pyobject_type
2727
(checked_downcast_impl)(x, pytype)
2828
);
2929
}
30+
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
31+
static PyTypeObject const* get_pytype() { return pytype; }
32+
#endif
3033
};
3134

3235
}}} // namespace boost::python::converter
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// Copyright David Abrahams 2002, Nikolay Mladenov 2007.
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 WRAP_PYTYPE_NM20070606_HPP
6+
# define WRAP_PYTYPE_NM20070606_HPP
7+
8+
# include <boost/python/detail/prefix.hpp>
9+
# include <boost/python/converter/registered.hpp>
10+
# include <boost/python/detail/unwind_type.hpp>
11+
12+
13+
namespace boost { namespace python {
14+
15+
namespace converter
16+
{
17+
template <PyTypeObject const* python_type>
18+
struct wrap_pytype
19+
{
20+
static PyTypeObject const* get_pytype()
21+
{
22+
return python_type;
23+
}
24+
};
25+
26+
typedef PyTypeObject const* (*pytype_function)();
27+
28+
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
29+
30+
31+
32+
namespace detail
33+
{
34+
struct unwind_type_id_helper{
35+
typedef python::type_info result_type;
36+
template <class U>
37+
static result_type execute(U* ){
38+
return python::type_id<U>();
39+
}
40+
};
41+
42+
template <class T>
43+
inline python::type_info unwind_type_id_(boost::type<T>* = 0, mpl::false_ * =0)
44+
{
45+
return boost::python::detail::unwind_type<unwind_type_id_helper, T> ();
46+
}
47+
48+
inline python::type_info unwind_type_id_(boost::type<void>* = 0, mpl::true_* =0)
49+
{
50+
return type_id<void>();
51+
}
52+
53+
template <class T>
54+
inline python::type_info unwind_type_id(boost::type<T>* p= 0)
55+
{
56+
return unwind_type_id_(p, (mpl::bool_<boost::is_void<T>::value >*)0 );
57+
}
58+
}
59+
60+
61+
template <class T>
62+
struct expected_pytype_for_arg
63+
{
64+
static PyTypeObject const *get_pytype()
65+
{
66+
const converter::registration *r=converter::registry::query(
67+
detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
68+
);
69+
return r ? r->expected_from_python_type(): 0;
70+
}
71+
};
72+
73+
74+
template <class T>
75+
struct registered_pytype
76+
{
77+
static PyTypeObject const *get_pytype()
78+
{
79+
const converter::registration *r=converter::registry::query(
80+
detail::unwind_type_id_((boost::type<T>*) 0, (mpl::bool_<boost::is_void<T>::value >*)0 )
81+
);
82+
return r ? r->m_class_object: 0;
83+
}
84+
};
85+
86+
87+
template <class T>
88+
struct registered_pytype_direct
89+
{
90+
static PyTypeObject const* get_pytype()
91+
{
92+
return registered<T>::converters.m_class_object;
93+
}
94+
};
95+
96+
template <class T>
97+
struct expected_from_python_type : expected_pytype_for_arg<T>{};
98+
99+
template <class T>
100+
struct expected_from_python_type_direct
101+
{
102+
static PyTypeObject const* get_pytype()
103+
{
104+
return registered<T>::converters.expected_from_python_type();
105+
}
106+
};
107+
108+
template <class T>
109+
struct to_python_target_type
110+
{
111+
static PyTypeObject const *get_pytype()
112+
{
113+
const converter::registration *r=converter::registry::query(
114+
detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
115+
);
116+
return r ? r->to_python_target_type(): 0;
117+
}
118+
};
119+
120+
template <class T>
121+
struct to_python_target_type_direct
122+
{
123+
static PyTypeObject const *get_pytype()
124+
{
125+
return registered<T>::converters.to_python_target_type();
126+
}
127+
};
128+
#endif
129+
130+
}}} // namespace boost::python
131+
132+
#endif // WRAP_PYTYPE_NM20070606_HPP

include/boost/python/converter/registrations.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ struct rvalue_from_python_chain
2727
{
2828
convertible_function convertible;
2929
constructor_function construct;
30+
PyTypeObject const* (*expected_pytype)();
3031
rvalue_from_python_chain* next;
3132
};
3233

3334
struct BOOST_PYTHON_DECL registration
3435
{
3536
public: // member functions
3637
explicit registration(type_info target, bool is_shared_ptr = false);
38+
~registration();
3739

3840
// Convert the appropriately-typed data to Python
3941
PyObject* to_python(void const volatile*) const;
@@ -42,6 +44,11 @@ struct BOOST_PYTHON_DECL registration
4244
// exception if no class has been registered.
4345
PyTypeObject* get_class_object() const;
4446

47+
// Return common denominator of the python class objects,
48+
// convertable to target. Inspects the m_class_object and the value_chains.
49+
PyTypeObject const* expected_from_python_type() const;
50+
PyTypeObject const* to_python_target_type() const;
51+
4552
public: // data members. So sue me.
4653
const python::type_info target_type;
4754

@@ -56,6 +63,8 @@ struct BOOST_PYTHON_DECL registration
5663

5764
// The unique to_python converter for the associated C++ type.
5865
to_python_function_t m_to_python;
66+
PyTypeObject const* (*m_to_python_target_type)();
67+
5968

6069
// True iff this type is a shared_ptr. Needed for special rvalue
6170
// from_python handling.
@@ -76,6 +85,7 @@ inline registration::registration(type_info target_type, bool is_shared_ptr)
7685
, rvalue_chain(0)
7786
, m_class_object(0)
7887
, m_to_python(0)
88+
, m_to_python_target_type(0)
7989
, is_shared_ptr(is_shared_ptr)
8090
{}
8191

include/boost/python/converter/registry.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,17 @@ namespace registry
2727
// Return a pointer to the corresponding registration, if one exists
2828
BOOST_PYTHON_DECL registration const* query(type_info);
2929

30-
BOOST_PYTHON_DECL void insert(to_python_function_t, type_info);
30+
BOOST_PYTHON_DECL void insert(to_python_function_t, type_info, PyTypeObject const* (*to_python_target_type)() = 0);
3131

3232
// Insert an lvalue from_python converter
33-
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info);
33+
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info, PyTypeObject const* (*expected_pytype)() = 0);
3434

3535
// Insert an rvalue from_python converter
3636
BOOST_PYTHON_DECL void insert(
3737
convertible_function
3838
, constructor_function
3939
, type_info
40+
, PyTypeObject const* (*expected_pytype)() = 0
4041
);
4142

4243
// Insert an rvalue from_python converter at the tail of the
@@ -45,6 +46,7 @@ namespace registry
4546
convertible_function
4647
, constructor_function
4748
, type_info
49+
, PyTypeObject const* (*expected_pytype)() = 0
4850
);
4951
}
5052

include/boost/python/converter/shared_ptr_from_python.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
# include <boost/python/converter/from_python.hpp>
1111
# include <boost/python/converter/rvalue_from_python_data.hpp>
1212
# include <boost/python/converter/registered.hpp>
13+
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
14+
# include <boost/python/converter/pytype_function.hpp>
15+
#endif
1316
# include <boost/shared_ptr.hpp>
1417

1518
namespace boost { namespace python { namespace converter {
@@ -19,7 +22,11 @@ struct shared_ptr_from_python
1922
{
2023
shared_ptr_from_python()
2124
{
22-
converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >());
25+
converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >()
26+
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
27+
, &converter::expected_from_python_type_direct<T>::get_pytype
28+
#endif
29+
);
2330
}
2431

2532
private:

include/boost/python/default_call_policies.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# include <boost/type_traits/is_pointer.hpp>
1414
# include <boost/type_traits/is_reference.hpp>
1515
# include <boost/mpl/or.hpp>
16+
# include <boost/mpl/front.hpp>
1617

1718
namespace boost { namespace python {
1819

@@ -49,6 +50,12 @@ struct default_call_policies
4950

5051
typedef default_result_converter result_converter;
5152
typedef PyObject* argument_package;
53+
54+
template <class Sig>
55+
struct extract_return_type : mpl::front<Sig>
56+
{
57+
};
58+
5259
};
5360

5461
struct default_result_converter

0 commit comments

Comments
 (0)