2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-26 06:42:27 +00:00

Further rationalized conversion registry

[SVN r14441]
This commit is contained in:
Dave Abrahams
2002-07-13 18:44:51 +00:00
parent e431318dc0
commit 093aae1f46
17 changed files with 104 additions and 217 deletions

View File

@@ -14,8 +14,8 @@
# include <boost/python/converter/rvalue_from_python_data.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/from_python.hpp>
# include <boost/python/converter/pointee_from_python.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/converter/registered_pointee.hpp>
# include <boost/python/detail/void_ptr.hpp>
# include <boost/python/back_reference.hpp>
# include <boost/python/detail/referent_storage.hpp>
@@ -229,7 +229,7 @@ inline pointer_cref_arg_from_python<T>::pointer_cref_arg_from_python(PyObject* p
// a U object.
python::detail::write_void_ptr_reference(
m_result.bytes
, p == Py_None ? p : converter::get_lvalue_from_python(p, pointee_from_python<T>::converters)
, p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee<T>::converters)
, (T(*)())0);
}
@@ -252,7 +252,7 @@ inline T pointer_cref_arg_from_python<T>::operator()(PyObject* p) const
template <class T>
inline pointer_arg_from_python<T>::pointer_arg_from_python(PyObject* p)
: arg_lvalue_from_python_base(
p == Py_None ? p : converter::get_lvalue_from_python(p, pointee_from_python<T>::converters))
p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee<T>::converters))
{
}
@@ -266,7 +266,7 @@ inline T pointer_arg_from_python<T>::operator()(PyObject* p) const
//
template <class T>
inline reference_arg_from_python<T>::reference_arg_from_python(PyObject* p)
: arg_lvalue_from_python_base(converter::get_lvalue_from_python(p,from_python<T>::converters))
: arg_lvalue_from_python_base(converter::get_lvalue_from_python(p,registered<T>::converters))
{
}
@@ -281,7 +281,7 @@ inline T reference_arg_from_python<T>::operator()(PyObject*) const
//
template <class T>
inline arg_rvalue_from_python<T>::arg_rvalue_from_python(PyObject* obj)
: m_data(converter::rvalue_from_python_stage1(obj, from_python<T>::converters))
: m_data(converter::rvalue_from_python_stage1(obj, registered<T>::converters))
{
}

View File

@@ -7,8 +7,8 @@
# define ARG_TO_PYTHON_DWA200265_HPP
# include <boost/python/ptr.hpp>
# include <boost/python/converter/to_python_function.hpp>
# include <boost/python/converter/pointee_to_python_function.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/converter/registered_pointee.hpp>
# include <boost/python/converter/arg_to_python_base.hpp>
# include <boost/python/converter/object_manager.hpp>
# include <boost/python/to_python_indirect.hpp>
@@ -180,13 +180,13 @@ namespace detail
template <class T>
inline value_arg_to_python<T>::value_arg_to_python(T const& x)
: arg_to_python_base(&x, to_python_function<T>::value)
: arg_to_python_base(&x, registered<T>::converters.to_python)
{
}
template <class Ptr>
inline pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr x)
: arg_to_python_base(x, pointee_to_python_function<Ptr>::value)
: arg_to_python_base(x, registered_pointee<Ptr>::converters.to_python)
{
detail::reject_raw_object_ptr((Ptr)0);
}

View File

@@ -9,13 +9,13 @@
namespace boost { namespace python { namespace converter {
struct rvalue_from_python_stage1_data;
struct from_python_registration;
struct registration;
namespace detail
{
BOOST_PYTHON_DECL void* convert_rvalue(PyObject*, rvalue_from_python_stage1_data&, void* storage);
BOOST_PYTHON_DECL void* callback_convert_reference(PyObject*, from_python_registration const&);
BOOST_PYTHON_DECL void* callback_convert_pointer(PyObject*, from_python_registration const&);
BOOST_PYTHON_DECL void* callback_convert_reference(PyObject*, registration const&);
BOOST_PYTHON_DECL void* callback_convert_pointer(PyObject*, registration const&);
BOOST_PYTHON_DECL void absorb_result(PyObject*);
}

View File

@@ -12,17 +12,17 @@
namespace boost { namespace python { namespace converter {
struct from_python_registration;
struct registration;
struct rvalue_from_python_chain;
BOOST_PYTHON_DECL void* get_lvalue_from_python(
PyObject* source, from_python_registration const&);
PyObject* source, registration const&);
BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
PyObject* source, from_python_registration const&);
PyObject* source, registration const&);
BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain(
PyObject* source, from_python_registration const&);
PyObject* source, registration const&);
}}} // namespace boost::python::converter

View File

@@ -7,6 +7,7 @@
# define IMPLICIT_DWA2002326_HPP
# include <boost/python/converter/rvalue_from_python_data.hpp>
# include <boost/python/converter/registrations.hpp>
# include <boost/python/converter/registered.hpp>
namespace boost { namespace python { namespace converter {
@@ -15,27 +16,27 @@ struct implicit
{
static void* convertible(PyObject* obj)
{
// Find a converter registration which can produce a Source
// instance from obj. The user has told us that Source can be
// converted to Target, and instantiating construct() below,
// ensures that at compile-time.
// Find a converter chain which can produce a Source instance
// from obj. The user has told us that Source can be converted
// to Target, and instantiating construct() below, ensures
// that at compile-time.
return const_cast<rvalue_from_python_chain*>(
converter::implicit_conversion_chain(obj, from_python<Source>::converters));
converter::implicit_conversion_chain(obj, registered<Source>::converters));
}
static void construct(PyObject* obj, rvalue_from_python_stage1_data* data)
{
// This is the registration we got from the convertible step
rvalue_from_python_chain const* registration
// This is the chain we got from the convertible step
rvalue_from_python_chain const* chain
= static_cast<rvalue_from_python_chain*>(data->convertible);
// Call the convertible function again
rvalue_from_python_data<Source> intermediate_data(registration->convertible(obj));
rvalue_from_python_data<Source> intermediate_data(chain->convertible(obj));
// Use the result to construct the source type if the first
// converter was an rvalue converter.
if (registration->construct != 0)
registration->construct(obj, &intermediate_data.stage1);
if (chain->construct != 0)
chain->construct(obj, &intermediate_data.stage1);
void* storage = ((rvalue_from_python_storage<Target>*)data)->storage.bytes;
# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13012108 // vc7.01 alpha workaround

View File

@@ -1,50 +0,0 @@
// 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 POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP
# define POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP
# 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/registry.hpp>
# include <boost/python/converter/to_python_function_type.hpp>
# include <boost/python/converter/pointer_type_id.hpp>
namespace boost { namespace python { namespace converter {
// pointee_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 pointee_to_python_function_base
{
static to_python_function_t const& value;
};
template <class T>
to_python_function_t const&
pointee_to_python_function_base<T>::value
= converter::registry::get_to_python_function(pointer_type_id<T>());
}
template <class T>
struct pointee_to_python_function
: detail::pointee_to_python_function_base<
typename add_reference<
typename add_cv<T>::type
>::type
>
{
};
}}} // namespace boost::python::converter
#endif // POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP

View File

@@ -3,29 +3,30 @@
// 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 FROM_PYTHON_DWA2002710_HPP
# define FROM_PYTHON_DWA2002710_HPP
#ifndef REGISTERED_DWA2002710_HPP
# define REGISTERED_DWA2002710_HPP
# include <boost/python/type_id.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/registrations.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/cv_traits.hpp>
namespace boost { namespace python { namespace converter {
struct from_python_registration;
struct registration;
namespace detail
{
template <class T>
struct from_python_base
struct registered_base
{
static from_python_registration const& converters;
static registration const& converters;
};
}
template <class T>
struct from_python
: detail::from_python_base<
struct registered
: detail::registered_base<
typename add_reference<
typename add_cv<T>::type
>::type
@@ -36,7 +37,7 @@ struct from_python
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// collapses a few more types to the same static instance
template <class T>
struct from_python<T&> : from_python<T> {};
struct registered<T&> : registered<T> {};
# endif
//
@@ -45,9 +46,9 @@ struct from_python<T&> : from_python<T> {};
namespace detail
{
template <class T>
from_python_registration const& from_python_base<T>::converters
= registry::from_python_converters(type_id<T>());
registration const& registered_base<T>::converters
= registry::lookup(type_id<T>());
}
}}} // namespace boost::python::converter
#endif // FROM_PYTHON_DWA2002710_HPP
#endif // REGISTERED_DWA2002710_HPP

View File

@@ -3,9 +3,9 @@
// 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 POINTEE_FROM_PYTHON_DWA2002710_HPP
# define POINTEE_FROM_PYTHON_DWA2002710_HPP
# include <boost/python/converter/from_python.hpp>
#ifndef REGISTERED_POINTEE_DWA2002710_HPP
# define REGISTERED_POINTEE_DWA2002710_HPP
# include <boost/python/converter/registered.hpp>
# include <boost/python/converter/pointer_type_id.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/type_traits/transform_traits.hpp>
@@ -13,12 +13,12 @@
namespace boost { namespace python { namespace converter {
struct from_python_registration;
struct registration;
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct pointee_from_python
: from_python<
struct registered_pointee
: registered<
typename remove_pointer<
typename remove_cv<
typename remove_reference<T>::type
@@ -31,15 +31,15 @@ struct pointee_from_python
namespace detail
{
template <class T>
struct pointee_from_python_base
struct registered_pointee_base
{
static from_python_registration const& converters;
static registration const& converters;
};
}
template <class T>
struct pointee_from_python
: detail::pointee_from_python_base<
struct registered_pointee
: detail::registered_pointee_base<
typename add_reference<
typename add_cv<T>::type
>::type
@@ -53,11 +53,11 @@ struct pointee_from_python
namespace detail
{
template <class T>
from_python_registration const& pointee_from_python_base<T>::converters
= registry::from_python_converters(pointer_type_id<T>());
registration const& registered_pointee_base<T>::converters
= registry::lookup(pointer_type_id<T>());
}
# endif
}}} // namespace boost::python::converter
#endif // POINTEE_FROM_PYTHON_DWA2002710_HPP
#endif // REGISTERED_POINTEE_DWA2002710_HPP

View File

@@ -6,8 +6,10 @@
#ifndef REGISTRATIONS_DWA2002223_HPP
# define REGISTRATIONS_DWA2002223_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/converter/convertible_function.hpp>
# include <boost/python/converter/constructor_function.hpp>
# include <boost/python/converter/to_python_function_type.hpp>
# include <boost/python/type_id.hpp>
namespace boost { namespace python { namespace converter {
@@ -25,24 +27,41 @@ struct rvalue_from_python_chain
rvalue_from_python_chain* next;
};
struct from_python_registration
struct registration
{
explicit from_python_registration(type_info);
explicit registration(type_info);
const python::type_info target_type;
// The chain of eligible from_python converters when an lvalue is required
lvalue_from_python_chain* lvalue_chain;
// The chain of eligible from_python converters when an rvalue is acceptable
rvalue_from_python_chain* rvalue_chain;
// The unique to_python converter for the associated C++ type.
to_python_function_t to_python;
// The class object associated with this type
PyTypeObject* class_object;
};
//
// implementations
//
inline from_python_registration::from_python_registration(type_info target_type)
inline registration::registration(type_info target_type)
: target_type(target_type)
, lvalue_chain(0)
, rvalue_chain(0)
, to_python(0)
, class_object(0)
{}
inline bool operator<(registration const& lhs, registration const& rhs)
{
return lhs.target_type < rhs.target_type;
}
}}} // namespace boost::python::converter
#endif // REGISTRATIONS_DWA2002223_HPP

View File

@@ -15,15 +15,12 @@
namespace boost { namespace python { namespace converter {
struct from_python_registration;
struct registration;
// This namespace acts as a sort of singleton
namespace registry
{
BOOST_PYTHON_DECL from_python_registration const& from_python_converters(type_info);
BOOST_PYTHON_DECL to_python_function_t const&
get_to_python_function(type_info);
BOOST_PYTHON_DECL registration const& lookup(type_info);
BOOST_PYTHON_DECL void insert(to_python_function_t, type_info);

View File

@@ -8,12 +8,11 @@
# include <boost/python/converter/callback_from_python_base.hpp>
# include <boost/python/converter/rvalue_from_python_data.hpp>
# include <boost/python/converter/from_python.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/converter/registered_pointee.hpp>
# include <boost/python/detail/void_ptr.hpp>
# include <boost/call_traits.hpp>
# include <boost/python/detail/void_return.hpp>
# include <boost/python/converter/from_python.hpp>
# include <boost/python/converter/pointee_from_python.hpp>
namespace boost { namespace python { namespace converter {
@@ -93,7 +92,7 @@ namespace detail
template <class T>
inline return_rvalue_from_python<T>::return_rvalue_from_python()
: m_data(
const_cast<from_python_registration*>(&from_python<T>::converters)
const_cast<registration*>(&registered<T>::converters)
)
{
}
@@ -109,14 +108,14 @@ namespace detail
inline T return_reference_from_python<T>::operator()(PyObject* obj) const
{
return python::detail::void_ptr_to_reference(
callback_convert_reference(obj, from_python<T>::converters)
callback_convert_reference(obj, registered<T>::converters)
, (T(*)())0);
}
template <class T>
inline T return_pointer_from_python<T>::operator()(PyObject* obj) const
{
return T(callback_convert_pointer(obj, pointee_from_python<T>::converters));
return T(callback_convert_pointer(obj, registered_pointee<T>::converters));
}
}

View File

@@ -1,50 +0,0 @@
// 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_DWA2002128_HPP
# define TO_PYTHON_FUNCTION_DWA2002128_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/cv_traits.hpp>
# include <boost/python/type_id.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/to_python_function_type.hpp>
namespace boost { namespace python { namespace converter {
// 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(type_id<T>());
}
template <class T>
struct to_python_function
: detail::to_python_function_base<
typename add_reference<
typename add_cv<T>::type
>::type
>
{
};
}}} // namespace boost::python::converter
#endif // TO_PYTHON_FUNCTION_DWA2002128_HPP

View File

@@ -7,7 +7,7 @@
# define TO_PYTHON_CONVERTER_DWA200221_HPP
# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/to_python_function.hpp>
# include <boost/python/converter/to_python_function_type.hpp>
# include <boost/python/type_id.hpp>
namespace boost { namespace python {

View File

@@ -8,7 +8,7 @@
# include <boost/type_traits/transform_traits.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/to_python_function.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/converter/builtin_converters.hpp>
# include <boost/python/converter/object_manager.hpp>
# include <boost/mpl/select_type.hpp>
@@ -65,13 +65,13 @@ namespace detail
template <class T>
inline bool registry_to_python_value<T>::convertible()
{
return converter::to_python_function<argument_type>::value != 0;
return converter::registered<argument_type>::converters.to_python != 0;
}
template <class T>
inline PyObject* registry_to_python_value<T>::operator()(argument_type x) const
{
return converter::to_python_function<argument_type>::value(&x);
return converter::registered<argument_type>::converters.to_python(&x);
}
template <class T>

View File

@@ -47,7 +47,7 @@ namespace detail
BOOST_PYTHON_DECL void* callback_convert_reference(
PyObject* source
, from_python_registration const& converters)
, registration const& converters)
{
handle<> holder(source);
if (source->ob_refcnt <= 2)
@@ -76,7 +76,7 @@ namespace detail
BOOST_PYTHON_DECL void* callback_convert_pointer(
PyObject* source
, from_python_registration const& converters)
, registration const& converters)
{
if (source == Py_None)
{
@@ -98,9 +98,9 @@ namespace detail
{
handle<> holder(src);
void const* registration = data.convertible;
void const* converters = data.convertible;
data = rvalue_from_python_stage1(
src, *static_cast<from_python_registration const*>(registration));
src, *static_cast<registration const*>(converters));
if (!data.convertible)
{

View File

@@ -16,7 +16,7 @@ namespace boost { namespace python { namespace converter {
BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
PyObject* source
, from_python_registration const& converters)
, registration const& converters)
{
rvalue_from_python_chain const* chain = converters.rvalue_chain;
@@ -37,7 +37,7 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
BOOST_PYTHON_DECL void* get_lvalue_from_python(
PyObject* source
, from_python_registration const& converters)
, registration const& converters)
{
lvalue_from_python_chain const* chain = converters.lvalue_chain;
@@ -76,7 +76,7 @@ namespace
BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain(
PyObject* source
, from_python_registration const& converters)
, registration const& converters)
{
rvalue_from_python_chain const* chain = converters.rvalue_chain;

View File

@@ -17,24 +17,7 @@ namespace boost { namespace python { namespace converter {
namespace // <unnamed>
{
// These are the elements stored in the registry
struct entry
{
entry(type_info target);
from_python_registration m_from_python;
// The unique to_python converter for the associated C++ type.
to_python_function_t m_to_python_converter;
// The class object associated with this type
PyTypeObject* m_class_object;
};
inline bool operator<(entry const& lhs, entry const& rhs)
{
return lhs.m_from_python.target_type < rhs.m_from_python.target_type;
}
typedef registration entry;
typedef std::set<entry> registry_t;
@@ -56,7 +39,7 @@ namespace // <unnamed>
std::cout << "registry: ";
for (registry_t::iterator p = registry.begin(); p != registry.end(); ++p)
{
std::cout << p->m_from_python.target_type << "; ";
std::cout << p->target_type << "; ";
}
std::cout << '\n';
# endif
@@ -74,29 +57,16 @@ namespace // <unnamed>
&*entries().insert(entry(type)).first
);
}
entry::entry(type_info target)
: m_from_python(target)
, m_to_python_converter(0)
, m_class_object(0)
{
}
} // namespace <unnamed>
namespace registry
{
to_python_function_t const& get_to_python_function(
type_info key)
{
return get(key)->m_to_python_converter;
}
void insert(to_python_function_t f, type_info source_t)
{
# ifdef BOOST_PYTHON_TRACE_REGISTRY
std::cout << "inserting to_python " << source_t << "\n";
# endif
to_python_function_t& slot = get(source_t)->m_to_python_converter;
to_python_function_t& slot = get(source_t)->to_python;
assert(slot == 0); // we have a problem otherwise
if (slot != 0)
@@ -116,8 +86,8 @@ namespace registry
entry* found = get(key);
lvalue_from_python_chain *registration = new lvalue_from_python_chain;
registration->convert = convert;
registration->next = found->m_from_python.lvalue_chain;
found->m_from_python.lvalue_chain = registration;
registration->next = found->lvalue_chain;
found->lvalue_chain = registration;
insert(convert, 0, key);
}
@@ -134,8 +104,8 @@ namespace registry
rvalue_from_python_chain *registration = new rvalue_from_python_chain;
registration->convertible = convertible;
registration->construct = construct;
registration->next = found->m_from_python.rvalue_chain;
found->m_from_python.rvalue_chain = registration;
registration->next = found->rvalue_chain;
found->rvalue_chain = registration;
}
// Insert an rvalue from_python converter
@@ -146,7 +116,7 @@ namespace registry
# ifdef BOOST_PYTHON_TRACE_REGISTRY
std::cout << "push_back rvalue from_python " << key << "\n";
# endif
rvalue_from_python_chain** found = &get(key)->m_from_python.rvalue_chain;
rvalue_from_python_chain** found = &get(key)->rvalue_chain;
while (*found != 0)
found = &(*found)->next;
@@ -159,12 +129,12 @@ namespace registry
PyTypeObject*& class_object(type_info key)
{
return get(key)->m_class_object;
return get(key)->class_object;
}
from_python_registration const& from_python_converters(type_info key)
registration const& lookup(type_info key)
{
return get(key)->m_from_python;
return *get(key);
}
} // namespace registry