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:
@@ -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
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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>()
|
||||
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
99
include/boost/python/detail/msvc_typeinfo.hpp
Normal file
99
include/boost/python/detail/msvc_typeinfo.hpp
Normal 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
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user