]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/python/opaque_pointer_converter.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / python / opaque_pointer_converter.hpp
1 // Copyright Gottfried Ganßauge 2003..2006.
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 /*
6 * Generic Conversion of opaque C++-pointers to a Python-Wrapper.
7 */
8 # ifndef OPAQUE_POINTER_CONVERTER_HPP_
9 # define OPAQUE_POINTER_CONVERTER_HPP_
10
11 # include <boost/python/detail/prefix.hpp>
12 # include <boost/python/lvalue_from_pytype.hpp>
13 # include <boost/python/to_python_converter.hpp>
14 # include <boost/python/converter/registrations.hpp>
15 # include <boost/python/detail/dealloc.hpp>
16 # include <boost/python/detail/type_traits.hpp>
17 # include <boost/python/detail/none.hpp>
18 # include <boost/python/type_id.hpp>
19 # include <boost/python/errors.hpp>
20
21 # include <boost/implicit_cast.hpp>
22
23 # include <boost/mpl/eval_if.hpp>
24 # include <boost/mpl/identity.hpp>
25 # include <boost/mpl/assert.hpp>
26
27 // opaque --
28 //
29 // registers to- and from- python conversions for a type Pointee.
30 //
31 // Note:
32 // In addition you need to define specializations for type_id
33 // on the type pointed to by Pointer using
34 // BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)
35 //
36 // For an example see libs/python/test/opaque.cpp
37 //
38 namespace boost { namespace python {
39
40 template <class Pointee>
41 struct opaque
42 {
43 opaque()
44 {
45 if (type_object.tp_name == 0)
46 {
47 type_object.tp_name = const_cast<char*>(type_id<Pointee*>().name());
48 if (PyType_Ready (&type_object) < 0)
49 {
50 throw error_already_set();
51 }
52
53 this->register_self();
54 }
55 }
56
57 static opaque instance;
58 private:
59
60 static void* extract(PyObject* op)
61 {
62 return PyObject_TypeCheck(op, &type_object)
63 ? static_cast<python_instance*>(implicit_cast<void*>(op))->x
64 : 0
65 ;
66 }
67
68 static PyObject* wrap(void const* px)
69 {
70 Pointee* x = *static_cast<Pointee*const*>(px);
71
72 if (x == 0)
73 return detail::none();
74
75 if ( python_instance *o = PyObject_New(python_instance, &type_object) )
76 {
77 o->x = x;
78 return static_cast<PyObject*>(implicit_cast<void*>(o));
79 }
80 else
81 {
82 throw error_already_set();
83 }
84 }
85
86 void register_self()
87 {
88 converter::registration const *existing =
89 converter::registry::query (type_id<Pointee*>());
90
91 if ((existing == 0) || (existing->m_to_python == 0))
92 {
93 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
94 converter::registry::insert(&extract, type_id<Pointee>(), &get_pytype);
95 converter::registry::insert(&wrap, type_id<Pointee*>(), &get_pytype);
96 #else
97 converter::registry::insert(&extract, type_id<Pointee>());
98 converter::registry::insert(&wrap, type_id<Pointee*>());
99 #endif
100 }
101 }
102
103 struct python_instance
104 {
105 PyObject_HEAD
106 Pointee* x;
107 };
108
109 static PyTypeObject type_object;
110 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
111 static PyTypeObject const *get_pytype(){return &type_object; }
112 #endif
113 };
114
115 template <class Pointee>
116 opaque<Pointee> opaque<Pointee>::instance;
117
118 template <class Pointee>
119 PyTypeObject opaque<Pointee>::type_object =
120 {
121 PyVarObject_HEAD_INIT(NULL, 0)
122 0,
123 sizeof( BOOST_DEDUCED_TYPENAME opaque<Pointee>::python_instance ),
124 0,
125 ::boost::python::detail::dealloc,
126 0, /* tp_print */
127 0, /* tp_getattr */
128 0, /* tp_setattr */
129 0, /* tp_compare */
130 0, /* tp_repr */
131 0, /* tp_as_number */
132 0, /* tp_as_sequence */
133 0, /* tp_as_mapping */
134 0, /* tp_hash */
135 0, /* tp_call */
136 0, /* tp_str */
137 0, /* tp_getattro */
138 0, /* tp_setattro */
139 0, /* tp_as_buffer */
140 0, /* tp_flags */
141 0, /* tp_doc */
142 0, /* tp_traverse */
143 0, /* tp_clear */
144 0, /* tp_richcompare */
145 0, /* tp_weaklistoffset */
146 0, /* tp_iter */
147 0, /* tp_iternext */
148 0, /* tp_methods */
149 0, /* tp_members */
150 0, /* tp_getset */
151 0, /* tp_base */
152 0, /* tp_dict */
153 0, /* tp_descr_get */
154 0, /* tp_descr_set */
155 0, /* tp_dictoffset */
156 0, /* tp_init */
157 0, /* tp_alloc */
158 0, /* tp_new */
159 0, /* tp_free */
160 0, /* tp_is_gc */
161 0, /* tp_bases */
162 0, /* tp_mro */
163 0, /* tp_cache */
164 0, /* tp_subclasses */
165 0, /* tp_weaklist */
166 #if PYTHON_API_VERSION >= 1012
167 0 /* tp_del */
168 #endif
169 };
170 }} // namespace boost::python
171
172 // If you change the below, don't forget to alter the end of type_id.hpp
173 # define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \
174 namespace boost { namespace python { \
175 template<> \
176 inline type_info type_id<Pointee>() \
177 { \
178 return type_info (typeid (Pointee *)); \
179 } \
180 template<> \
181 inline type_info type_id<const volatile Pointee&>() \
182 { \
183 return type_info (typeid (Pointee *)); \
184 } \
185 }}
186
187 # endif // OPAQUE_POINTER_CONVERTER_HPP_