2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-27 19:12:16 +00:00

Last rewrite of the type conversion mechanism, I hope

[SVN r12631]
This commit is contained in:
Dave Abrahams
2002-02-02 14:04:48 +00:00
parent 12988b879e
commit 25c56164b0
29 changed files with 305 additions and 916 deletions

View File

@@ -8,20 +8,41 @@
# include <string>
# include <boost/python/detail/wrap_python.hpp>
namespace boost { namespace python { namespace converter {
namespace boost { namespace python {
template <class T> struct to_python_lookup;
// Provide specializations of to_python_value
template <class T> struct to_python_value;
template <class T>
struct to_python_int
namespace detail
{
bool convertible() const { return true; }
PyObject* operator()(T x) const { return PyInt_FromLong(long(x)); }
};
struct builtin_to_python
{
static bool convertible() { return true; }
};
}
# define BOOST_PYTHON_TO_INT(T) \
template <> struct to_python_lookup<signed T const&> : to_python_int<signed T const&> {}; \
template <> struct to_python_lookup<unsigned T const&> : to_python_int<unsigned T const&> {};
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
template <> struct to_python_value<T&> \
: detail::builtin_to_python \
{ \
PyObject* operator()(T const& x) const \
{ \
return (expr); \
} \
}; \
template <> struct to_python_value<T const&> \
: detail::builtin_to_python \
{ \
PyObject* operator()(T const& x) const \
{ \
return (expr); \
} \
};
# define BOOST_PYTHON_TO_INT(T) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x))
BOOST_PYTHON_TO_INT(char)
BOOST_PYTHON_TO_INT(short)
@@ -29,47 +50,13 @@ BOOST_PYTHON_TO_INT(int)
BOOST_PYTHON_TO_INT(long)
# undef BOOST_TO_PYTHON_INT
template <>
struct to_python_lookup<char const*const&>
{
bool convertible() const { return true; }
PyObject* operator()(char const* x) const { return PyString_FromString(x); }
};
template <>
struct to_python_lookup<std::string const&>
{
bool convertible() const { return true; }
PyObject* operator()(std::string const& x) const
{
return PyString_FromString(x.c_str());
}
};
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, PyString_FromString(x))
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)
template <>
struct to_python_lookup<float const&>
{
bool convertible() const { return true; }
PyObject* operator()(float x) const { return PyFloat_FromDouble(x); }
};
template <>
struct to_python_lookup<double const&>
{
bool convertible() const { return true; }
PyObject* operator()(double x) const { return PyFloat_FromDouble(x); }
};
template <>
struct to_python_lookup<long double const&>
{
bool convertible() const { return true; }
PyObject* operator()(long double x) const
{
return PyFloat_FromDouble(x);
}
};
}}} // namespace boost::python::converter
}} // namespace boost::python::converter
#endif // BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP

View File

@@ -11,7 +11,7 @@
# include <boost/python/converter/from_python_function.hpp>
# include <boost/python/converter/from_python_data.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/converter/registration.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/detail/wrap_python.hpp>
namespace boost { namespace python { namespace converter {
@@ -29,16 +29,21 @@ template <class T> struct from_python_lookup;
struct BOOST_PYTHON_DECL from_python_converter_base : body
{
from_python_converter_base(type_id_t, from_python_check); // registers
~from_python_converter_base(); // unregisters
// 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.
inline void* convertible(PyObject*) const;
// inline type_id_t key() const;
// Given the head of a from_python converter chain, find the
// converter which can convert p, leaving its intermediate data in
// data.
inline static from_python_converter_base const*
find(from_python_converter_base const*chain, PyObject* p, void*& data);
private:
// type_id_t m_key;
from_python_check m_convertible;
from_python_converter_base* m_next;
};
@@ -52,17 +57,24 @@ struct from_python_converter : from_python_converter_base
from_python_converter(from_python_check, conversion_function, from_python_destructor = 0);
T convert(PyObject*, from_python_data&) const;
void destroy(from_python_data&) const;
// Find a converter for converting p to a T.
static from_python_converter<T> const* find(PyObject* p, void*& data);
private: // data members
conversion_function m_convert;
from_python_destructor m_destroy;
// Keeps the chain of converters which convert from PyObject* to T
static from_python_converter_base*const& chain;
};
// -------------------------------------------------------------------------
// Initialized to refer to a common place in the registry.
template <class T>
from_python_converter_base*const&
from_python_converter<T>::chain = registry::from_python_chain(type_id<T>());
//struct from_python_base
//{
//};
// -------------------------------------------------------------------------
// A class which implements from_python with a registry lookup.
template <class T>
@@ -95,12 +107,21 @@ inline void* from_python_converter_base::convertible(PyObject* o) const
return m_convertible(o);
}
# if 0
inline type_id_t from_python_converter_base::key() const
inline from_python_converter_base const*
from_python_converter_base::find(
from_python_converter_base const* chain, PyObject* p, void*& data)
{
return m_key;
for (from_python_converter_base const* q = chain; q != 0 ; q = q->m_next)
{
void* d = q->convertible(p);
if (d != 0)
{
data = d;
return q;
}
}
return 0;
}
# endif
template <class T>
inline from_python_converter<T>::from_python_converter(
@@ -115,6 +136,14 @@ inline from_python_converter<T>::from_python_converter(
}
template <class T>
inline from_python_converter<T> const*
from_python_converter<T>::find(PyObject* p, void*& data)
{
return static_cast<from_python_converter<T> const*>(
from_python_converter_base::find(chain, p, data));
}
template <class T>
inline T from_python_converter<T>::convert(PyObject* src, from_python_data& data) const
{
@@ -133,7 +162,7 @@ inline void from_python_converter<T>::destroy(from_python_data& data) const
template <class T>
inline from_python_lookup<T>::from_python_lookup(PyObject* src)
: m_converter(
registration<T>::get_from_python(
from_python_converter<T>::find(
src, m_intermediate_data.stage1))
{
}

View File

@@ -1,148 +0,0 @@
// Copyright David Abrahams 2001. 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 REGISTRATION_DWA20011130_HPP
# define REGISTRATION_DWA20011130_HPP
# include <boost/python/detail/config.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/mpl/pop_front.hpp>
# include <boost/mpl/for_each.hpp>
# include <boost/mpl/front.hpp>
# include <utility>
# ifdef BOOST_PYTHON_TRACE
# include <iostream>
# endif
namespace boost { namespace python { namespace converter {
template <class T> struct from_python_converter;
template <class T> struct target;
template <class T> struct source;
// This class is really sort of a "templated namespace". It manages a
// static data member which refers to the registry entry for T. This
// reference is acquired once to reduce the burden of multiple
// dictionary lookups at runtime.
template <class T>
struct registration
{
public: // member functions
// Return a converter which can convert the given Python object to
// T, or 0 if no such converter exists. Fill in data with
// the result of the converter's check function
static from_python_converter<T> const* get_from_python(PyObject*, void*& data);
// Return a converter which can convert T to a Python object, or 0
// if no such converter exists
static to_python_function<T>::type get_to_python();
static registry::entry* find_entry();
private: // helper functions
static registry::entry* entry();
static registry::entry* known_entry();
private: // data members
static registry::entry* m_registry_entry;
};
namespace detail
{
// An MPL BinaryMetaFunction class which initializes the
// registration entry for the target type of its 2nd argument.
struct setup_target_registration
{
template <class Ignored, class T> struct apply
{
typedef T type;
static void execute()
{
typedef typename target<T>::type target_t;
registration<target_t>::find_entry();
}
};
};
template <class T>
struct find_return_value_entry
{
static void execute() { registration<T>::find_entry(); }
};
template <>
struct find_return_value_entry<void>
{
static void execute() {}
};
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200
template <>
struct find_return_value_entry<void const>
{
static void execute() {}
};
# endif
}
template <class Sequence>
void acquire_registrations(Sequence signature)
{
typedef typename mpl::pop_front<Sequence>::sequence args;
typedef typename mpl::front<Sequence>::type return_type;
mpl::for_each<args, void, detail::setup_target_registration>::execute();
typedef typename source<return_type>::type return_source_type;
detail::find_return_value_entry<return_source_type>::execute();
}
// because this is static POD data it will be initialized to zero
template <class T>
registry::entry* registration<T>::m_registry_entry;
template <class T>
registry::entry* registration<T>::find_entry()
{
return m_registry_entry = registry::find(type_id<T>());
}
template <class T>
inline registry::entry* registration<T>::entry()
{
if (!m_registry_entry)
find_entry();
return m_registry_entry;
}
template <class T>
inline registry::entry* registration<T>::known_entry()
{
assert(m_registry_entry != 0);
return m_registry_entry;
}
template <class T>
from_python_converter<T> const* registration<T>::get_from_python(PyObject* p, void*& data)
{
return static_cast<from_python_converter<T> const*>(
known_entry()->get_from_python(p, data)
);
}
template <class T>
typename to_python_function<T>::type registration<T>::get_to_python()
{
# ifdef BOOST_PYTHON_TRACE
std::cout << "retrieving wrapper for " << type_id<T>() << std::endl;
# endif
return reinterpret_cast<to_python_function<T>::type>(
known_entry()->get_to_python());
}
}}} // namespace boost::python::converter
#endif // REGISTRATION_DWA20011130_HPP

View File

@@ -5,72 +5,26 @@
// to its suitability for any purpose.
#ifndef REGISTRY_DWA20011127_HPP
# define REGISTRY_DWA20011127_HPP
# include <boost/python/detail/wrap_python.hpp>
# 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 <vector>
# include <memory>
# include <utility>
namespace boost { namespace python { namespace converter {
struct BOOST_PYTHON_DECL from_python_converter_base;
struct BOOST_PYTHON_DECL to_python_converter_base;
// This namespace acts as a sort of singleton
namespace registry
{
// These are the elements stored in the registry
class BOOST_PYTHON_DECL entry
{
public: // member functions
entry();
~entry();
// Return a converter appropriate for converting the given
// Python object from_python to the C++ type with which this
// converter is associated in the registry, or 0 if no such
// converter exists.
from_python_converter_base const* get_from_python(PyObject*, void*& data) const;
// Return a conversion function appropriate for converting a C++
// object whose type this entry is associated with in the
// registry to a Python object, or 0 if no such converter
// exists. This function must be reinterpret_cast to the
// appropriate to_python_function type.
to_python_function_base get_to_python() const;
// Conversion classes use these functions to register
// themselves.
void insert(from_python_converter_base&);
void remove(from_python_converter_base&);
void insert(to_python_converter_base&);
void remove(to_python_converter_base&);
private: // types
typedef std::vector<from_python_converter_base*> from_python_converters;
private: // helper functions
from_python_converters::iterator find(from_python_converter_base const&);
private: // data members
// The collection of from_python converters for the associated
// C++ type.
from_python_converters m_from_python_converters;
// The unique to_python converter for the associated C++ type.
to_python_converter_base* m_to_python_converter;
};
BOOST_PYTHON_DECL entry* find(type_id_t);
BOOST_PYTHON_DECL to_python_value_function const&
to_python_function(undecorated_type_id_t);
BOOST_PYTHON_DECL void insert(to_python_converter_base& x);
BOOST_PYTHON_DECL void insert(from_python_converter_base& x);
BOOST_PYTHON_DECL void remove(to_python_converter_base& x);
BOOST_PYTHON_DECL void remove(from_python_converter_base& x);
BOOST_PYTHON_DECL void insert(to_python_value_function, undecorated_type_id_t);
BOOST_PYTHON_DECL from_python_converter_base*& from_python_chain(type_id_t);
BOOST_PYTHON_DECL PyTypeObject*& class_object(undecorated_type_id_t key);
}
}}} // namespace boost::python::converter

View File

@@ -1,32 +0,0 @@
// Copyright David Abrahams 2001. 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 SOURCE_DWA20011119_HPP
# define SOURCE_DWA20011119_HPP
# include <boost/type_traits/cv_traits.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/mpl/select_type.hpp>
namespace boost { namespace python { namespace converter {
// source --
//
// This type generator (see
// ../../../more/generic_programming.html#type_generator) is used
// to select the argument type to use when converting T to a PyObject*
template <class T>
struct source
{
typedef
typename add_reference<
typename add_const<T>::type
>::type
type;
};
}}} // namespace boost::python::converter
#endif // SOURCE_DWA20011119_HPP

View File

@@ -1,24 +0,0 @@
// Copyright David Abrahams 2001. 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 SOURCE_HOLDER_DWA20011215_HPP
# define SOURCE_HOLDER_DWA20011215_HPP
namespace boost { namespace python { namespace converter {
struct source_holder_base
{
};
template <class T>
struct source_holder : source_holder_base
{
source_holder(T x) : value(x) {}
T value;
};
}}} // namespace boost::python::converter
#endif // SOURCE_HOLDER_DWA20011215_HPP

View File

@@ -1,116 +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_DWA2002127_HPP
# define TO_PYTHON_DWA2002127_HPP
# include <boost/python/detail/config.hpp>
# include <boost/python/converter/body.hpp>
# include <boost/python/converter/registration.hpp>
# include <boost/python/converter/source_holder.hpp>
# include <boost/python/converter/to_python_function.hpp>
# include <boost/python/converter/builtin_to_python_converters.hpp>
namespace boost { namespace python { namespace converter {
template <class T> struct to_python_lookup;
struct BOOST_PYTHON_DECL to_python_converter_base : body
{
to_python_converter_base(type_id_t, to_python_function_base); // registers
~to_python_converter_base(); // unregisters
// inline type_id_t key() const;
inline to_python_function_base converter() const;
private:
// type_id_t m_key;
to_python_function_base m_convert;
};
template <class T>
struct to_python_converter : to_python_converter_base
{
public: // types
typedef typename to_python_function<T>::type converter_t;
public: // member functions
to_python_converter(converter_t);
converter_t converter() const;
private: // data members
converter_t m_convert;
};
// -------------------------------------------------------------------------
//struct to_python_base {};
template <class T>
struct to_python_lookup //: to_python_base
{
public: // member functions
to_python_lookup();
bool convertible() const;
PyObject* operator()(T) const;
private:
typename to_python_function<T>::type m_convert;
};
//
// implementations
//
# if 0
inline type_id_t
to_python_converter_base::key() const
{
return m_key;
}
# endif
inline to_python_function_base
to_python_converter_base::converter() const
{
return m_convert;
}
template <class T>
to_python_converter<T>::to_python_converter(converter_t convert)
: to_python_converter_base(
type_id<T>(), reinterpret_cast<to_python_function_base>(convert))
{
}
template <class T>
inline typename to_python_function<T>::type
to_python_converter<T>::converter() const
{
return reinterpret_cast<converter_t>(
this->to_python_converter_base::converter());
}
template <class T>
inline to_python_lookup<T>::to_python_lookup()
: m_convert(
registration<T>::get_to_python())
{
}
template <class T>
inline bool
to_python_lookup<T>::convertible() const
{
return m_convert != 0;
}
template <class T>
inline PyObject*
to_python_lookup<T>::operator()(T x) const
{
return m_convert ? m_convert(x) : 0;
}
}}} // namespace boost::python::converter
#endif // TO_PYTHON_DWA2002127_HPP

View File

@@ -7,15 +7,24 @@
# define TO_PYTHON_FUNCTION_DWA2002128_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/type_traits/transform_traits.hpp>
namespace boost { namespace python { namespace converter {
typedef PyObject* (*to_python_function_base)(void);
// 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*);
template <class T>
struct to_python_function
// 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
{
typedef PyObject*(*type)(T);
static PyObject* convert(void const* x)
{
return ToPython::convert(*(T const*)x);
}
};
}}} // namespace boost::python::converter

View File

@@ -7,8 +7,12 @@
# define TYPE_ID_DWA20011127_HPP
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/python/detail/msvc_typeinfo.hpp>
# include <boost/type_traits/cv_traits.hpp>
# include <boost/type_traits/composite_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/operators.hpp>
# include <boost/type.hpp>
# include <typeinfo>
# include <iosfwd>
# include <cstring>
@@ -16,13 +20,6 @@
namespace boost { namespace python { namespace converter {
// a portable mechanism for identifying types at runtime across modules.
namespace detail
{
template <class T> class dummy;
}
// for this compiler at least, cross-shared-library type_info
// comparisons don't work, so use typeid(x).name() instead. It's not
// yet clear what the best default strategy is.
@@ -61,7 +58,7 @@ struct type_id_t : totally_ordered<type_id_t>
{
enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 };
type_id_t(undecorated_type_id_t, decoration decoration);
type_id_t(undecorated_type_id_t, decoration = decoration());
bool operator<(type_id_t const& rhs) const;
bool operator==(type_id_t const& rhs) const;
@@ -78,13 +75,19 @@ struct type_id_t : totally_ordered<type_id_t>
};
template <class T>
inline undecorated_type_id_t undecorated_type_id(detail::dummy<T>* = 0)
inline undecorated_type_id_t undecorated_type_id(boost::type<T>* = 0)
{
return undecorated_type_id_t(typeid(T));
return undecorated_type_id_t(
# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600)
typeid(T)
# else // strip the decoration which msvc and Intel mistakenly leave in
python::detail::msvc_typeid<T>()
# endif
);
}
template <class T>
inline type_id_t type_id(detail::dummy<T>* = 0)
inline type_id_t type_id(boost::type<T>* = 0)
{
return type_id_t(
undecorated_type_id<T>()

View File

@@ -1,28 +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 WRAPPER_BASE_DWA2002110_HPP
# define WRAPPER_BASE_DWA2002110_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/converter/body.hpp>
namespace boost { namespace python { namespace converter {
struct source_holder_base;
struct wrap_base;
template <class T> struct wrap_more_;
struct BOOST_PYTHON_DECL wrapper_base : body
{
public:
wrapper_base(type_id_t); // registers
~wrapper_base(); // unregisters
virtual PyObject* do_conversion(wrap_base const&, source_holder_base const&) const = 0;
};
}}} // namespace boost::python::converter
#endif // WRAPPER_BASE_DWA2002110_HPP

View File

@@ -7,7 +7,7 @@
# define COPY_CONST_REFERENCE_DWA2002131_HPP
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/python/to_python.hpp>
# include <boost/python/to_python_value.hpp>
namespace boost { namespace python {

View File

@@ -7,7 +7,7 @@
# define COPY_NON_CONST_REFERENCE_DWA2002131_HPP
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/select_type.hpp>
# include <boost/python/to_python.hpp>
# include <boost/python/to_python_value.hpp>
namespace boost { namespace python {

View File

@@ -20,26 +20,6 @@ namespace boost { namespace python
namespace boost { namespace python { namespace detail {
// for "readable" error messages
template <class T> struct must_use_a_result_handler_to_wrap_functions_returning
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
struct to_python_generator
{
template <class R>
struct apply
{
typedef typename mpl::select_type<
is_reference<R>::value | is_pointer<R>::value
, must_use_a_result_handler_to_wrap_functions_returning<R>
, to_python<R>
>::type type;
};
};
struct caller
{
typedef PyObject* result_type;

View File

@@ -0,0 +1,99 @@
// 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 MSVC_TYPEINFO_DWA200222_HPP
# define MSVC_TYPEINFO_DWA200222_HPP
#include <boost/type.hpp>
#include <typeinfo>
//
// Fix for MSVC's broken typeid() implementation which doesn't strip
// decoration. This fix doesn't handle cv-qualified array types. It
// could probably be done, but I haven't figured it out yet.
//
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 600
namespace boost { namespace python { namespace detail {
typedef std::type_info const& typeinfo;
template<int>struct value_id_accessor;
template<>
struct value_id_accessor<0>
{
template <class T>
static typeinfo get(T*) { return typeid(T); }
};
template<>
struct value_id_accessor<1>
{
template <class T>
static typeinfo get(T const*) { return typeid(T); }
};
template<>
struct value_id_accessor<2>
{
template <class T>
static typeinfo get(T volatile*) { return typeid(T); }
};
template<>
struct value_id_accessor<3>
{
template <class T>
static typeinfo get(T const volatile*) { return typeid(T); }
};
template <bool> struct bool_t{};
template <class T>
inline typeinfo typeid_nonref(boost::type<T>* = 0)
{
BOOST_STATIC_CONSTANT(bool, c = is_const<T>::value);
BOOST_STATIC_CONSTANT(bool, v = is_volatile<T>::value);
return value_id_accessor<(2 * v + c)>::get((T*)0);
}
template <class T>
inline typeinfo typeid_ref(boost::type<T>*, ...)
{
return typeid_nonref<T>();
}
template <class U, class T>
inline typeinfo typeid_ref(boost::type<U>*, T& (*)())
{
return typeid_nonref<T>();
}
template <class T>
inline typeinfo typeid_array(bool_t<false>, boost::type<T>* = 0)
{
typedef T (*x)();
return typeid_ref((boost::type<T>*)0, x(0));
}
template <class T>
inline typeinfo typeid_array(bool_t<true>, boost::type<T>* = 0)
{
return typeid_nonref<T>();
}
template <class T>
inline typeinfo msvc_typeid(boost::type<T>* = 0)
{
typedef bool_t<is_array<T>::value> tag;
return typeid_array(tag(), (boost::type<T>*)0);
}
}}} // namespace boost::python::detail
# endif // BOOST_MSVC
#endif // MSVC_TYPEINFO_DWA200222_HPP

View File

@@ -11,17 +11,10 @@
#ifndef RETURNING_DWA20011201_HPP
# define RETURNING_DWA20011201_HPP
//# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/config.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/python/from_python.hpp>
# include <boost/python/to_python.hpp>
namespace boost { namespace python
{
template <class T> struct to_python;
}} // namespace boost::python
namespace boost { namespace python { namespace detail {

View File

@@ -8,7 +8,6 @@
# include <boost/python/object/function.hpp>
# include <boost/python/object/make_holder.hpp>
# include <boost/python/converter/registration.hpp>
# include <boost/python/detail/caller.hpp>
# include <boost/python/detail/arg_tuple_size.hpp>
# include <boost/mpl/size.hpp>

View File

@@ -6,21 +6,18 @@
#ifndef CLASS_WRAPPER_DWA20011221_HPP
# define CLASS_WRAPPER_DWA20011221_HPP
# include <boost/python/object/class.hpp>
# include <boost/python/object/value_holder.hpp>
# include <boost/python/reference.hpp>
# include <boost/python/converter/to_python.hpp>
# include <memory>
# include <boost/python/to_python_converter.hpp>
namespace boost { namespace python { namespace objects {
template <class T>
struct class_wrapper
: converter::to_python_converter<T const&>
: to_python_converter<T, class_wrapper<T> >
{
class_wrapper(ref const& type_)
: converter::to_python_converter<T const&>(convert)
, m_class_object_keeper(type_)
: m_class_object_keeper(type_)
{
assert(type_->ob_type == (PyTypeObject*)class_metatype().get());
m_class_object = (PyTypeObject*)type_.get();
@@ -31,9 +28,8 @@ struct class_wrapper
// Don't call the type to do the construction, since that
// would require the registration of an __init__ copy
// constructor. Instead, just construct the object in place.
PyObject* raw_result = (PyObject*)PyObject_New(
instance, m_class_object);
PyObject* raw_result = m_class_object->tp_alloc(m_class_object, 0);
if (raw_result == 0)
return 0;
@@ -41,6 +37,8 @@ struct class_wrapper
// exceptions.
ref result(raw_result, ref::allow_null());
((instance*)raw_result)->objects = 0;
// Build a value_holder to contain the object using the copy
// constructor
value_holder<T>* p = new value_holder<T>(raw_result, cref(x));

View File

@@ -1,37 +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_DWA2002128_HPP
# define TO_PYTHON_DWA2002128_HPP
# include <boost/python/converter/to_python.hpp>
# include <boost/python/converter/source.hpp>
namespace boost { namespace python {
template <class T>
struct to_python
: converter::to_python_lookup<typename converter::source<T>::type>
{
};
// specialization for PyObject*
template <>
struct to_python<PyObject*>
{
bool convertible() const { return true; }
PyObject* operator()(PyObject* source) const { return source; }
};
template <>
struct to_python<PyObject*const&>
{
bool convertible() const { return true; }
PyObject* operator()(PyObject* source) const { return source; }
};
}} // namespace boost::python
#endif // TO_PYTHON_DWA2002128_HPP