Warning, file /include/boost/python/opaque_pointer_converter.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008 # ifndef OPAQUE_POINTER_CONVERTER_HPP_
0009 # define OPAQUE_POINTER_CONVERTER_HPP_
0010
0011 # include <boost/python/detail/prefix.hpp>
0012 # include <boost/python/lvalue_from_pytype.hpp>
0013 # include <boost/python/to_python_converter.hpp>
0014 # include <boost/python/converter/registrations.hpp>
0015 # include <boost/python/detail/dealloc.hpp>
0016 # include <boost/python/detail/type_traits.hpp>
0017 # include <boost/python/detail/none.hpp>
0018 # include <boost/python/type_id.hpp>
0019 # include <boost/python/errors.hpp>
0020
0021 # include <boost/implicit_cast.hpp>
0022
0023 # include <boost/mpl/eval_if.hpp>
0024 # include <boost/mpl/identity.hpp>
0025 # include <boost/mpl/assert.hpp>
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 namespace boost { namespace python {
0039
0040 template <class Pointee>
0041 struct opaque
0042 {
0043 opaque()
0044 {
0045 if (type_object.tp_name == 0)
0046 {
0047 type_object.tp_name = const_cast<char*>(type_id<Pointee*>().name());
0048 if (PyType_Ready (&type_object) < 0)
0049 {
0050 throw error_already_set();
0051 }
0052
0053 this->register_self();
0054 }
0055 }
0056
0057 static opaque instance;
0058 private:
0059
0060 static void* extract(PyObject* op)
0061 {
0062 return PyObject_TypeCheck(op, &type_object)
0063 ? static_cast<python_instance*>(implicit_cast<void*>(op))->x
0064 : 0
0065 ;
0066 }
0067
0068 static PyObject* wrap(void const* px)
0069 {
0070 Pointee* x = *static_cast<Pointee*const*>(px);
0071
0072 if (x == 0)
0073 return detail::none();
0074
0075 if ( python_instance *o = PyObject_New(python_instance, &type_object) )
0076 {
0077 o->x = x;
0078 return static_cast<PyObject*>(implicit_cast<void*>(o));
0079 }
0080 else
0081 {
0082 throw error_already_set();
0083 }
0084 }
0085
0086 void register_self()
0087 {
0088 converter::registration const *existing =
0089 converter::registry::query (type_id<Pointee*>());
0090
0091 if ((existing == 0) || (existing->m_to_python == 0))
0092 {
0093 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0094 converter::registry::insert(&extract, type_id<Pointee>(), &get_pytype);
0095 converter::registry::insert(&wrap, type_id<Pointee*>(), &get_pytype);
0096 #else
0097 converter::registry::insert(&extract, type_id<Pointee>());
0098 converter::registry::insert(&wrap, type_id<Pointee*>());
0099 #endif
0100 }
0101 }
0102
0103 struct python_instance
0104 {
0105 PyObject_HEAD
0106 Pointee* x;
0107 };
0108
0109 static PyTypeObject type_object;
0110 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0111 static PyTypeObject const *get_pytype(){return &type_object; }
0112 #endif
0113 };
0114
0115 template <class Pointee>
0116 opaque<Pointee> opaque<Pointee>::instance;
0117
0118 template <class Pointee>
0119 PyTypeObject opaque<Pointee>::type_object =
0120 {
0121 PyVarObject_HEAD_INIT(NULL, 0)
0122 0,
0123 sizeof( BOOST_DEDUCED_TYPENAME opaque<Pointee>::python_instance ),
0124 0,
0125 ::boost::python::detail::dealloc,
0126 0,
0127 0,
0128 0,
0129 0,
0130 0,
0131 0,
0132 0,
0133 0,
0134 0,
0135 0,
0136 0,
0137 0,
0138 0,
0139 0,
0140 0,
0141 0,
0142 0,
0143 0,
0144 0,
0145 0,
0146 0,
0147 0,
0148 0,
0149 0,
0150 0,
0151 0,
0152 0,
0153 0,
0154 0,
0155 0,
0156 0,
0157 0,
0158 0,
0159 0,
0160 0,
0161 0,
0162 0,
0163 0,
0164 0,
0165 0,
0166 #if PYTHON_API_VERSION >= 1012
0167 0
0168 #endif
0169 };
0170 }}
0171
0172
0173 # define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \
0174 namespace boost { namespace python { \
0175 template<> \
0176 inline type_info type_id<Pointee>() \
0177 { \
0178 return type_info (typeid (Pointee *)); \
0179 } \
0180 template<> \
0181 inline type_info type_id<const volatile Pointee&>() \
0182 { \
0183 return type_info (typeid (Pointee *)); \
0184 } \
0185 }}
0186
0187 # endif