Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/python/opaque_pointer_converter.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

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