mirror of
https://github.com/boostorg/python.git
synced 2026-02-02 09:02:15 +00:00
Beginning of callback implementation
[SVN r13135]
This commit is contained in:
104
Jamfile
104
Jamfile
@@ -4,93 +4,21 @@ subproject libs/python ;
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
|
||||
|
||||
{
|
||||
local BOOST_PYTHON_V2_PROPERTIES
|
||||
= $(PYTHON_PROPERTIES)
|
||||
<metrowerks><*><cxxflags>"-inline deferred"
|
||||
<cxx><*><include>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers
|
||||
<define>BOOST_PYTHON_DYNAMIC_LIB
|
||||
<define>BOOST_PYTHON_V2
|
||||
;
|
||||
|
||||
local gcc-release-properties
|
||||
= <optimization>speed <cxxflags>-fomit-frame-pointer
|
||||
<inlining>on <cxxflags>-foptimize-sibling-calls
|
||||
;
|
||||
|
||||
local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) <gcc><release>$(gcc-release-properties)
|
||||
;
|
||||
|
||||
dll bpl
|
||||
:
|
||||
src/converter/from_python.cpp
|
||||
src/converter/registry.cpp
|
||||
src/converter/type_id.cpp
|
||||
src/object/class.cpp
|
||||
src/object/function.cpp
|
||||
src/object/inheritance.cpp
|
||||
src/object/life_support.cpp
|
||||
src/errors.cpp
|
||||
src/module.cpp
|
||||
src/objects.cpp
|
||||
src/converter/builtin_converters.cpp
|
||||
:
|
||||
$(BOOST_PYTHON_V2_PROPERTIES)
|
||||
<define>BOOST_PYTHON_SOURCE
|
||||
;
|
||||
|
||||
# -------- general test -------
|
||||
extension m1 : test/m1.cpp <dll>bpl
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
extension m2 : test/m2.cpp <dll>bpl
|
||||
:
|
||||
: ;
|
||||
|
||||
boost-python-runtest try : test/newtest.py <pyd>m1 <pyd>m2 : : ;
|
||||
|
||||
# ----------- builtin converters -----------
|
||||
|
||||
extension builtin_converters_ext : test/test_builtin_converters.cpp <dll>bpl
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
boost-python-runtest test_builtin_converters : test/test_builtin_converters.py
|
||||
<pyd>builtin_converters_ext
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
# ----------- pointer adoption -----------
|
||||
|
||||
extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp <dll>bpl
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py
|
||||
<pyd>test_pointer_adoption_ext
|
||||
:
|
||||
:
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
unit-test indirect_traits_test
|
||||
: test/indirect_traits_test.cpp : <include>$(BOOST_ROOT) ;
|
||||
unit-test destroy_test
|
||||
: test/destroy_test.cpp : <include>$(BOOST_ROOT) ;
|
||||
unit-test pointer_type_id_test
|
||||
: test/pointer_type_id_test.cpp : <include>$(BOOST_ROOT) ;
|
||||
|
||||
unit-test select_from_python_test
|
||||
: test/select_from_python_test.cpp
|
||||
dll bpl
|
||||
:
|
||||
src/converter/from_python.cpp
|
||||
src/converter/registry.cpp
|
||||
src/converter/type_id.cpp
|
||||
src/converter/registry.cpp # MWerks needs this for some reason
|
||||
: $(PYTHON_PROPERTIES)
|
||||
src/object/class.cpp
|
||||
src/object/function.cpp
|
||||
src/object/inheritance.cpp
|
||||
src/object/life_support.cpp
|
||||
src/errors.cpp
|
||||
src/module.cpp
|
||||
src/objects.cpp
|
||||
src/converter/builtin_converters.cpp
|
||||
src/converter/callback.cpp
|
||||
:
|
||||
$(BOOST_PYTHON_V2_PROPERTIES)
|
||||
<define>BOOST_PYTHON_SOURCE
|
||||
;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# define BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/none.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <string>
|
||||
# include <complex>
|
||||
|
||||
@@ -23,6 +24,11 @@ namespace detail
|
||||
};
|
||||
}
|
||||
|
||||
namespace converter
|
||||
{
|
||||
template <class T> struct callback_to_python;
|
||||
}
|
||||
|
||||
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
|
||||
template <> struct to_python_value<T&> \
|
||||
: detail::builtin_to_python \
|
||||
@@ -39,7 +45,19 @@ namespace detail
|
||||
{ \
|
||||
return (expr); \
|
||||
} \
|
||||
};
|
||||
}; \
|
||||
namespace converter \
|
||||
{ \
|
||||
template <> struct callback_to_python< T > \
|
||||
{ \
|
||||
callback_to_python(T const& x) \
|
||||
: m_held(expr) {} \
|
||||
PyObject* get() const \
|
||||
{ return m_held.get(); } \
|
||||
private: \
|
||||
ref m_held; \
|
||||
}; \
|
||||
}
|
||||
|
||||
|
||||
# define BOOST_PYTHON_TO_INT(T) \
|
||||
@@ -53,12 +71,12 @@ BOOST_PYTHON_TO_INT(int)
|
||||
BOOST_PYTHON_TO_INT(long)
|
||||
# undef BOOST_TO_PYTHON_INT
|
||||
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, x ? PyString_FromString(x) : detail::none())
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, x ? PyString_FromString(x) : boost::python::detail::none())
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x ? x : detail::none())
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, (x ? x : boost::python::detail::none()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, PyComplex_FromDoubles(x.real(), x.imag()))
|
||||
|
||||
45
include/boost/python/converter/callback_to_python_base.hpp
Normal file
45
include/boost/python/converter/callback_to_python_base.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef CALLBACK_TO_PYTHON_BASE_DWA200237_HPP
|
||||
# define CALLBACK_TO_PYTHON_BASE_DWA200237_HPP
|
||||
# include <boost/python/converter/to_python_function_type.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct callback_to_python_holder
|
||||
{
|
||||
callback_to_python_holder(PyObject* obj);
|
||||
inline PyObject* get() const;
|
||||
private:
|
||||
ref m_held;
|
||||
};
|
||||
|
||||
struct BOOST_PYTHON_DECL callback_to_python_base : callback_to_python_holder
|
||||
{
|
||||
callback_to_python_base(void const volatile* source, to_python_function_t);
|
||||
};
|
||||
|
||||
//
|
||||
// implmentation
|
||||
//
|
||||
inline callback_to_python_holder::callback_to_python_holder(PyObject* obj)
|
||||
: m_held(obj)
|
||||
{
|
||||
}
|
||||
|
||||
inline PyObject* callback_to_python_holder::get() const
|
||||
{
|
||||
return m_held.get();
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // CALLBACK_TO_PYTHON_BASE_DWA200237_HPP
|
||||
@@ -8,17 +8,18 @@
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/converter/from_python_stage1_data.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct lvalue_from_python_registration;
|
||||
struct rvalue_from_python_registration;
|
||||
struct rvalue_stage1_data;
|
||||
|
||||
BOOST_PYTHON_DECL void* find(
|
||||
PyObject* source, lvalue_from_python_registration const*);
|
||||
BOOST_PYTHON_DECL void* find(
|
||||
PyObject* source, rvalue_from_python_registration const*, rvalue_stage1_data&);
|
||||
|
||||
BOOST_PYTHON_DECL rvalue_stage1_data find(
|
||||
PyObject* source, rvalue_from_python_registration const*);
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
|
||||
# include <boost/python/converter/find_from_python.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/destroy.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/python/converter/pointer_type_id.hpp>
|
||||
# include <boost/python/converter/from_python_data.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/lvalue_from_python_chain.hpp>
|
||||
# include <boost/python/converter/rvalue_from_python_chain.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
@@ -42,8 +43,6 @@ struct pointer_const_reference_from_python
|
||||
|
||||
private:
|
||||
typename detail::referent_storage<T>::type m_result;
|
||||
|
||||
static lvalue_from_python_registration*& chain;
|
||||
};
|
||||
|
||||
// Used when T == U*
|
||||
@@ -52,8 +51,6 @@ struct pointer_from_python : from_python_base
|
||||
{
|
||||
pointer_from_python(PyObject*);
|
||||
T operator()(PyObject*) const;
|
||||
|
||||
static lvalue_from_python_registration*& chain;
|
||||
};
|
||||
|
||||
// Used when T == U& and (T != V const& or T == W volatile&)
|
||||
@@ -62,8 +59,6 @@ struct reference_from_python : from_python_base
|
||||
{
|
||||
reference_from_python(PyObject*);
|
||||
T operator()(PyObject*) const;
|
||||
|
||||
static lvalue_from_python_registration*& chain;
|
||||
};
|
||||
|
||||
// ------- rvalue converters ---------
|
||||
@@ -79,14 +74,12 @@ class rvalue_from_python
|
||||
|
||||
public:
|
||||
rvalue_from_python(PyObject*);
|
||||
~rvalue_from_python();
|
||||
bool convertible() const;
|
||||
|
||||
result_type operator()(PyObject*);
|
||||
|
||||
private:
|
||||
rvalue_data<result_type> m_data;
|
||||
static rvalue_from_python_registration*& chain;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -191,7 +184,7 @@ inline pointer_const_reference_from_python<T>::pointer_const_reference_from_pyth
|
||||
{
|
||||
detail::write_void_ptr_reference(
|
||||
m_result.bytes
|
||||
, p == Py_None ? p : find(p, chain)
|
||||
, p == Py_None ? p : find(p, lvalue_from_python_chain<T>::value)
|
||||
, (T(*)())0);
|
||||
}
|
||||
|
||||
@@ -208,15 +201,11 @@ inline T pointer_const_reference_from_python<T>::operator()(PyObject* p) const
|
||||
: detail::void_ptr_to_reference(m_result.bytes, (T(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
lvalue_from_python_registration*& pointer_const_reference_from_python<T>::chain
|
||||
= registry::lvalue_converters(pointer_type_id<T>());
|
||||
|
||||
// --------
|
||||
|
||||
template <class T>
|
||||
inline pointer_from_python<T>::pointer_from_python(PyObject* p)
|
||||
: from_python_base(p == Py_None ? p : find(p, chain))
|
||||
: from_python_base(p == Py_None ? p : find(p, lvalue_from_python_chain<T>::value))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -226,15 +215,11 @@ inline T pointer_from_python<T>::operator()(PyObject* p) const
|
||||
return (p == Py_None) ? 0 : T(result());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
lvalue_from_python_registration*& pointer_from_python<T>::chain
|
||||
= registry::lvalue_converters(pointer_type_id<T>());
|
||||
|
||||
// --------
|
||||
|
||||
template <class T>
|
||||
inline reference_from_python<T>::reference_from_python(PyObject* p)
|
||||
: from_python_base(find(p,chain))
|
||||
: from_python_base(find(p,lvalue_from_python_chain<T>::value))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -244,23 +229,12 @@ inline T reference_from_python<T>::operator()(PyObject*) const
|
||||
return detail::void_ptr_to_reference(result(), (T(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
lvalue_from_python_registration*& reference_from_python<T>::chain
|
||||
= registry::lvalue_converters(undecorated_type_id<T>());
|
||||
|
||||
// -------
|
||||
|
||||
template <class T>
|
||||
inline rvalue_from_python<T>::rvalue_from_python(PyObject* obj)
|
||||
: m_data(find(obj, rvalue_from_python_chain<T>::value))
|
||||
{
|
||||
find(obj, chain, m_data.stage1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline rvalue_from_python<T>::~rvalue_from_python()
|
||||
{
|
||||
if (m_data.stage1.convertible == m_data.storage.bytes)
|
||||
python::detail::destroy_reference<result_type>(m_data.storage.bytes);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -279,10 +253,6 @@ rvalue_from_python<T>::operator()(PyObject* p)
|
||||
return detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
rvalue_from_python_registration*& rvalue_from_python<T>::chain
|
||||
= registry::rvalue_converters(undecorated_type_id<T>());
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_DWA2002127_HPP
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/type_traits/ice.hpp>
|
||||
# include <boost/python/detail/destroy.hpp>
|
||||
# include <boost/preprocessor/list/for_each_i.hpp>
|
||||
# include <boost/preprocessor/tuple/to_list.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
@@ -161,7 +162,7 @@ namespace detail
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct rvalue_data
|
||||
struct rvalue_base_data
|
||||
{
|
||||
rvalue_stage1_data stage1;
|
||||
|
||||
@@ -170,6 +171,40 @@ struct rvalue_data
|
||||
>::type storage;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct rvalue_data : rvalue_base_data<T>
|
||||
{
|
||||
rvalue_data(rvalue_stage1_data const&);
|
||||
rvalue_data(void*);
|
||||
~rvalue_data();
|
||||
};
|
||||
|
||||
//
|
||||
// Implementataions
|
||||
//
|
||||
template <class T>
|
||||
inline rvalue_data<T>::rvalue_data(rvalue_stage1_data const& stage1)
|
||||
{
|
||||
this->stage1 = stage1;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline rvalue_data<T>::rvalue_data(void* convertible)
|
||||
{
|
||||
this->stage1.convertible = convertible;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline rvalue_data<T>::~rvalue_data()
|
||||
{
|
||||
if (this->stage1.convertible == this->storage.bytes)
|
||||
python::detail::destroy_reference<
|
||||
add_reference<
|
||||
add_cv<T>::type
|
||||
>::type
|
||||
>(storage.bytes);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
|
||||
67
include/boost/python/converter/lvalue_from_python_chain.hpp
Normal file
67
include/boost/python/converter/lvalue_from_python_chain.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP
|
||||
# define LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP
|
||||
|
||||
# include <boost/python/converter/pointer_type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// Given T == U*cv&, T == U*, or T == U&, lvalue_from_python_chain<T>
|
||||
// declares a "templated global reference" to the lvalue from_python
|
||||
// converter chain for U
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct ptr_or_ptr_ref_lvalue_from_python_chain
|
||||
{
|
||||
static lvalue_from_python_registration*const& value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
lvalue_from_python_registration*const&
|
||||
ptr_or_ptr_ref_lvalue_from_python_chain<T>::value
|
||||
= registry::lvalue_converters(pointer_type_id<T>());
|
||||
|
||||
template <class T>
|
||||
struct ref_lvalue_from_python_chain
|
||||
{
|
||||
static lvalue_from_python_registration*const& value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
lvalue_from_python_registration*const&
|
||||
ref_lvalue_from_python_chain<T>::value
|
||||
= registry::lvalue_converters(undecorated_type_id<T>());
|
||||
|
||||
template <class T>
|
||||
struct select_lvalue_from_python_chain
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, ptr = boost::python::detail::is_reference_to_pointer<T>::value
|
||||
|| is_pointer<T>::value);
|
||||
|
||||
typedef typename add_reference<typename add_cv<T>::type>::type normalized;
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
ptr
|
||||
, ptr_or_ptr_ref_lvalue_from_python_chain<normalized>
|
||||
, ref_lvalue_from_python_chain<normalized>
|
||||
>::type type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct lvalue_from_python_chain
|
||||
: detail::select_lvalue_from_python_chain<T>::type
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP
|
||||
@@ -8,7 +8,7 @@
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/converter/to_python_function.hpp>
|
||||
# include <boost/python/converter/to_python_function_type.hpp>
|
||||
# include <boost/python/converter/from_python_function.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
@@ -22,10 +22,10 @@ namespace registry
|
||||
BOOST_PYTHON_DECL lvalue_from_python_registration*& lvalue_converters(undecorated_type_id_t);
|
||||
BOOST_PYTHON_DECL rvalue_from_python_registration*& rvalue_converters(undecorated_type_id_t);
|
||||
|
||||
BOOST_PYTHON_DECL to_python_value_function const&
|
||||
to_python_function(undecorated_type_id_t);
|
||||
BOOST_PYTHON_DECL to_python_function_t const&
|
||||
get_to_python_function(undecorated_type_id_t);
|
||||
|
||||
BOOST_PYTHON_DECL void insert(to_python_value_function, undecorated_type_id_t);
|
||||
BOOST_PYTHON_DECL void insert(to_python_function_t, undecorated_type_id_t);
|
||||
|
||||
// Insert an lvalue from_python converter
|
||||
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), undecorated_type_id_t);
|
||||
|
||||
@@ -8,23 +8,41 @@
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/to_python_function_type.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// The type of stored function pointers which actually do conversion
|
||||
// by-value. The void* points to the object to be converted, and
|
||||
// type-safety is preserved through runtime registration.
|
||||
typedef PyObject* (*to_python_value_function)(void const*);
|
||||
|
||||
// Given a typesafe to_python conversion function, produces a
|
||||
// to_python_value_function which can be registered in the usual way.
|
||||
template <class T, class ToPython>
|
||||
struct as_to_python_value_function
|
||||
// to_python_function --
|
||||
//
|
||||
// essentially a "templated global reference" which holds the
|
||||
// converter for converting a type to Python by-value. We "normalize"
|
||||
// T by adding "const volatile&" so that fewer global variables and
|
||||
// associated static initializations are generated.
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct to_python_function_base
|
||||
{
|
||||
static to_python_function_t const& value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
to_python_function_t const&
|
||||
to_python_function_base<T>::value
|
||||
= converter::registry::get_to_python_function(undecorated_type_id<T>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct to_python_function
|
||||
: detail::to_python_function_base<
|
||||
typename add_reference<
|
||||
typename add_cv<T>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
static PyObject* convert(void const* x)
|
||||
{
|
||||
return ToPython::convert(*(T const*)x);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
30
include/boost/python/converter/to_python_function_type.hpp
Normal file
30
include/boost/python/converter/to_python_function_type.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
|
||||
# define TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// The type of stored function pointers which actually do conversion
|
||||
// by-value. The void* points to the object to be converted, and
|
||||
// type-safety is preserved through runtime registration.
|
||||
typedef PyObject* (*to_python_function_t)(void const*);
|
||||
|
||||
// Given a typesafe to_python conversion function, produces a
|
||||
// to_python_function_t which can be registered in the usual way.
|
||||
template <class T, class ToPython>
|
||||
struct as_to_python_function
|
||||
{
|
||||
static PyObject* convert(void const* x)
|
||||
{
|
||||
return ToPython::convert(*(T const*)x);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
|
||||
@@ -25,7 +25,7 @@ struct to_python_converter
|
||||
template <class T, class Conversion>
|
||||
to_python_converter<T,Conversion>::to_python_converter()
|
||||
{
|
||||
typedef converter::as_to_python_value_function<
|
||||
typedef converter::as_to_python_function<
|
||||
T, Conversion
|
||||
> normalized;
|
||||
|
||||
|
||||
@@ -23,25 +23,14 @@ struct to_python_value
|
||||
|
||||
static bool convertible();
|
||||
PyObject* operator()(argument_type) const;
|
||||
|
||||
private:
|
||||
// Note that this is a pointer to a function pointer
|
||||
static converter::to_python_value_function const* fconvert;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
converter::to_python_value_function const*
|
||||
to_python_value<T>::fconvert
|
||||
= &converter::registry::to_python_function(converter::undecorated_type_id<T>());
|
||||
|
||||
|
||||
template <class T>
|
||||
bool to_python_value<T>::convertible()
|
||||
{
|
||||
// if this assert fires, our static variable hasn't been set up yet.
|
||||
assert(fconvert != 0);
|
||||
return *fconvert != 0;
|
||||
return converter::to_python_function<argument_type>::value != 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -49,8 +38,7 @@ PyObject* to_python_value<T>::operator()(argument_type x) const
|
||||
{
|
||||
// This might be further optimized on platforms which dynamically
|
||||
// link without specific imports/exports
|
||||
converter::to_python_value_function f = *fconvert;
|
||||
return f(&x);
|
||||
return converter::to_python_function<argument_type>::value(&x);
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace
|
||||
ref intermediate(creator(obj));
|
||||
|
||||
// Get the location in which to construct
|
||||
void* storage = ((rvalue_data<T>*)data)->storage.bytes;
|
||||
void* storage = ((rvalue_base_data<T>*)data)->storage.bytes;
|
||||
new (storage) T(SlotPolicy::extract(intermediate.get()));
|
||||
|
||||
// record successful construction
|
||||
|
||||
@@ -10,21 +10,23 @@
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
BOOST_PYTHON_DECL void* find(
|
||||
BOOST_PYTHON_DECL rvalue_stage1_data find(
|
||||
PyObject* source
|
||||
, rvalue_from_python_registration const* chain
|
||||
, rvalue_stage1_data& data)
|
||||
, rvalue_from_python_registration const* chain)
|
||||
{
|
||||
rvalue_stage1_data data;
|
||||
data.convertible = 0;
|
||||
for (;chain != 0; chain = chain->next)
|
||||
{
|
||||
void* r = chain->convertible(source);
|
||||
if (r != 0)
|
||||
{
|
||||
data.convertible = r;
|
||||
data.construct = chain->construct;
|
||||
return data.convertible = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data.convertible = 0;
|
||||
return data;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* find(
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace // <unnamed>
|
||||
entry();
|
||||
|
||||
// The unique to_python converter for the associated C++ type.
|
||||
to_python_value_function m_to_python_converter;
|
||||
to_python_function_t m_to_python_converter;
|
||||
|
||||
// The collection of from_python converters for the associated
|
||||
// C++ type.
|
||||
@@ -66,15 +66,15 @@ namespace // <unnamed>
|
||||
|
||||
namespace registry
|
||||
{
|
||||
to_python_value_function const& to_python_function(
|
||||
to_python_function_t const& get_to_python_function(
|
||||
undecorated_type_id_t key)
|
||||
{
|
||||
return find(key)->m_to_python_converter;
|
||||
}
|
||||
|
||||
void insert(to_python_value_function f, undecorated_type_id_t source_t)
|
||||
void insert(to_python_function_t f, undecorated_type_id_t source_t)
|
||||
{
|
||||
to_python_value_function& slot = find(source_t)->m_to_python_converter;
|
||||
to_python_function_t& slot = find(source_t)->m_to_python_converter;
|
||||
assert(slot == 0); // we have a problem otherwise
|
||||
if (slot != 0)
|
||||
{
|
||||
|
||||
@@ -112,6 +112,30 @@ void function::add_to_namespace(
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct bind_return
|
||||
{
|
||||
bind_return(PyObject*& result, function const* f, PyObject* args, PyObject* keywords)
|
||||
: m_result(result)
|
||||
, m_f(f)
|
||||
, m_args(args)
|
||||
, m_keywords(keywords)
|
||||
{}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
m_result = m_f->call(m_args, m_keywords);
|
||||
}
|
||||
|
||||
private:
|
||||
PyObject*& m_result;
|
||||
function const* m_f;
|
||||
PyObject* m_args;
|
||||
PyObject* m_keywords;
|
||||
};
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// Stolen from Python's funcobject.c
|
||||
@@ -130,9 +154,11 @@ extern "C"
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
function_call(PyObject *func, PyObject *arg, PyObject *kw)
|
||||
function_call(PyObject *func, PyObject *args, PyObject *kw)
|
||||
{
|
||||
return static_cast<function*>(func)->call(arg, kw);
|
||||
PyObject* result = 0;
|
||||
handle_exception(bind_return(result, static_cast<function*>(func), args, kw));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
75
test/Jamfile
Normal file
75
test/Jamfile
Normal file
@@ -0,0 +1,75 @@
|
||||
subproject libs/python/test ;
|
||||
|
||||
# bring in the rules for python
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
|
||||
local PYTHON_V1_PROPERTIES = $(PYTHON_PROPERTIES) ;
|
||||
local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) ;
|
||||
|
||||
#
|
||||
rule bpl-test ( name ? : files * )
|
||||
{
|
||||
files ?= $(name).py $(name).cpp ;
|
||||
|
||||
local modules ;
|
||||
local py ;
|
||||
for local f in $(files)
|
||||
{
|
||||
if $(f:S) = .py
|
||||
{
|
||||
if $(py)
|
||||
{
|
||||
EXIT too many python drivers specified: "$(py)" "$(f)" ;
|
||||
}
|
||||
py = $(f) ;
|
||||
}
|
||||
}
|
||||
|
||||
name ?= $(py:S=) ;
|
||||
|
||||
for local f in $(files)
|
||||
{
|
||||
if $(f:S) != .py
|
||||
{
|
||||
local m = $(f:S=) ;
|
||||
|
||||
if $(m) = $(py:S=)
|
||||
{
|
||||
m = $(name) ;
|
||||
|
||||
if $(m) = $(py:S=)
|
||||
{
|
||||
m = $(m)_ext ;
|
||||
}
|
||||
}
|
||||
extension $(m) : $(f) <dll>../bpl ;
|
||||
modules += $(m) ;
|
||||
}
|
||||
}
|
||||
|
||||
boost-python-runtest $(name) : $(py) <pyd>$(modules) ;
|
||||
}
|
||||
|
||||
bpl-test try : newtest.py m1.cpp m2.cpp ;
|
||||
bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ;
|
||||
bpl-test test_pointer_adoption ;
|
||||
bpl-test callbacks ;
|
||||
|
||||
# --- unit tests of library components ---
|
||||
unit-test indirect_traits_test
|
||||
: indirect_traits_test.cpp : <include>$(BOOST_ROOT) ;
|
||||
unit-test destroy_test
|
||||
: destroy_test.cpp : <include>$(BOOST_ROOT) ;
|
||||
unit-test pointer_type_id_test
|
||||
: pointer_type_id_test.cpp : <include>$(BOOST_ROOT) ;
|
||||
|
||||
unit-test select_from_python_test
|
||||
: select_from_python_test.cpp
|
||||
../src/converter/type_id.cpp
|
||||
# ../src/converter/registry.cpp # MWerks needs this for some reason
|
||||
|
||||
: <include>$(BOOST_ROOT) <define>BOOST_PYTHON_STATIC_LIB
|
||||
$(PYTHON_V1_PROPERTIES)
|
||||
;
|
||||
|
||||
@@ -25,9 +25,9 @@ struct by_const_reference
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(builtin_converters_ext)
|
||||
BOOST_PYTHON_MODULE_INIT(builtin_converters)
|
||||
{
|
||||
boost::python::module("builtin_converters_ext")
|
||||
boost::python::module("builtin_converters")
|
||||
|
||||
.def("rewrap_value_bool", by_value<bool>::rewrap)
|
||||
.def("rewrap_value_signed_char", by_value<signed char>::rewrap)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
>>> from builtin_converters_ext import *
|
||||
>>> from builtin_converters import *
|
||||
>>> rewrap_value_bool(None)
|
||||
0
|
||||
>>> rewrap_value_bool(0)
|
||||
|
||||
Reference in New Issue
Block a user