Back to home page

EIC code displayed by LXR

 
 

    


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 // Copyright Gottfried Ganßauge 2003..2006.
0002 // Distributed under the Boost Software License, Version 1.0. (See
0003 // accompanying file LICENSE_1_0.txt or copy at
0004 // http://www.boost.org/LICENSE_1_0.txt)
0005 /*
0006  * Generic Conversion of opaque C++-pointers to a Python-Wrapper.
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 // opaque --
0028 //
0029 // registers to- and from- python conversions for a type Pointee.
0030 //
0031 // Note:
0032 // In addition you need to define specializations for type_id
0033 // on the type pointed to by Pointer using
0034 // BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)
0035 //
0036 // For an example see libs/python/test/opaque.cpp
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,          /* tp_print */
0127     0,          /* tp_getattr */
0128     0,          /* tp_setattr */
0129     0,          /* tp_compare */
0130     0,          /* tp_repr */
0131     0,          /* tp_as_number */
0132     0,          /* tp_as_sequence */
0133     0,          /* tp_as_mapping */
0134     0,          /* tp_hash */
0135     0,          /* tp_call */
0136     0,          /* tp_str */
0137     0,          /* tp_getattro */
0138     0,          /* tp_setattro */
0139     0,          /* tp_as_buffer */
0140     0,          /* tp_flags */
0141     0,          /* tp_doc */
0142     0,          /* tp_traverse */
0143     0,          /* tp_clear */
0144     0,          /* tp_richcompare */
0145     0,          /* tp_weaklistoffset */
0146     0,          /* tp_iter */
0147     0,          /* tp_iternext */
0148     0,          /* tp_methods */
0149     0,          /* tp_members */
0150     0,          /* tp_getset */
0151     0,          /* tp_base */
0152     0,          /* tp_dict */
0153     0,          /* tp_descr_get */
0154     0,          /* tp_descr_set */
0155     0,          /* tp_dictoffset */
0156     0,          /* tp_init */
0157     0,          /* tp_alloc */
0158     0,          /* tp_new */
0159     0,          /* tp_free */
0160     0,          /* tp_is_gc */
0161     0,          /* tp_bases */
0162     0,          /* tp_mro */
0163     0,          /* tp_cache */
0164     0,          /* tp_subclasses */
0165     0,          /* tp_weaklist */
0166 #if PYTHON_API_VERSION >= 1012
0167     0           /* tp_del */
0168 #endif
0169 };
0170 }} // namespace boost::python
0171 
0172 // If you change the below, don't forget to alter the end of type_id.hpp
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    // OPAQUE_POINTER_CONVERTER_HPP_