summaryrefslogtreecommitdiff
path: root/boost/python/lvalue_from_pytype.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/python/lvalue_from_pytype.hpp')
-rw-r--r--boost/python/lvalue_from_pytype.hpp116
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