117 lines
3.6 KiB
Plaintext
117 lines
3.6 KiB
Plaintext
|
// Copyright David Abrahams 2002.
|
||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||
|
#ifndef LVALUE_FROM_PYTYPE_DWA2002130_HPP
|
||
|
# define LVALUE_FROM_PYTYPE_DWA2002130_HPP
|
||
|
|
||
|
# include <boost/python/detail/prefix.hpp>
|
||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||
|
# include <boost/python/converter/pytype_function.hpp>
|
||
|
#endif
|
||
|
|
||
|
# include <boost/python/type_id.hpp>
|
||
|
# include <boost/python/converter/registry.hpp>
|
||
|
# include <boost/python/detail/void_ptr.hpp>
|
||
|
|
||
|
namespace boost { namespace python {
|
||
|
|
||
|
namespace detail
|
||
|
{
|
||
|
// Given a pointer-to-function of 1 parameter returning a reference
|
||
|
// type, return the type_id of the function's return type.
|
||
|
template <class T, class U>
|
||
|
inline type_info extractor_type_id(T&(*)(U))
|
||
|
{
|
||
|
return type_id<T>();
|
||
|
}
|
||
|
|
||
|
// A function generator whose static execute() function is an lvalue
|
||
|
// from_python converter using the given Extractor. U is expected to
|
||
|
// be the actual type of the PyObject instance from which the result
|
||
|
// is being extracted.
|
||
|
template <class Extractor, class U>
|
||
|
struct normalized_extractor
|
||
|
{
|
||
|
static inline void* execute(PyObject* op)
|
||
|
{
|
||
|
typedef typename boost::add_reference<U>::type param;
|
||
|
return &Extractor::execute(
|
||
|
boost::python::detail::void_ptr_to_reference(
|
||
|
op, (param(*)())0 )
|
||
|
);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Given an Extractor type and a pointer to its execute function,
|
||
|
// return a new object whose static execute function does the same
|
||
|
// job but is a conforming lvalue from_python conversion function.
|
||
|
//
|
||
|
// usage: normalize<Extractor>(&Extractor::execute)
|
||
|
template <class Extractor, class T, class U>
|
||
|
inline normalized_extractor<Extractor,U>
|
||
|
normalize(T(*)(U), Extractor* = 0)
|
||
|
{
|
||
|
return normalized_extractor<Extractor, U>();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// An Extractor which extracts the given member from a Python object
|
||
|
// whose instances are stored as InstanceType.
|
||
|
template <class InstanceType, class MemberType, MemberType (InstanceType::*member)>
|
||
|
struct extract_member
|
||
|
{
|
||
|
static MemberType& execute(InstanceType& c)
|
||
|
{
|
||
|
(void)Py_TYPE(&c); // static assertion
|
||
|
return c.*member;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// An Extractor which simply extracts the entire python object
|
||
|
// instance of InstanceType.
|
||
|
template <class InstanceType>
|
||
|
struct extract_identity
|
||
|
{
|
||
|
static InstanceType& execute(InstanceType& c)
|
||
|
{
|
||
|
(void)Py_TYPE(&c); // static assertion
|
||
|
return c;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Registers a from_python conversion which extracts lvalues using
|
||
|
// Extractor's static execute function from Python objects whose type
|
||
|
// object is python_type.
|
||
|
template <class Extractor, PyTypeObject const* python_type>
|
||
|
struct lvalue_from_pytype
|
||
|
{
|
||
|
lvalue_from_pytype()
|
||
|
{
|
||
|
converter::registry::insert
|
||
|
( &extract
|
||
|
, detail::extractor_type_id(&Extractor::execute)
|
||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||
|
, &get_pytype
|
||
|
#endif
|
||
|
);
|
||
|
}
|
||
|
private:
|
||
|
static void* extract(PyObject* op)
|
||
|
{
|
||
|
return PyObject_TypeCheck(op, const_cast<PyTypeObject*>(python_type))
|
||
|
? const_cast<void*>(
|
||
|
static_cast<void const volatile*>(
|
||
|
detail::normalize<Extractor>(&Extractor::execute).execute(op)))
|
||
|
: 0
|
||
|
;
|
||
|
}
|
||
|
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||
|
static PyTypeObject const*get_pytype() { return python_type; }
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
}} // namespace boost::python
|
||
|
|
||
|
#endif // LVALUE_FROM_PYTYPE_DWA2002130_HPP
|