]> git.sesse.net Git - casparcg/blob - dependencies/boost/boost/python/lvalue_from_pytype.hpp
Manually merged pull request #222
[casparcg] / dependencies / boost / boost / python / lvalue_from_pytype.hpp
1 // Copyright David Abrahams 2002.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 #ifndef LVALUE_FROM_PYTYPE_DWA2002130_HPP
6 # define LVALUE_FROM_PYTYPE_DWA2002130_HPP
7
8 # include <boost/python/detail/prefix.hpp>
9 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
10 # include <boost/python/converter/pytype_function.hpp>
11 #endif
12
13 # include <boost/python/type_id.hpp>
14 # include <boost/python/converter/registry.hpp>
15 # include <boost/python/detail/void_ptr.hpp>
16
17 namespace boost { namespace python {
18
19 namespace detail
20 {
21   // Given a pointer-to-function of 1 parameter returning a reference
22   // type, return the type_id of the function's return type.
23   template <class T, class U>
24   inline type_info extractor_type_id(T&(*)(U))
25   {
26       return type_id<T>();
27   }
28
29   // A function generator whose static execute() function is an lvalue
30   // from_python converter using the given Extractor. U is expected to
31   // be the actual type of the PyObject instance from which the result
32   // is being extracted.
33   template <class Extractor, class U>
34   struct normalized_extractor
35   {
36       static inline void* execute(PyObject* op)
37       {
38           typedef typename boost::add_reference<U>::type param;
39           return &Extractor::execute(
40               boost::python::detail::void_ptr_to_reference(
41                   op, (param(*)())0 )
42               );
43       }
44   };
45
46   // Given an Extractor type and a pointer to its execute function,
47   // return a new object whose static execute function does the same
48   // job but is a conforming lvalue from_python conversion function.
49   //
50   // usage: normalize<Extractor>(&Extractor::execute)
51   template <class Extractor, class T, class U>
52   inline normalized_extractor<Extractor,U>
53   normalize(T(*)(U), Extractor* = 0)
54   {
55       return normalized_extractor<Extractor, U>();
56   }
57 }
58
59 // An Extractor which extracts the given member from a Python object
60 // whose instances are stored as InstanceType.
61 template <class InstanceType, class MemberType, MemberType (InstanceType::*member)>
62 struct extract_member
63 {
64     static MemberType& execute(InstanceType& c)
65     {
66         (void)Py_TYPE(&c); // static assertion
67         return c.*member;
68     }
69 };
70
71 // An Extractor which simply extracts the entire python object
72 // instance of InstanceType.
73 template <class InstanceType>
74 struct extract_identity
75 {
76     static InstanceType& execute(InstanceType& c)
77     {
78         (void)Py_TYPE(&c); // static assertion
79         return c;
80     }
81 };
82
83 // Registers a from_python conversion which extracts lvalues using
84 // Extractor's static execute function from Python objects whose type
85 // object is python_type.
86 template <class Extractor, PyTypeObject const* python_type>
87 struct lvalue_from_pytype 
88 {
89     lvalue_from_pytype()
90     {
91         converter::registry::insert
92             ( &extract
93             , detail::extractor_type_id(&Extractor::execute)
94 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
95             , &get_pytype
96 #endif
97             );
98     }
99  private:
100     static void* extract(PyObject* op)
101     {
102         return PyObject_TypeCheck(op, const_cast<PyTypeObject*>(python_type))
103             ? const_cast<void*>(
104                 static_cast<void const volatile*>(
105                     detail::normalize<Extractor>(&Extractor::execute).execute(op)))
106             : 0
107             ;
108     }
109 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
110     static PyTypeObject const*get_pytype() { return python_type; }
111 #endif
112 };
113
114 }} // namespace boost::python
115
116 #endif // LVALUE_FROM_PYTYPE_DWA2002130_HPP