2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-28 07:22:31 +00:00

Convertibility checks now collect the auxiliary conversion data

BOOST_PYTHON_EXPORT -> BOOST_PYTHON_DECL


[SVN r12191]
This commit is contained in:
Dave Abrahams
2002-01-01 18:52:04 +00:00
parent bfcb36927c
commit b2944a12de
5 changed files with 68 additions and 66 deletions

View File

@@ -5,18 +5,19 @@
// to its suitability for any purpose.
#ifndef REGISTRATION_DWA20011130_HPP
# define REGISTRATION_DWA20011130_HPP
# include <boost/config.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/export.hpp>
# include <boost/python/detail/config.hpp>
# include <utility>
# ifdef BOOST_PYTHON_TRACE
# include <iostream>
# endif
namespace boost { namespace python { namespace converter {
struct BOOST_PYTHON_EXPORT wrapper_base;
struct BOOST_PYTHON_EXPORT unwrapper_base;
struct BOOST_PYTHON_DECL wrapper_base;
struct BOOST_PYTHON_DECL unwrapper_base;
// This class is really sort of a "templated namespace". It manages a
// static data member which refers to the registry entry for T. This
@@ -28,7 +29,7 @@ struct registration
public: // member functions
// Return a converter which can convert the given Python object to
// T, or 0 if no such converter exists
static unwrapper_base* unwrapper(PyObject*);
static std::pair<unwrapper_base*,void*> unwrapper(PyObject*);
// Return a converter which can convert T to a Python object, or 0
// if no such converter exists
@@ -61,7 +62,7 @@ inline registry::entry* registration<T>::entry()
}
template <class T>
unwrapper_base* registration<T>::unwrapper(PyObject* p)
std::pair<unwrapper_base*,void*> registration<T>::unwrapper(PyObject* p)
{
# ifdef BOOST_PYTHON_TRACE
std::cout << "retrieving unwrapper for " << type_id<T>() << std::endl;

View File

@@ -7,20 +7,21 @@
# define REGISTRY_DWA20011127_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/export.hpp>
# include <boost/python/detail/config.hpp>
# include <list>
# include <memory>
# include <utility>
namespace boost { namespace python { namespace converter {
struct BOOST_PYTHON_EXPORT wrapper_base;
struct BOOST_PYTHON_EXPORT unwrapper_base;
struct BOOST_PYTHON_DECL wrapper_base;
struct BOOST_PYTHON_DECL unwrapper_base;
// This namespace acts as a sort of singleton
namespace registry
{
// These are the elements stored in the registry
class BOOST_PYTHON_EXPORT entry
class BOOST_PYTHON_DECL entry
{
public: // member functions
entry();
@@ -30,7 +31,7 @@ namespace registry
// Python object from_python to the C++ type with which this
// converter is associated in the registry, or 0 if no such
// converter exists.
unwrapper_base* unwrapper(PyObject*) const;
std::pair<unwrapper_base*,void*> unwrapper(PyObject*) const;
// Return a converter appropriate for converting a C++ object
// whose type this entry is associated with in the registry to a
@@ -61,12 +62,12 @@ namespace registry
converter::wrapper_base* m_wrapper;
};
BOOST_PYTHON_EXPORT entry* find(type_id_t);
BOOST_PYTHON_DECL entry* find(type_id_t);
BOOST_PYTHON_EXPORT void insert(wrapper_base& x);
BOOST_PYTHON_EXPORT void insert(unwrapper_base& x);
BOOST_PYTHON_EXPORT void remove(wrapper_base& x);
BOOST_PYTHON_EXPORT void remove(unwrapper_base& x);
BOOST_PYTHON_DECL void insert(wrapper_base& x);
BOOST_PYTHON_DECL void insert(unwrapper_base& x);
BOOST_PYTHON_DECL void remove(wrapper_base& x);
BOOST_PYTHON_DECL void remove(unwrapper_base& x);
}
}}} // namespace boost::python::converter

View File

@@ -12,22 +12,28 @@
# include <boost/python/converter/registration.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/converter/unwrapper_select.hpp>
# include <boost/python/export.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/type.hpp>
namespace boost { namespace python { namespace converter {
template <class T> struct unwrapper;
struct BOOST_PYTHON_EXPORT body;
struct BOOST_PYTHON_DECL body;
struct BOOST_PYTHON_EXPORT unwrap_base : handle
struct BOOST_PYTHON_DECL unwrap_base : handle
{
public: // member functions
inline unwrap_base(PyObject* source, body*, handle& prev);
inline unwrap_base(PyObject* source, body*);
inline unwrap_base(PyObject* source, std::pair<unwrapper_base*,void*>, handle& prev);
inline unwrap_base(PyObject* source, std::pair<unwrapper_base*,void*>);
inline PyObject* source() const;
protected:
inline PyObject*& source();
inline void* data() const;
private: // data members
PyObject* m_source;
void* m_data;
};
// These converters will be used by the function wrappers. They don't
@@ -47,15 +53,7 @@ struct unwrap_more_ : unwrap_base
// this constructor is only for the use of unwrap_
unwrap_more_(PyObject* source);
private: // helper functions
// Return the unwrapper which will convert the given Python object
// to T, or 0 if no such converter exists
static unwrapper_base* lookup(PyObject*);
private:
// unspecified storage which may be allocated by the unwrapper to
// do value conversions.
mutable void* m_storage;
typedef typename unwrapper_select<T>::type unwrapper_t;
};
@@ -78,9 +76,9 @@ struct unwrap_more_<PyObject*>
return source();
}
bool convertible(PyObject*) const
void* can_convert(PyObject*) const
{
return true;
return &m_unwrapper;
}
protected: // constructor
@@ -91,7 +89,7 @@ struct unwrap_more_<PyObject*>
{
}
private:
static BOOST_PYTHON_EXPORT unwrapper_base* m_unwrapper;
static BOOST_PYTHON_DECL std::pair<unwrapper_base*,void*> m_unwrapper;
};
template <class T>
@@ -104,42 +102,47 @@ struct unwrap_ : unwrap_more_<T>
//
// implementations
//
inline unwrap_base::unwrap_base(PyObject* source, body* body, handle& prev)
: handle(body, prev)
inline unwrap_base::unwrap_base(
PyObject* source, std::pair<unwrapper_base*,void*> unwrapper, handle& prev)
: handle(unwrapper.first, prev)
, m_source(source)
, m_data(unwrapper.second)
{
}
inline unwrap_base::unwrap_base(PyObject* source, body* body)
: handle(body)
inline unwrap_base::unwrap_base(PyObject* source, std::pair<unwrapper_base*,void*> unwrapper)
: handle(unwrapper.first)
, m_source(source)
, m_data(unwrapper.second)
{
}
inline void* unwrap_base::data() const
{
return m_data;
}
inline PyObject* unwrap_base::source() const
{
return m_source;
}
template <class T>
inline unwrapper_base* unwrap_more_<T>::lookup(PyObject* source)
inline PyObject*& unwrap_base::source()
{
// Find the converters registered for T and get a unwrapper
// appropriate for the source object
return registration<T>::unwrapper(source);
return m_source;
}
template <class T>
unwrap_more_<T>::unwrap_more_(PyObject* source, handle& prev)
: unwrap_base(source, lookup(source), prev)
, m_storage(0)
: unwrap_base(source,
registration<T>::unwrapper(source),
prev)
{
}
template <class T>
unwrap_more_<T>::unwrap_more_(PyObject* source)
: unwrap_base(source, lookup(source))
, m_storage(0)
: unwrap_base(source, registration<T>::unwrapper(source))
{
}
@@ -153,7 +156,7 @@ template <class T>
T unwrap_more_<T>::operator*()
{
return static_cast<unwrapper<T>*>(
get_body())->convert(this->m_source, this->m_storage);
get_body())->convert(this->source(), this->data(), boost::type<T>());
}
template <class T>

View File

@@ -9,6 +9,7 @@
# include <boost/python/converter/unwrapper_base.hpp>
# include <boost/python/converter/unwrap.hpp>
# include <boost/python/converter/body.hpp>
# include <boost/type.hpp>
namespace boost { namespace python { namespace converter {
@@ -21,13 +22,7 @@ struct unwrapper : unwrapper_base
public:
unwrapper();
T do_conversion(unwrap_more_<T> const* handle) const;
private:
virtual T convert(PyObject*, void*&) const = 0;
private: // body required interface implementation
void destroy_handle(handle*) const {}
virtual T convert(PyObject*, void* data, boost::type<T>) const = 0;
};
//
@@ -39,15 +34,6 @@ unwrapper<T>::unwrapper()
{
}
// We could think about making this virtual in an effort to get its
// code generated in the module where the unwrapper is defined, but
// it's not clear that it's a good tradeoff.
template <class T>
T unwrapper<T>::do_conversion(unwrap_more_<T> const* handle) const
{
return convert(handle->source(), handle->m_storage);
}
}}} // namespace boost::python::converter
#endif // UNWRAPPER_DWA2001127_HPP

View File

@@ -8,16 +8,27 @@
# include <boost/python/converter/type_id.hpp>
# include <boost/python/converter/body.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/export.hpp>
# include <boost/python/detail/config.hpp>
namespace boost { namespace python { namespace converter {
struct BOOST_PYTHON_EXPORT unwrapper_base : body
struct BOOST_PYTHON_DECL unwrapper_base : body
{
public:
unwrapper_base(type_id_t); // registers
~unwrapper_base(); // unregisters
virtual bool convertible(PyObject*) const = 0;
// Must return non-null iff the conversion will be successful. Any
// non-null pointer is acceptable, and will be passed on to the
// convert() function, so useful data can be stored there.
virtual void* can_convert(PyObject*) const = 0;
protected:
// this is an arbitrary non-null pointer you can use to indicate success
static void* const non_null;
private: // body required interface implementation
void destroy_handle(handle*) const {}
};
}}} // namespace boost::python::converter