diff options
Diffstat (limited to 'boost/python/lvalue_from_pytype.hpp')
-rw-r--r-- | boost/python/lvalue_from_pytype.hpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/boost/python/lvalue_from_pytype.hpp b/boost/python/lvalue_from_pytype.hpp new file mode 100644 index 0000000000..e15dfbbb85 --- /dev/null +++ b/boost/python/lvalue_from_pytype.hpp @@ -0,0 +1,116 @@ +// 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 |