mirror of
https://github.com/boostorg/python.git
synced 2026-01-21 05:02:17 +00:00
New conversion methods, builtin converters
---------------------------------------------------------------------- Committing in . Modified Files: boost/python/reference_from_python.hpp boost/python/value_from_python.hpp boost/python/converter/body.hpp boost/python/converter/handle.hpp libs/python/src/converter/builtin_converters.cpp libs/python/test/m1.cpp libs/python/test/m2.cpp Added Files: boost/python/converter/builtin_converters.hpp boost/python/converter/builtin_to_python_converters.hpp boost/python/converter/from_python.hpp boost/python/converter/from_python_data.hpp boost/python/converter/from_python_function.hpp boost/python/converter/to_python.hpp boost/python/converter/to_python_function.hpp boost/python/object/auto_ptr_generator.hpp boost/python/object/pointer_holder.hpp libs/python/src/converter/from_python.cpp libs/python/src/converter/to_python.cpp libs/python/test/test_builtin_converters.cpp libs/python/test/test_builtin_converters.py Removed Files: boost/python/convert.hpp boost/python/converter/unwrap.hpp boost/python/converter/unwrapper.hpp boost/python/converter/wrap.hpp boost/python/converter/wrapper.hpp boost/python/object/class_unwrapper.hpp ---------------------------------------------------------------------- [SVN r12596]
This commit is contained in:
@@ -1,84 +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 CONVERT_DWA20011129_HPP
|
||||
# define CONVERT_DWA20011129_HPP
|
||||
|
||||
# include <boost/python/converter/target.hpp>
|
||||
# include <boost/python/converter/source.hpp>
|
||||
# include <boost/python/converter/wrap.hpp>
|
||||
# include <boost/python/converter/unwrap.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct converter_gen
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef typename converter::source<value_type>::type source_t;
|
||||
typedef converter::wrap_<source_t> wrap_t;
|
||||
typedef converter::wrap_more_<source_t> wrap_more_t;
|
||||
|
||||
typedef typename converter::target<value_type>::type target_t;
|
||||
typedef converter::unwrap_<target_t> unwrap_t;
|
||||
typedef converter::unwrap_more_<target_t> unwrap_more_t;
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct wrap : detail::converter_gen<T>::wrap_t
|
||||
{
|
||||
typedef typename detail::converter_gen<T>::wrap_t base_t;
|
||||
typedef typename detail::converter_gen<T>::source_t source_t;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct wrap_more : detail::converter_gen<T>::wrap_more_t
|
||||
{
|
||||
typedef typename detail::converter_gen<T>::wrap_more_t base_t;
|
||||
typedef typename detail::converter_gen<T>::source_t source_t;
|
||||
wrap_more(converter::handle& prev);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct unwrap : detail::converter_gen<T>::unwrap_t
|
||||
{
|
||||
typedef typename detail::converter_gen<T>::unwrap_t base_t;
|
||||
unwrap(PyObject*);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct unwrap_more : detail::converter_gen<T>::unwrap_more_t
|
||||
{
|
||||
typedef typename detail::converter_gen<T>::unwrap_more_t base_t;
|
||||
unwrap_more(PyObject*, converter::handle& prev);
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <class T>
|
||||
inline wrap_more<T>::wrap_more(converter::handle& prev)
|
||||
: base_t(prev)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unwrap<T>::unwrap(PyObject* source)
|
||||
: base_t(source)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unwrap_more<T>::unwrap_more(PyObject* source, converter::handle& prev)
|
||||
: base_t(source, prev)
|
||||
{
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CONVERT_DWA20011129_HPP
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct BOOST_PYTHON_DECL handle;
|
||||
|
||||
namespace registry
|
||||
{
|
||||
class entry;
|
||||
@@ -23,9 +21,6 @@ struct BOOST_PYTHON_DECL body
|
||||
body(type_id_t key);
|
||||
virtual ~body() {}
|
||||
|
||||
// default implementation is a no-op
|
||||
virtual void destroy_handle(handle*) const;
|
||||
|
||||
type_id_t key() const;
|
||||
|
||||
protected:
|
||||
|
||||
15
include/boost/python/converter/builtin_converters.hpp
Normal file
15
include/boost/python/converter/builtin_converters.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
// 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 BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
# define BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
void initialize_builtin_converters();
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // BUILTIN_CONVERTERS_DWA2002124_HPP
|
||||
@@ -0,0 +1,75 @@
|
||||
// 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 BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP
|
||||
# define BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP
|
||||
# include <string>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
template <class T> struct to_python_lookup;
|
||||
|
||||
template <class T>
|
||||
struct to_python_int
|
||||
{
|
||||
bool convertible() const { return true; }
|
||||
PyObject* operator()(T x) const { return PyInt_FromLong(long(x)); }
|
||||
};
|
||||
|
||||
# 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&> {};
|
||||
|
||||
BOOST_PYTHON_TO_INT(char)
|
||||
BOOST_PYTHON_TO_INT(short)
|
||||
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());
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
#endif // BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP
|
||||
169
include/boost/python/converter/from_python.hpp
Normal file
169
include/boost/python/converter/from_python.hpp
Normal file
@@ -0,0 +1,169 @@
|
||||
// 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 FROM_PYTHON_DWA2002127_HPP
|
||||
# define FROM_PYTHON_DWA2002127_HPP
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/converter/body.hpp>
|
||||
# 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/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// The type of convertibility checking functions
|
||||
typedef void* (*from_python_check)(PyObject*);
|
||||
typedef void (*from_python_destructor)(from_python_data&);
|
||||
|
||||
// forward declaration
|
||||
template <class T> struct from_python_lookup;
|
||||
|
||||
// from_python --
|
||||
// A body class representing a conversion from python to C++.
|
||||
|
||||
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;
|
||||
private:
|
||||
// type_id_t m_key;
|
||||
from_python_check m_convertible;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct from_python_converter : from_python_converter_base
|
||||
{
|
||||
public: // types
|
||||
typedef typename from_python_function<T>::type conversion_function;
|
||||
|
||||
public: // member functions
|
||||
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;
|
||||
|
||||
private: // data members
|
||||
conversion_function m_convert;
|
||||
from_python_destructor m_destroy;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
//struct from_python_base
|
||||
//{
|
||||
//};
|
||||
|
||||
// A class which implements from_python with a registry lookup.
|
||||
template <class T>
|
||||
struct from_python_lookup // : from_python_base
|
||||
{
|
||||
public: // types
|
||||
|
||||
public: // member functions
|
||||
from_python_lookup(PyObject* source);
|
||||
~from_python_lookup();
|
||||
|
||||
bool convertible() const;
|
||||
T operator()(PyObject*);
|
||||
|
||||
public: // functions for use by conversion implementations
|
||||
// Get the converter object
|
||||
from_python_converter<T> const* converter() const;
|
||||
|
||||
private: // data members
|
||||
typedef typename from_python_intermediate_data<T>::type intermediate_t;
|
||||
mutable intermediate_t m_intermediate_data;
|
||||
from_python_converter<T> const* m_converter;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
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
|
||||
{
|
||||
return m_key;
|
||||
}
|
||||
# endif
|
||||
|
||||
template <class T>
|
||||
inline from_python_converter<T>::from_python_converter(
|
||||
from_python_check checker
|
||||
, conversion_function converter
|
||||
, from_python_destructor destructor // = 0
|
||||
)
|
||||
: from_python_converter_base(type_id<T>(), checker)
|
||||
, m_convert(converter)
|
||||
, m_destroy(destructor)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T from_python_converter<T>::convert(PyObject* src, from_python_data& data) const
|
||||
{
|
||||
return this->m_convert(src, data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void from_python_converter<T>::destroy(from_python_data& data) const
|
||||
{
|
||||
if (this->m_destroy)
|
||||
{
|
||||
this->m_destroy(data);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_lookup<T>::from_python_lookup(PyObject* src)
|
||||
: m_converter(
|
||||
registration<T>::get_from_python(
|
||||
src, m_intermediate_data.stage1))
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_lookup<T>::~from_python_lookup()
|
||||
{
|
||||
if (m_converter != 0)
|
||||
m_converter->destroy(m_intermediate_data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool from_python_lookup<T>::convertible() const
|
||||
{
|
||||
return this->m_converter != 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T from_python_lookup<T>::operator()(PyObject* obj)
|
||||
{
|
||||
return this->m_converter->convert(obj, m_intermediate_data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline from_python_converter<T> const*
|
||||
from_python_lookup<T>::converter() const
|
||||
{
|
||||
return this->m_converter;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_DWA2002127_HPP
|
||||
206
include/boost/python/converter/from_python_data.hpp
Normal file
206
include/boost/python/converter/from_python_data.hpp
Normal file
@@ -0,0 +1,206 @@
|
||||
// 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 FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
# define FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/detail/char_array.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
# include <boost/type.hpp>
|
||||
|
||||
// Keep these for the metaprogram which EDG is choking on.
|
||||
# if !defined(__EDG__) || (__EDG_VERSION__ > 245)
|
||||
# include <boost/mpl/type_list.hpp>
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/type_traits/alignment_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# endif
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// A POD which is layout-compatible with the real intermediate data
|
||||
// for all from_python conversions. There may be additional storage if
|
||||
// we are converting a reference type.
|
||||
struct from_python_data
|
||||
{
|
||||
void* stage1;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T> struct referent_alignment;
|
||||
template <class T> struct referent_size;
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class T>
|
||||
struct referent_alignment<T&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, value = alignment_of<T>::value);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct referent_size<T&>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, value = sizeof(T));
|
||||
};
|
||||
|
||||
# else
|
||||
|
||||
template <class U>
|
||||
struct alignment_chars
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_T, n = alignment_of<U>::value);
|
||||
char elements[n + 1];
|
||||
};
|
||||
|
||||
template <class T> struct referent_alignment
|
||||
{
|
||||
template <class U>
|
||||
static alignment_chars<U> helper(U&);
|
||||
|
||||
static T t;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, value = sizeof(helper(t).elements) - 1);
|
||||
};
|
||||
|
||||
|
||||
template <class T> struct referent_size
|
||||
{
|
||||
static T t;
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(t));
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
struct unknown_alignment
|
||||
{
|
||||
void* p;
|
||||
};
|
||||
|
||||
// EDG is too slow to handle this metaprogram :(
|
||||
#if !defined(__EDG__) || (__EDG_VERSION__ > 245)
|
||||
struct alignment_dummy;
|
||||
|
||||
template <std::size_t target_alignment>
|
||||
struct best_alignment_type
|
||||
{
|
||||
template <class T1, class T2>
|
||||
struct apply
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, align1 = alignment_of<T1>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, align2 = alignment_of<T2>::value);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, aligned2 = (
|
||||
(align2 >= target_alignment)
|
||||
& (align2 % target_alignment == 0))
|
||||
);
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, choose_t2 = (
|
||||
aligned2 && (
|
||||
is_same<T1,unknown_alignment>::value
|
||||
| (align2 < alignment_of<T1>::value)
|
||||
| (sizeof(T2) < sizeof(T1)))
|
||||
));
|
||||
|
||||
typedef mpl::select_type<choose_t2, T2, T1>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
typedef mpl::type_list<
|
||||
char,short,int,long,float,double,long double
|
||||
,void*
|
||||
,void(*)()
|
||||
,void (alignment_dummy::*)()
|
||||
, char (alignment_dummy::*)
|
||||
>
|
||||
align_types;
|
||||
#endif // EDG is too slow
|
||||
|
||||
template <class Align, std::size_t size>
|
||||
struct aligned_storage
|
||||
{
|
||||
typedef Align align_t;
|
||||
union
|
||||
{
|
||||
Align align;
|
||||
char bytes[size
|
||||
// this is just a STATIC_ASSERT. For some reason
|
||||
// MSVC was barfing on the boost one.
|
||||
- (is_same<align_t,unknown_alignment>::value ? size : 0)];
|
||||
};
|
||||
};
|
||||
|
||||
template <class Reference>
|
||||
struct referent_storage
|
||||
{
|
||||
// EDG is too slow to handle this metaprogram :(
|
||||
#if !defined(__EDG__) || (__EDG_VERSION__ > 245)
|
||||
typedef mpl::for_each<
|
||||
align_types
|
||||
, unknown_alignment
|
||||
, best_alignment_type<referent_alignment<Reference>::value>
|
||||
> loop;
|
||||
typedef typename loop::state align_t;
|
||||
#else
|
||||
// The Python source makes the assumption that double has
|
||||
// maximal alignment anyway
|
||||
typedef double align_t;
|
||||
#endif
|
||||
|
||||
typedef aligned_storage<align_t,referent_size<Reference>::value> type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct intermediate_data : from_python_data
|
||||
{
|
||||
typename referent_storage<T>::type stage2;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct intermediate_data<void> : from_python_data
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Auxiliary POD storage where the convertible and/or convert functions of a
|
||||
// from_python object may place arbitrary data.
|
||||
//
|
||||
// Always starts with a void*
|
||||
//
|
||||
// For references, we produce additional aligned storage sufficient to
|
||||
// store the referent
|
||||
|
||||
template <class T>
|
||||
struct from_python_intermediate_data
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_reference<T>::value, T, void>::type just_reference_t;
|
||||
|
||||
typedef detail::intermediate_data<just_reference_t> type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void* get_storage(from_python_data& x, boost::type<T>* = 0)
|
||||
{
|
||||
typedef typename from_python_intermediate_data<T>::type layout;
|
||||
return static_cast<layout*>(&x)->stage2.bytes;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP
|
||||
23
include/boost/python/converter/from_python_function.hpp
Normal file
23
include/boost/python/converter/from_python_function.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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 FROM_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
# define FROM_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
struct from_python_data;
|
||||
|
||||
template <class T>
|
||||
struct from_python_function
|
||||
{
|
||||
typedef T (*type)(PyObject*, from_python_data&);
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // FROM_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
@@ -24,6 +24,7 @@ struct BOOST_PYTHON_DECL handle : boost::noncopyable
|
||||
//
|
||||
// Constructors taking a handle links this into a chain of
|
||||
// handles, for more efficient management in function wrappers
|
||||
handle();
|
||||
handle(body* body);
|
||||
handle(body* body, handle& prev);
|
||||
|
||||
@@ -43,6 +44,9 @@ struct BOOST_PYTHON_DECL handle : boost::noncopyable
|
||||
protected: // member functions for derived classes
|
||||
// Get the body we hold
|
||||
inline body* get_body() const;
|
||||
|
||||
inline void set_body(body*);
|
||||
inline void set_prev(handle&);
|
||||
|
||||
// Release all bodies in the chain, in reverse order of
|
||||
// initialization. Only actually called for the head of the chain.
|
||||
@@ -59,6 +63,10 @@ struct BOOST_PYTHON_DECL handle : boost::noncopyable
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
inline handle::handle()
|
||||
: m_next(0)
|
||||
{}
|
||||
|
||||
inline handle::handle(body* body, handle& prev)
|
||||
: m_body(body), m_next(0)
|
||||
{
|
||||
@@ -85,6 +93,16 @@ inline body* handle::get_body() const
|
||||
return m_body;
|
||||
}
|
||||
|
||||
inline void handle::set_body(body* body)
|
||||
{
|
||||
m_body = body;
|
||||
}
|
||||
|
||||
inline void handle::set_prev(handle& prev)
|
||||
{
|
||||
prev.m_next = this;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // HANDLE_DWA20011130_HPP
|
||||
|
||||
116
include/boost/python/converter/to_python.hpp
Normal file
116
include/boost/python/converter/to_python.hpp
Normal file
@@ -0,0 +1,116 @@
|
||||
// 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_converter != 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
|
||||
23
include/boost/python/converter/to_python_function.hpp
Normal file
23
include/boost/python/converter/to_python_function.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
typedef PyObject* (*to_python_function_base)(void);
|
||||
|
||||
template <class T>
|
||||
struct to_python_function
|
||||
{
|
||||
typedef PyObject*(*type)(T);
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
@@ -1,172 +0,0 @@
|
||||
#error obsolete
|
||||
// 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 UNWRAP_BASE_DWA20011130_HPP
|
||||
# define UNWRAP_BASE_DWA20011130_HPP
|
||||
|
||||
# include <boost/python/converter/unwrapper_base.hpp>
|
||||
# include <boost/python/converter/unwrapper.hpp>
|
||||
# include <boost/python/converter/handle.hpp>
|
||||
# include <boost/python/converter/registration.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/unwrapper_select.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_DECL body;
|
||||
|
||||
struct BOOST_PYTHON_DECL unwrap_base : handle
|
||||
{
|
||||
public: // member functions
|
||||
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;
|
||||
|
||||
inline void*& data();
|
||||
|
||||
protected:
|
||||
inline PyObject*& source();
|
||||
|
||||
private: // data members
|
||||
PyObject* m_source;
|
||||
void* m_data;
|
||||
};
|
||||
|
||||
// These converters will be used by the function wrappers. They don't
|
||||
// manage any resources, but are instead linked into a chain which is
|
||||
// managed by an instance of unwrap_ or wrap_.
|
||||
template <class T>
|
||||
struct unwrap_more_ : unwrap_base
|
||||
{
|
||||
public: // member functions
|
||||
// Construction
|
||||
unwrap_more_(PyObject* source, handle& prev);
|
||||
|
||||
// invoke the conversion or throw an exception if unsuccessful
|
||||
T operator*();
|
||||
|
||||
protected: // constructor
|
||||
// this constructor is only for the use of unwrap_
|
||||
unwrap_more_(PyObject* source);
|
||||
|
||||
private:
|
||||
typedef typename unwrapper_select<T>::type unwrapper_t;
|
||||
};
|
||||
|
||||
// specialization for PyObject*
|
||||
template <>
|
||||
struct unwrap_more_<PyObject*>
|
||||
: unwrap_base
|
||||
{
|
||||
public: // member functions
|
||||
// Construction
|
||||
unwrap_more_(PyObject* source, handle& prev)
|
||||
: unwrap_base(source, m_unwrapper, prev)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// invoke the conversion or throw an exception if unsuccessful
|
||||
PyObject* operator*()
|
||||
{
|
||||
return source();
|
||||
}
|
||||
|
||||
void* can_convert(PyObject*) const
|
||||
{
|
||||
return &m_unwrapper;
|
||||
}
|
||||
|
||||
protected: // constructor
|
||||
// this constructor is only for the use of unwrap_
|
||||
unwrap_more_(PyObject* source)
|
||||
: unwrap_base(source, m_unwrapper)
|
||||
|
||||
{
|
||||
}
|
||||
private:
|
||||
static BOOST_PYTHON_DECL std::pair<unwrapper_base*,void*>& m_unwrapper;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct unwrap_ : unwrap_more_<T>
|
||||
{
|
||||
unwrap_(PyObject* source);
|
||||
~unwrap_();
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
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, std::pair<unwrapper_base*,void*> unwrapper)
|
||||
: handle(unwrapper.first)
|
||||
, m_source(source)
|
||||
, m_data(unwrapper.second)
|
||||
{
|
||||
}
|
||||
|
||||
inline void*& unwrap_base::data()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
inline PyObject* unwrap_base::source() const
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
inline PyObject*& unwrap_base::source()
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
unwrap_more_<T>::unwrap_more_(PyObject* source, handle& prev)
|
||||
: unwrap_base(source,
|
||||
registration<T>::unwrapper(source),
|
||||
prev)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
unwrap_more_<T>::unwrap_more_(PyObject* source)
|
||||
: unwrap_base(source, registration<T>::unwrapper(source))
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unwrap_<T>::unwrap_(PyObject* source)
|
||||
: unwrap_more_<T>(source)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T unwrap_more_<T>::operator*()
|
||||
{
|
||||
return static_cast<unwrapper<T>*>(
|
||||
get_body())->convert(this->source(), this->data(), boost::type<T>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
unwrap_<T>::~unwrap_()
|
||||
{
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // UNWRAP_BASE_DWA20011130_HPP
|
||||
@@ -1,40 +0,0 @@
|
||||
#error obsolete
|
||||
// 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 UNWRAPPER_DWA2001127_HPP
|
||||
# define UNWRAPPER_DWA2001127_HPP
|
||||
|
||||
# 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 {
|
||||
|
||||
template <class T> struct unwrap_more_;
|
||||
|
||||
// Abstract base for all unwrappers of Ts
|
||||
template <class T>
|
||||
struct unwrapper : unwrapper_base
|
||||
{
|
||||
public:
|
||||
unwrapper();
|
||||
|
||||
virtual T convert(PyObject*, void*& data, boost::type<T>) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <class T>
|
||||
unwrapper<T>::unwrapper()
|
||||
: unwrapper_base(type_id<T>())
|
||||
{
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // UNWRAPPER_DWA2001127_HPP
|
||||
@@ -1,167 +0,0 @@
|
||||
#error obsolete
|
||||
// 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 WRAP_DWA2001127_HPP
|
||||
# define WRAP_DWA2001127_HPP
|
||||
# include <boost/python/converter/registration.hpp>
|
||||
# include <boost/python/converter/handle.hpp>
|
||||
# include <boost/python/converter/body.hpp>
|
||||
# include <boost/python/converter/wrapper.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/converter/source_holder.hpp>
|
||||
# include <boost/python/converter/wrapper_base.hpp>
|
||||
# include <cassert>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
extern BOOST_PYTHON_DECL body& identity_wrapper;
|
||||
|
||||
template <class T> struct wrapper;
|
||||
|
||||
struct wrap_base : handle
|
||||
{
|
||||
public: // member functions
|
||||
wrap_base(body*, handle& prev);
|
||||
wrap_base(body*);
|
||||
PyObject* release();
|
||||
|
||||
public: // accessor, really only for wrappers
|
||||
PyObject*& target() const;
|
||||
|
||||
protected:
|
||||
void hold_result(PyObject*) const;
|
||||
|
||||
private:
|
||||
mutable PyObject* m_target;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct wrap_more_ : wrap_base
|
||||
{
|
||||
protected:
|
||||
typedef T source_t;
|
||||
|
||||
public: // member functions
|
||||
wrap_more_(handle& prev);
|
||||
|
||||
PyObject* operator()(source_t) const;
|
||||
|
||||
protected: // constructor for wrap_<T>, below
|
||||
wrap_more_();
|
||||
|
||||
private: // helper functions
|
||||
static wrapper_base* lookup();
|
||||
|
||||
private:
|
||||
friend class wrapper<T>;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct wrap_ : wrap_more_<T>
|
||||
{
|
||||
typedef typename wrap_more_<T>::source_t source_t;
|
||||
public: // member functions
|
||||
wrap_();
|
||||
~wrap_();
|
||||
};
|
||||
|
||||
|
||||
// Specialization for PyObject*
|
||||
template <>
|
||||
struct wrap_more_<PyObject*> : wrap_base
|
||||
{
|
||||
protected:
|
||||
typedef PyObject* source_t;
|
||||
|
||||
public: // member functions
|
||||
wrap_more_(handle& prev)
|
||||
: wrap_base(&identity_wrapper, prev) {}
|
||||
|
||||
PyObject* operator()(source_t x) const { return x; }
|
||||
|
||||
protected: // constructor for wrap_<T>, below
|
||||
wrap_more_()
|
||||
: wrap_base(&identity_wrapper) {}
|
||||
private:
|
||||
friend class wrapper<PyObject*>;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
inline wrap_base::wrap_base(body* body, handle& prev)
|
||||
: handle(body, prev)
|
||||
, m_target(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline wrap_base::wrap_base(body* body)
|
||||
: handle(body),
|
||||
m_target(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline PyObject*& wrap_base::target() const
|
||||
{
|
||||
return m_target;
|
||||
}
|
||||
|
||||
inline void wrap_base::hold_result(PyObject* p) const
|
||||
{
|
||||
assert(m_target == 0);
|
||||
m_target = p;
|
||||
}
|
||||
|
||||
inline PyObject* wrap_base::release()
|
||||
{
|
||||
PyObject* result = m_target;
|
||||
m_target = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline wrapper_base* wrap_more_<T>::lookup()
|
||||
{
|
||||
// Find the converters registered for T and get a wrapper
|
||||
// appropriate for the source object
|
||||
return registration<T>::wrapper();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline wrap_more_<T>::wrap_more_(handle& prev)
|
||||
: wrap_base(lookup(), prev)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* wrap_more_<T>::operator()(source_t x) const
|
||||
{
|
||||
return static_cast<wrapper<T>*>(
|
||||
this->get_body())->do_conversion(*this, source_holder<T>(x));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
wrap_more_<T>::wrap_more_()
|
||||
: wrap_base(lookup())
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
wrap_<T>::wrap_()
|
||||
: wrap_more_<T>()
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
wrap_<T>::~wrap_()
|
||||
{
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // WRAP_DWA2001127_HPP
|
||||
@@ -1,57 +0,0 @@
|
||||
#error obsolete
|
||||
// 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 WRAPPER_DWA2001127_HPP
|
||||
# define WRAPPER_DWA2001127_HPP
|
||||
# include <boost/python/converter/wrapper_base.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/wrap.hpp>
|
||||
# include <boost/python/converter/source_holder.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
extern BOOST_PYTHON_DECL body& identity_wrapper;
|
||||
|
||||
template <class T>
|
||||
struct wrapper : wrapper_base
|
||||
{
|
||||
public:
|
||||
wrapper();
|
||||
|
||||
PyObject* do_conversion(wrap_base const&, source_holder_base const&) const;
|
||||
|
||||
// This does the actual conversion
|
||||
virtual PyObject* convert(T source) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
|
||||
template <class T>
|
||||
wrapper<T>::wrapper()
|
||||
: wrapper_base(type_id<T>())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
PyObject* wrapper<T>::do_conversion(wrap_base const& handle_, source_holder_base const& data_) const
|
||||
{
|
||||
// Casting pointers instead of references suppresses a CWPro7 bug.
|
||||
wrap_more_<T> const& handle = *static_cast<wrap_more_<T> const*>(&handle_);
|
||||
source_holder<T> const& data = *static_cast<source_holder<T> const*>(&data_);
|
||||
if (handle.target() == 0)
|
||||
{
|
||||
handle.hold_result(convert(data.value));
|
||||
}
|
||||
return handle.target();
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // WRAPPER_DWA2001127_HPP
|
||||
23
include/boost/python/object/auto_ptr_generator.hpp
Normal file
23
include/boost/python/object/auto_ptr_generator.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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 AUTO_PTR_GENERATOR_DWA2002123_HPP
|
||||
# define AUTO_PTR_GENERATOR_DWA2002123_HPP
|
||||
# include <memory>
|
||||
|
||||
namespace boost { namespace python { namespace object {
|
||||
|
||||
struct auto_ptr_generator
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef std::auto_ptr<T> type;
|
||||
};
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
#endif // AUTO_PTR_GENERATOR_DWA2002123_HPP
|
||||
@@ -1,40 +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 CLASS_UNWRAPPER_DWA20011221_HPP
|
||||
# define CLASS_UNWRAPPER_DWA20011221_HPP
|
||||
|
||||
# include <boost/python/object/class.hpp>
|
||||
# include <boost/python/converter/unwrapper.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
template <class T>
|
||||
struct class_unwrapper
|
||||
{
|
||||
private:
|
||||
template <class Target>
|
||||
struct reference_unwrapper : converter::unwrapper<Target>
|
||||
{
|
||||
void* can_convert(PyObject* p) const
|
||||
{
|
||||
return find_instance<T>(p);
|
||||
}
|
||||
|
||||
Target convert(PyObject* p, void* data, ) const
|
||||
{
|
||||
return *find_instance<T>(p)->target();
|
||||
}
|
||||
};
|
||||
|
||||
reference_unwrapper<T&> m_reference;
|
||||
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
reference_unwrapper<T const&> m_const_reference;
|
||||
# endif
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // CLASS_UNWRAPPER_DWA20011221_HPP
|
||||
201
include/boost/python/object/pointer_holder.hpp
Normal file
201
include/boost/python/object/pointer_holder.hpp
Normal file
@@ -0,0 +1,201 @@
|
||||
// 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 POINTER_HOLDER_DWA20011215_HPP
|
||||
# define POINTER_HOLDER_DWA20011215_HPP
|
||||
|
||||
# include <boost/python/object/class.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/object/inheritance.hpp>
|
||||
# include <boost/python/detail/eval.hpp>
|
||||
# include <boost/ref.hpp>
|
||||
# include <boost/type.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
template <class Pointer, class Value>
|
||||
struct pointer_holder : instance_holder
|
||||
{
|
||||
pointer_holder(Pointer);
|
||||
|
||||
// Forward construction to the held object
|
||||
pointer_holder(PyObject*)
|
||||
: m_p(new Value) {}
|
||||
|
||||
|
||||
template <class A1>
|
||||
pointer_holder(PyObject*, A1 a1)
|
||||
: m_p(new Value(
|
||||
(unwrap_reference<A1>::type&)(a1)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2)
|
||||
: m_p(new Value(
|
||||
(unwrap_reference<A1>::type&)(a1)
|
||||
, (unwrap_reference<A2>::type&)(a2)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3)
|
||||
: m_p(new Value(
|
||||
(unwrap_reference<A1>::type&)(a1)
|
||||
, (unwrap_reference<A2>::type&)(a2)
|
||||
, (unwrap_reference<A3>::type&)(a3)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4)
|
||||
: m_p(new Value(
|
||||
(unwrap_reference<A1>::type&)(a1)
|
||||
, (unwrap_reference<A2>::type&)(a2)
|
||||
, (unwrap_reference<A3>::type&)(a3)
|
||||
, (unwrap_reference<A4>::type&)(a4)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
|
||||
: m_p(new Value(
|
||||
(unwrap_reference<A1>::type&)(a1)
|
||||
, (unwrap_reference<A2>::type&)(a2)
|
||||
, (unwrap_reference<A3>::type&)(a3)
|
||||
, (unwrap_reference<A4>::type&)(a4)
|
||||
, (unwrap_reference<A5>::type&)(a5)
|
||||
)) {}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
|
||||
: m_p(new Value(
|
||||
(unwrap_reference<A1>::type&)(a1)
|
||||
, (unwrap_reference<A2>::type&)(a2)
|
||||
, (unwrap_reference<A3>::type&)(a3)
|
||||
, (unwrap_reference<A4>::type&)(a4)
|
||||
, (unwrap_reference<A5>::type&)(a5)
|
||||
, (unwrap_reference<A6>::type&)(a6)
|
||||
)) {}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
|
||||
: m_p(new Value(
|
||||
(unwrap_reference<A1>::type&)(a1)
|
||||
, (unwrap_reference<A2>::type&)(a2)
|
||||
, (unwrap_reference<A3>::type&)(a3)
|
||||
, (unwrap_reference<A4>::type&)(a4)
|
||||
, (unwrap_reference<A5>::type&)(a5)
|
||||
, (unwrap_reference<A6>::type&)(a6)
|
||||
, (unwrap_reference<A7>::type&)(a7)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
|
||||
: m_p(new Value(
|
||||
(unwrap_reference<A1>::type&)(a1)
|
||||
, (unwrap_reference<A2>::type&)(a2)
|
||||
, (unwrap_reference<A3>::type&)(a3)
|
||||
, (unwrap_reference<A4>::type&)(a4)
|
||||
, (unwrap_reference<A5>::type&)(a5)
|
||||
, (unwrap_reference<A6>::type&)(a6)
|
||||
, (unwrap_reference<A7>::type&)(a7)
|
||||
, (unwrap_reference<A8>::type&)(a8)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
|
||||
: m_p(new Value(
|
||||
(unwrap_reference<A1>::type&)(a1)
|
||||
, (unwrap_reference<A2>::type&)(a2)
|
||||
, (unwrap_reference<A3>::type&)(a3)
|
||||
, (unwrap_reference<A4>::type&)(a4)
|
||||
, (unwrap_reference<A5>::type&)(a5)
|
||||
, (unwrap_reference<A6>::type&)(a6)
|
||||
, (unwrap_reference<A7>::type&)(a7)
|
||||
, (unwrap_reference<A8>::type&)(a8)
|
||||
, (unwrap_reference<A9>::type&)(a9)
|
||||
))
|
||||
{}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10)
|
||||
: m_p(new Value(
|
||||
(unwrap_reference<A1>::type&)(a1)
|
||||
, (unwrap_reference<A2>::type&)(a2)
|
||||
, (unwrap_reference<A3>::type&)(a3)
|
||||
, (unwrap_reference<A4>::type&)(a4)
|
||||
, (unwrap_reference<A5>::type&)(a5)
|
||||
, (unwrap_reference<A6>::type&)(a6)
|
||||
, (unwrap_reference<A7>::type&)(a7)
|
||||
, (unwrap_reference<A8>::type&)(a8)
|
||||
, (unwrap_reference<A9>::type&)(a9)
|
||||
, (unwrap_reference<A10>::type&)(a10)
|
||||
))
|
||||
{}
|
||||
|
||||
private: // required holder implementation
|
||||
void* holds(converter::type_id_t);
|
||||
|
||||
private: // data members
|
||||
Pointer m_p;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
// back to namespace boost for this forward declaration
|
||||
namespace boost
|
||||
{
|
||||
template <class T> class shared_ptr;
|
||||
}
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
struct shared_ptr_generator
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef boost::shared_ptr<T> type;
|
||||
};
|
||||
};
|
||||
|
||||
// A generator metafunction which can be passed to make_holder
|
||||
// PointerGenerator should be another generator metafunction which
|
||||
// makes the appropriate (smart) pointer type to hold the argument to
|
||||
// pointer_holder_generator.
|
||||
template <class PointerGenerator>
|
||||
struct pointer_holder_generator
|
||||
{
|
||||
template <class Held>
|
||||
struct apply
|
||||
{
|
||||
typedef typename detail::eval<PointerGenerator,Held>::type pointer;
|
||||
typedef pointer_holder<pointer, Held> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class Pointer, class Value>
|
||||
pointer_holder<Pointer,Value>::pointer_holder(Pointer p)
|
||||
: m_p(p)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Pointer, class Value>
|
||||
void* pointer_holder<Pointer, Value>::holds(converter::type_id_t dst_t)
|
||||
{
|
||||
if (dst_t == converter::type_id<Pointer>())
|
||||
return &this->m_p;
|
||||
|
||||
converter::type_id_t src_t = converter::type_id<Value>();
|
||||
return src_t == dst_t ? &*this->m_p
|
||||
: find_dynamic_type(&*this->m_p, src_t, dst_t);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // POINTER_HOLDER_DWA20011215_HPP
|
||||
@@ -26,23 +26,28 @@ template <
|
||||
PyTypeObject const* python_type
|
||||
, class Value
|
||||
, class PythonObject
|
||||
, Value& (*extract)(PythonObject&)
|
||||
, class Extract
|
||||
>
|
||||
struct reference_from_python : type_from_python<python_type>
|
||||
struct reference_from_python
|
||||
{
|
||||
typedef type_from_python<python_type> convertible_t;
|
||||
|
||||
reference_from_python()
|
||||
: m_mutable_converter(convertible, convert_mutable)
|
||||
, m_const_converter(convertible, convert_const)
|
||||
: m_mutable_converter(
|
||||
&convertible_t::convertible, convert_mutable)
|
||||
|
||||
, m_const_converter(
|
||||
&convertible_t::convertible, convert_const)
|
||||
{}
|
||||
|
||||
static Value& convert_mutable(PyObject* op, converter::from_python_data&)
|
||||
{
|
||||
return extract(*(PythonObject*)op);
|
||||
return Extract::execute(*(PythonObject*)op);
|
||||
}
|
||||
|
||||
static Value const& convert_const(PyObject* op, converter::from_python_data&)
|
||||
{
|
||||
return extract(*(PythonObject*)op);
|
||||
return Extract::execute(*(PythonObject*)op);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -9,12 +9,27 @@
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <typename T, class Derived>
|
||||
struct value_from_python
|
||||
{
|
||||
typedef converter::from_python_check from_python_check;
|
||||
|
||||
value_from_python(from_python_check convertible)
|
||||
: m_converter(
|
||||
convertible
|
||||
, &Derived::convert
|
||||
|
||||
// Change this to a compile-time check later to avoid
|
||||
// generating destroy function
|
||||
, has_trivial_destructor<T>::value ? 0 : &Derived::destroy
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
value_from_python()
|
||||
: m_converter(
|
||||
&Derived::convertible
|
||||
@@ -25,9 +40,6 @@ struct value_from_python
|
||||
, has_trivial_destructor<T>::value ? 0 : &Derived::destroy
|
||||
)
|
||||
{
|
||||
// Scalar types are really converted by-value; the formulation
|
||||
// is much simpler.
|
||||
BOOST_STATIC_ASSERT(!(is_scalar<T>::value));
|
||||
}
|
||||
|
||||
static void* get_storage(converter::from_python_data& data)
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
#include <boost/python/detail/wrap_python.hpp>
|
||||
#include <boost/python/converter/builtin_converters.hpp>
|
||||
#include <boost/python/converter/target.hpp>
|
||||
#include <boost/python/converter/from_python.hpp>
|
||||
#include <boost/python/value_from_python.hpp>
|
||||
#include <boost/python/converter/from_python_data.hpp>
|
||||
#include <boost/python/reference.hpp>
|
||||
#include <boost/cast.hpp>
|
||||
//#include <boost/mpl/type_list.hpp>
|
||||
@@ -18,113 +19,185 @@ namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace
|
||||
{
|
||||
struct int_value_functions_base
|
||||
// Only an object which we know is holding a char const* can be
|
||||
// converted to one
|
||||
struct convertible_to_cstring
|
||||
{
|
||||
static void* convertible(PyObject* obj)
|
||||
static unaryfunc* execute(PyObject* obj)
|
||||
{
|
||||
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
|
||||
|
||||
return number_methods && number_methods->nb_int
|
||||
? &number_methods->nb_int : 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct int_value_functions : int_value_functions_base
|
||||
{
|
||||
static T convert(PyObject* obj, from_python_data& data)
|
||||
{
|
||||
unaryfunc f = *static_cast<unaryfunc*>(data.stage1);
|
||||
ref int_object(f(obj));
|
||||
return numeric_cast<T>(PyInt_AsLong(int_object.get()));
|
||||
return PyString_Check(obj) ? &obj->ob_type->tp_str : 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct cstring_value_functions
|
||||
struct extract_cstring
|
||||
{
|
||||
static void* convertible(PyObject* obj)
|
||||
{
|
||||
return PyString_Check(obj) ? obj : 0;
|
||||
}
|
||||
|
||||
static char const* convert(PyObject* obj, from_python_data&)
|
||||
static char const* execute(PyObject* obj)
|
||||
{
|
||||
return PyString_AsString(obj);
|
||||
}
|
||||
};
|
||||
|
||||
char constructed;
|
||||
|
||||
struct string_cref_functions
|
||||
// Any object which can be converted to a Python string can also be
|
||||
// converted to a C++ string, since the latter owns its bytes.
|
||||
struct convertible_to_string
|
||||
{
|
||||
typedef std::string const& result_type;
|
||||
|
||||
static void* convertible(PyObject* obj)
|
||||
static unaryfunc* execute(PyObject* obj)
|
||||
{
|
||||
return obj->ob_type->tp_str ? &obj->ob_type->tp_str : 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Transform a function returning a unaryfunc* into one that returns a void*
|
||||
template <class F>
|
||||
struct return_void_ptr
|
||||
{
|
||||
static void* execute(PyObject* p) { return F::execute(p); }
|
||||
};
|
||||
|
||||
template <
|
||||
class T // The target type
|
||||
, class Convertible // returns a pointer to a unaryfunc producing an object
|
||||
, class TExtract // ...from which TExtract extracts T's constructor argument
|
||||
>
|
||||
struct tp_scalar_from_python
|
||||
: from_python_converter<T>
|
||||
{
|
||||
private:
|
||||
typedef return_void_ptr<Convertible> convertible_fn;
|
||||
|
||||
static std::string const& convert(
|
||||
PyObject* obj, from_python_data& data)
|
||||
public:
|
||||
tp_scalar_from_python()
|
||||
: from_python_converter<T>(
|
||||
&convertible_fn::execute
|
||||
, convert)
|
||||
{}
|
||||
|
||||
static T convert(PyObject* obj, from_python_data& data)
|
||||
{
|
||||
ref string_object((**static_cast<reprfunc*>(data.stage1))(obj));
|
||||
void* storage = get_storage<result_type>(data);
|
||||
std::string* p = new (storage) std::string(PyString_AsString(string_object.get()));
|
||||
unaryfunc converter = *(unaryfunc*)data.stage1;
|
||||
ref converted(converter(obj));
|
||||
return TExtract::execute(converted.get());
|
||||
}
|
||||
};
|
||||
|
||||
// Extract a reference to T using the functions in the source
|
||||
// object's type slots
|
||||
template <
|
||||
class T // The target type
|
||||
, class Convertible // returns a pointer to a unaryfunc producing an object
|
||||
, class TExtract // ...from which TExtract extracts T's constructor argument
|
||||
>
|
||||
struct tp_cref_from_python
|
||||
: value_from_python<T, tp_cref_from_python<T,Convertible,TExtract> >
|
||||
{
|
||||
private:
|
||||
typedef value_from_python<T, tp_cref_from_python<T,Convertible,TExtract> > base;
|
||||
|
||||
public:
|
||||
tp_cref_from_python()
|
||||
: base(&return_void_ptr<Convertible>::execute)
|
||||
{}
|
||||
|
||||
static T const& convert(PyObject* obj, from_python_data& data)
|
||||
{
|
||||
unaryfunc converter = *(unaryfunc*)data.stage1;
|
||||
|
||||
void* storage = get_storage(data);
|
||||
|
||||
ref converted(converter(obj));
|
||||
|
||||
T* const p = new (storage) T(TExtract::execute(converted.get()));
|
||||
|
||||
// note that construction is successful.
|
||||
data.stage1 = &constructed;
|
||||
data.stage1 = p;
|
||||
|
||||
return *p;
|
||||
}
|
||||
};
|
||||
|
||||
static void destroy(from_python_data& data)
|
||||
struct convertible_to_int
|
||||
{
|
||||
static unaryfunc* execute(PyObject* obj)
|
||||
{
|
||||
if (data.stage1 == &constructed)
|
||||
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
// For floating types, return the float conversion slot to avoid
|
||||
// creating a new object. We'll handle that in
|
||||
// py_int_or_float_as_long, below
|
||||
if (PyObject_TypeCheck(obj, &PyFloat_Type) && number_methods->nb_float)
|
||||
return &number_methods->nb_float;
|
||||
|
||||
return number_methods && number_methods->nb_int
|
||||
? &number_methods->nb_int : 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct py_int_or_float_as_long
|
||||
{
|
||||
static long execute(PyObject* obj)
|
||||
{
|
||||
if (PyObject_TypeCheck(obj, &PyFloat_Type))
|
||||
{
|
||||
typedef std::string string_t;
|
||||
void* storage = get_storage<result_type>(data);
|
||||
((string_t*)storage)->~string_t();
|
||||
return numeric_cast<long>(PyFloat_AS_DOUBLE(obj));
|
||||
}
|
||||
else
|
||||
{
|
||||
return PyInt_AS_LONG(obj);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class Base>
|
||||
struct rvalue_const_ref_functions : Base
|
||||
struct convertible_to_double
|
||||
{
|
||||
static T const& convert(PyObject* obj, from_python_data& data)
|
||||
static unaryfunc* execute(PyObject* obj)
|
||||
{
|
||||
void* storage = get_storage<T const&>(data);
|
||||
T* p = new (storage) T(Base::convert(obj,data));
|
||||
|
||||
// note that construction is successful.
|
||||
data.stage1 = &constructed;
|
||||
return *p;
|
||||
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
// For integer types, return the tp_int conversion slot to avoid
|
||||
// creating a new object. We'll handle that in
|
||||
// py_float_or_int_as_double, below
|
||||
if (PyObject_TypeCheck(obj, &PyInt_Type) && number_methods->nb_int)
|
||||
return &number_methods->nb_int;
|
||||
|
||||
return number_methods && number_methods->nb_float
|
||||
? &number_methods->nb_float : 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct register_int_converters
|
||||
struct py_float_or_int_as_double
|
||||
{
|
||||
template <class Ignored, class T>
|
||||
struct apply
|
||||
static double execute(PyObject* obj)
|
||||
{
|
||||
typedef void type;
|
||||
|
||||
static void execute()
|
||||
if (PyObject_TypeCheck(obj, &PyInt_Type))
|
||||
{
|
||||
typedef int_value_functions<T> value_functions;
|
||||
typedef rvalue_const_ref_functions<T,value_functions> cref_functions;
|
||||
|
||||
static from_python_converter<T> value_from_python(
|
||||
value_functions::convertible
|
||||
, value_functions::convert);
|
||||
static from_python_converter<T const&> cref_from_python(
|
||||
cref_functions::convertible
|
||||
, cref_functions::convert);
|
||||
};
|
||||
};
|
||||
return PyInt_AS_LONG(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
return PyFloat_AS_DOUBLE(obj);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define REGISTER_INT_CONVERTERS(U) register_int_converters::apply<void,U>::execute()
|
||||
template <class T, class Convertible, class Convert>
|
||||
struct scalar_from_python
|
||||
{
|
||||
tp_cref_from_python<T,Convertible,Convert> cref_converter;
|
||||
tp_scalar_from_python<T,Convertible,Convert> value_converter;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void register_int_converters(T* = 0)
|
||||
{
|
||||
static scalar_from_python<T, convertible_to_int, py_int_or_float_as_long> x;
|
||||
};
|
||||
}
|
||||
|
||||
#define REGISTER_INT_CONVERTERS(U) register_int_converters<U>()
|
||||
#define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U)
|
||||
|
||||
|
||||
@@ -134,20 +207,21 @@ void initialize_builtin_converters()
|
||||
REGISTER_INT_CONVERTERS2(short);
|
||||
REGISTER_INT_CONVERTERS2(int);
|
||||
REGISTER_INT_CONVERTERS2(long);
|
||||
// mpl::for_each<integral_types,void,register_int_converters>::execute();
|
||||
|
||||
static from_python_converter<char const*> cstring_from_python(
|
||||
&cstring_value_functions::convertible
|
||||
, &cstring_value_functions::convert);
|
||||
static scalar_from_python<
|
||||
float,convertible_to_double,py_float_or_int_as_double> float_from_python;
|
||||
|
||||
static scalar_from_python<
|
||||
double,convertible_to_double,py_float_or_int_as_double> double_from_python;
|
||||
|
||||
static scalar_from_python<
|
||||
long double,convertible_to_double,py_float_or_int_as_double> long_double_from_python;
|
||||
|
||||
static scalar_from_python<
|
||||
char const*, convertible_to_cstring, extract_cstring> cstring_from_python;
|
||||
|
||||
static from_python_converter<char const*const&> cstring_cref_from_python(
|
||||
&rvalue_const_ref_functions<char const*,cstring_value_functions>::convertible
|
||||
, &rvalue_const_ref_functions<char const*, cstring_value_functions>::convert);
|
||||
|
||||
static from_python_converter<std::string const&> string_cref_from_python(
|
||||
&string_cref_functions::convertible
|
||||
, &string_cref_functions::convert
|
||||
, &string_cref_functions::destroy);
|
||||
static tp_cref_from_python<
|
||||
std::string, convertible_to_string, extract_cstring> string_from_python;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
27
src/converter/from_python.cpp
Normal file
27
src/converter/from_python.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// 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.
|
||||
|
||||
#include <boost/python/converter/from_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
from_python_converter_base::from_python_converter_base(
|
||||
type_id_t type
|
||||
, from_python_check checker
|
||||
)
|
||||
: body(type)
|
||||
, m_convertible(checker)
|
||||
{
|
||||
registry::insert(*this);
|
||||
}
|
||||
|
||||
from_python_converter_base::~from_python_converter_base()
|
||||
{
|
||||
if (can_unregister())
|
||||
registry::remove(*this);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
24
src/converter/to_python.cpp
Normal file
24
src/converter/to_python.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
// 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.
|
||||
|
||||
#include <boost/python/converter/to_python.hpp>
|
||||
#include <boost/python/converter/registry.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
to_python_converter_base::to_python_converter_base(type_id_t key, to_python_function_base convert)
|
||||
: body(key)
|
||||
, m_convert(convert)
|
||||
{
|
||||
registry::insert(*this);
|
||||
}
|
||||
|
||||
to_python_converter_base::~to_python_converter_base()
|
||||
{
|
||||
registry::remove(*this);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
@@ -64,8 +64,11 @@ struct SimpleObject
|
||||
{
|
||||
PyObject_HEAD
|
||||
simple x;
|
||||
};
|
||||
|
||||
static simple& extract(SimpleObject& o) { return o.x; }
|
||||
struct extract_simple_object
|
||||
{
|
||||
static simple& execute(SimpleObject& o) { return o.x; }
|
||||
};
|
||||
|
||||
PyTypeObject SimpleType = {
|
||||
@@ -209,12 +212,13 @@ BOOST_PYTHON_MODULE_INIT(m1)
|
||||
&SimpleType
|
||||
, simple
|
||||
, SimpleObject
|
||||
, &SimpleObject::extract
|
||||
, extract_simple_object
|
||||
>
|
||||
unwrap_simple;
|
||||
|
||||
static to_python_converter<simple&> simple_ref_wrapper(simple_ref_to_python);
|
||||
|
||||
|
||||
module m1("m1");
|
||||
|
||||
typedef boost::python::objects::pointer_holder_generator<
|
||||
|
||||
@@ -49,9 +49,6 @@ PyObject* unwrap_int_const_ref(int const& x)
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
// MSVC6 bug workaround
|
||||
template <class T> struct xxxx;
|
||||
|
||||
// rewrap<T> extracts a T from the argument, then converts the T back
|
||||
// to a PyObject* and returns it.
|
||||
template <class T>
|
||||
|
||||
65
test/test_builtin_converters.cpp
Normal file
65
test/test_builtin_converters.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
// 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.
|
||||
#include <string>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/mpl/type_list.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
|
||||
|
||||
template <class T>
|
||||
struct by_value
|
||||
{
|
||||
static T rewrap(T x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct by_const_reference
|
||||
{
|
||||
static T rewrap(T const& x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(builtin_converters_ext)
|
||||
{
|
||||
boost::python::module("builtin_converters_ext")
|
||||
|
||||
.def("rewrap_value_signed_char", by_value<signed char>::rewrap)
|
||||
.def("rewrap_value_unsigned_char", by_value<unsigned char>::rewrap)
|
||||
.def("rewrap_value_int", by_value<int>::rewrap)
|
||||
.def("rewrap_value_unsigned_int", by_value<unsigned int>::rewrap)
|
||||
.def("rewrap_value_short", by_value<short>::rewrap)
|
||||
.def("rewrap_value_unsigned_short", by_value<unsigned short>::rewrap)
|
||||
.def("rewrap_value_long", by_value<long>::rewrap)
|
||||
.def("rewrap_value_unsigned_long", by_value<unsigned long>::rewrap)
|
||||
.def("rewrap_value_float", by_value<float>::rewrap)
|
||||
.def("rewrap_value_double", by_value<double>::rewrap)
|
||||
.def("rewrap_value_long_double", by_value<long double>::rewrap)
|
||||
.def("rewrap_value_string", by_value<std::string>::rewrap)
|
||||
.def("rewrap_value_cstring", by_value<char const*>::rewrap)
|
||||
|
||||
|
||||
.def("rewrap_const_reference_signed_char", by_const_reference<signed char>::rewrap)
|
||||
.def("rewrap_const_reference_unsigned_char", by_const_reference<unsigned char>::rewrap)
|
||||
.def("rewrap_const_reference_int", by_const_reference<int>::rewrap)
|
||||
.def("rewrap_const_reference_unsigned_int", by_const_reference<unsigned int>::rewrap)
|
||||
.def("rewrap_const_reference_short", by_const_reference<short>::rewrap)
|
||||
.def("rewrap_const_reference_unsigned_short", by_const_reference<unsigned short>::rewrap)
|
||||
.def("rewrap_const_reference_long", by_const_reference<long>::rewrap)
|
||||
.def("rewrap_const_reference_unsigned_long", by_const_reference<unsigned long>::rewrap)
|
||||
.def("rewrap_const_reference_float", by_const_reference<float>::rewrap)
|
||||
.def("rewrap_const_reference_double", by_const_reference<double>::rewrap)
|
||||
.def("rewrap_const_reference_long_double", by_const_reference<long double>::rewrap)
|
||||
.def("rewrap_const_reference_string", by_const_reference<std::string>::rewrap)
|
||||
.def("rewrap_const_reference_cstring", by_const_reference<char const*>::rewrap)
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
86
test/test_builtin_converters.py
Normal file
86
test/test_builtin_converters.py
Normal file
@@ -0,0 +1,86 @@
|
||||
"""
|
||||
>>> from builtin_converters_ext import *
|
||||
>>> rewrap_value_signed_char(42)
|
||||
42
|
||||
>>> rewrap_value_unsigned_char(42)
|
||||
42
|
||||
>>> rewrap_value_int(42)
|
||||
42
|
||||
>>> rewrap_value_unsigned_int(42)
|
||||
42
|
||||
>>> rewrap_value_short(42)
|
||||
42
|
||||
>>> rewrap_value_unsigned_short(42)
|
||||
42
|
||||
>>> rewrap_value_long(42)
|
||||
42
|
||||
>>> rewrap_value_unsigned_long(42)
|
||||
42
|
||||
|
||||
>>> abs(rewrap_value_float(4.2) - 4.2) < .000001
|
||||
1
|
||||
>>> rewrap_value_double(4.2) - 4.2
|
||||
0.0
|
||||
>>> rewrap_value_long_double(4.2) - 4.2
|
||||
0.0
|
||||
|
||||
>>> rewrap_value_cstring('hello, world')
|
||||
'hello, world'
|
||||
>>> rewrap_value_string('yo, wassup?')
|
||||
'yo, wassup?'
|
||||
|
||||
>>> rewrap_const_reference_signed_char(42)
|
||||
42
|
||||
>>> rewrap_const_reference_unsigned_char(42)
|
||||
42
|
||||
>>> rewrap_const_reference_int(42)
|
||||
42
|
||||
>>> rewrap_const_reference_unsigned_int(42)
|
||||
42
|
||||
>>> rewrap_const_reference_short(42)
|
||||
42
|
||||
>>> rewrap_const_reference_unsigned_short(42)
|
||||
42
|
||||
>>> rewrap_const_reference_long(42)
|
||||
42
|
||||
>>> rewrap_const_reference_unsigned_long(42)
|
||||
42
|
||||
>>> abs(rewrap_const_reference_float(4.2) - 4.2) < .000001
|
||||
1
|
||||
>>> rewrap_const_reference_double(4.2) - 4.2
|
||||
0.0
|
||||
>>> rewrap_const_reference_long_double(4.2) - 4.2
|
||||
0.0
|
||||
|
||||
>>> rewrap_const_reference_cstring('hello, world')
|
||||
'hello, world'
|
||||
>>> rewrap_const_reference_string('yo, wassup?')
|
||||
'yo, wassup?'
|
||||
|
||||
Now check implicit conversions between floating/integer types
|
||||
|
||||
>>> rewrap_const_reference_float(42)
|
||||
42.0
|
||||
|
||||
>>> rewrap_const_reference_int(42.0)
|
||||
42
|
||||
|
||||
>>> rewrap_value_float(42)
|
||||
42.0
|
||||
|
||||
>>> rewrap_value_int(42.0)
|
||||
42
|
||||
|
||||
"""
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
Reference in New Issue
Block a user