comparison DEPENDENCIES/generic/include/boost/python/handle.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
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 HANDLE_DWA200269_HPP
6 # define HANDLE_DWA200269_HPP
7
8 # include <boost/python/detail/prefix.hpp>
9
10 # include <boost/python/cast.hpp>
11 # include <boost/python/errors.hpp>
12 # include <boost/python/borrowed.hpp>
13 # include <boost/python/handle_fwd.hpp>
14 # include <boost/python/refcount.hpp>
15 # include <boost/python/tag.hpp>
16 # include <boost/python/detail/raw_pyobject.hpp>
17
18 namespace boost { namespace python {
19
20 template <class T> struct null_ok;
21
22 template <class T>
23 inline null_ok<T>* allow_null(T* p)
24 {
25 return (null_ok<T>*)p;
26 }
27
28 namespace detail
29 {
30 template <class T>
31 inline T* manage_ptr(detail::borrowed<null_ok<T> >* p, int)
32 {
33 return python::xincref((T*)p);
34 }
35
36 template <class T>
37 inline T* manage_ptr(null_ok<detail::borrowed<T> >* p, int)
38 {
39 return python::xincref((T*)p);
40 }
41
42 template <class T>
43 inline T* manage_ptr(detail::borrowed<T>* p, long)
44 {
45 return python::incref(expect_non_null((T*)p));
46 }
47
48 template <class T>
49 inline T* manage_ptr(null_ok<T>* p, long)
50 {
51 return (T*)p;
52 }
53
54 template <class T>
55 inline T* manage_ptr(T* p, ...)
56 {
57 return expect_non_null(p);
58 }
59 }
60
61 template <class T>
62 class handle
63 {
64 typedef T* (handle::* bool_type )() const;
65
66 public: // types
67 typedef T element_type;
68
69 public: // member functions
70 handle();
71 ~handle();
72
73 template <class Y>
74 explicit handle(Y* p)
75 : m_p(
76 python::upcast<T>(
77 detail::manage_ptr(p, 0)
78 )
79 )
80 {
81 }
82
83 handle& operator=(handle const& r)
84 {
85 python::xdecref(m_p);
86 m_p = python::xincref(r.m_p);
87 return *this;
88 }
89
90 #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
91
92 template<typename Y>
93 handle& operator=(handle<Y> const & r) // never throws
94 {
95 python::xdecref(m_p);
96 m_p = python::xincref(python::upcast<T>(r.get()));
97 return *this;
98 }
99
100 #endif
101
102 template <typename Y>
103 handle(handle<Y> const& r)
104 : m_p(python::xincref(python::upcast<T>(r.get())))
105 {
106 }
107
108 handle(handle const& r)
109 : m_p(python::xincref(r.m_p))
110 {
111 }
112
113 T* operator-> () const;
114 T& operator* () const;
115 T* get() const;
116 T* release();
117 void reset();
118
119 operator bool_type() const // never throws
120 {
121 return m_p ? &handle<T>::get : 0;
122 }
123 bool operator! () const; // never throws
124
125 public: // implementation details -- do not touch
126 // Defining this in the class body suppresses a VC7 link failure
127 inline handle(detail::borrowed_reference x)
128 : m_p(
129 python::incref(
130 downcast<T>((PyObject*)x)
131 ))
132 {
133 }
134
135 private: // data members
136 T* m_p;
137 };
138
139 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
140 } // namespace python
141 #endif
142
143 template<class T> inline T * get_pointer(python::handle<T> const & p)
144 {
145 return p.get();
146 }
147
148 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
149 namespace python {
150 #else
151
152 // We don't want get_pointer above to hide the others
153 using boost::get_pointer;
154
155 #endif
156
157 typedef handle<PyTypeObject> type_handle;
158
159 //
160 // Compile-time introspection
161 //
162 # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
163 template<typename T>
164 class is_handle
165 {
166 public:
167 BOOST_STATIC_CONSTANT(bool, value = false);
168 };
169
170 template<typename T>
171 class is_handle<handle<T> >
172 {
173 public:
174 BOOST_STATIC_CONSTANT(bool, value = true);
175 };
176 # else
177 namespace detail
178 {
179 typedef char (&yes_handle_t)[1];
180 typedef char (&no_handle_t)[2];
181
182 no_handle_t is_handle_test(...);
183
184 template<typename T>
185 yes_handle_t is_handle_test(boost::type< handle<T> >);
186 }
187
188 template<typename T>
189 class is_handle
190 {
191 public:
192 BOOST_STATIC_CONSTANT(
193 bool, value = (
194 sizeof(detail::is_handle_test(boost::type<T>()))
195 == sizeof(detail::yes_handle_t)));
196 };
197 # endif
198
199 //
200 // implementations
201 //
202 template <class T>
203 inline handle<T>::handle()
204 : m_p(0)
205 {
206 }
207
208 template <class T>
209 inline handle<T>::~handle()
210 {
211 python::xdecref(m_p);
212 }
213
214 template <class T>
215 inline T* handle<T>::operator->() const
216 {
217 return m_p;
218 }
219
220 template <class T>
221 inline T& handle<T>::operator*() const
222 {
223 return *m_p;
224 }
225
226 template <class T>
227 inline T* handle<T>::get() const
228 {
229 return m_p;
230 }
231
232 template <class T>
233 inline bool handle<T>::operator!() const
234 {
235 return m_p == 0;
236 }
237
238 template <class T>
239 inline T* handle<T>::release()
240 {
241 T* result = m_p;
242 m_p = 0;
243 return result;
244 }
245
246 template <class T>
247 inline void handle<T>::reset()
248 {
249 python::xdecref(m_p);
250 m_p = 0;
251 }
252
253 // Because get_managed_object must return a non-null PyObject*, we
254 // return Py_None if the handle is null.
255 template <class T>
256 inline PyObject* get_managed_object(handle<T> const& h, tag_t)
257 {
258 return h.get() ? python::upcast<PyObject>(h.get()) : Py_None;
259 }
260
261 }} // namespace boost::python
262
263
264 #endif // HANDLE_DWA200269_HPP