Chris@16
|
1 // Copyright David Abrahams 2002.
|
Chris@16
|
2 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
3 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5 #ifndef OBJECT_CORE_DWA2002615_HPP
|
Chris@16
|
6 # define OBJECT_CORE_DWA2002615_HPP
|
Chris@16
|
7
|
Chris@16
|
8 # define BOOST_PYTHON_OBJECT_HAS_IS_NONE // added 2010-03-15 by rwgk
|
Chris@16
|
9
|
Chris@16
|
10 # include <boost/python/detail/prefix.hpp>
|
Chris@16
|
11
|
Chris@16
|
12 # include <boost/type.hpp>
|
Chris@16
|
13
|
Chris@16
|
14 # include <boost/python/call.hpp>
|
Chris@16
|
15 # include <boost/python/handle_fwd.hpp>
|
Chris@16
|
16 # include <boost/python/errors.hpp>
|
Chris@16
|
17 # include <boost/python/refcount.hpp>
|
Chris@16
|
18 # include <boost/python/detail/preprocessor.hpp>
|
Chris@16
|
19 # include <boost/python/tag.hpp>
|
Chris@16
|
20 # include <boost/python/def_visitor.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 # include <boost/python/detail/raw_pyobject.hpp>
|
Chris@16
|
23 # include <boost/python/detail/dependent.hpp>
|
Chris@16
|
24
|
Chris@16
|
25 # include <boost/python/object/forward.hpp>
|
Chris@16
|
26 # include <boost/python/object/add_to_namespace.hpp>
|
Chris@16
|
27
|
Chris@16
|
28 # include <boost/preprocessor/iterate.hpp>
|
Chris@16
|
29 # include <boost/preprocessor/debug/line.hpp>
|
Chris@16
|
30
|
Chris@16
|
31 # include <boost/python/detail/is_xxx.hpp>
|
Chris@16
|
32 # include <boost/python/detail/string_literal.hpp>
|
Chris@16
|
33 # include <boost/python/detail/def_helper_fwd.hpp>
|
Chris@16
|
34
|
Chris@16
|
35 # include <boost/type_traits/is_same.hpp>
|
Chris@16
|
36 # include <boost/type_traits/is_convertible.hpp>
|
Chris@16
|
37 # include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
38
|
Chris@16
|
39 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
Chris@16
|
40 # include <boost/type_traits/add_pointer.hpp>
|
Chris@16
|
41 # endif
|
Chris@16
|
42
|
Chris@16
|
43 # include <boost/mpl/if.hpp>
|
Chris@16
|
44
|
Chris@16
|
45 namespace boost { namespace python {
|
Chris@16
|
46
|
Chris@16
|
47 namespace detail
|
Chris@16
|
48 {
|
Chris@16
|
49 class kwds_proxy;
|
Chris@16
|
50 class args_proxy;
|
Chris@16
|
51 }
|
Chris@16
|
52
|
Chris@16
|
53 namespace converter
|
Chris@16
|
54 {
|
Chris@16
|
55 template <class T> struct arg_to_python;
|
Chris@16
|
56 }
|
Chris@16
|
57
|
Chris@16
|
58 // Put this in an inner namespace so that the generalized operators won't take over
|
Chris@16
|
59 namespace api
|
Chris@16
|
60 {
|
Chris@16
|
61
|
Chris@16
|
62 // This file contains the definition of the object class and enough to
|
Chris@16
|
63 // construct/copy it, but not enough to do operations like
|
Chris@16
|
64 // attribute/item access or addition.
|
Chris@16
|
65
|
Chris@16
|
66 template <class Policies> class proxy;
|
Chris@16
|
67
|
Chris@16
|
68 struct const_attribute_policies;
|
Chris@16
|
69 struct attribute_policies;
|
Chris@16
|
70 struct const_objattribute_policies;
|
Chris@16
|
71 struct objattribute_policies;
|
Chris@16
|
72 struct const_item_policies;
|
Chris@16
|
73 struct item_policies;
|
Chris@16
|
74 struct const_slice_policies;
|
Chris@16
|
75 struct slice_policies;
|
Chris@16
|
76 class slice_nil;
|
Chris@16
|
77
|
Chris@16
|
78 typedef proxy<const_attribute_policies> const_object_attribute;
|
Chris@16
|
79 typedef proxy<attribute_policies> object_attribute;
|
Chris@16
|
80 typedef proxy<const_objattribute_policies> const_object_objattribute;
|
Chris@16
|
81 typedef proxy<objattribute_policies> object_objattribute;
|
Chris@16
|
82 typedef proxy<const_item_policies> const_object_item;
|
Chris@16
|
83 typedef proxy<item_policies> object_item;
|
Chris@16
|
84 typedef proxy<const_slice_policies> const_object_slice;
|
Chris@16
|
85 typedef proxy<slice_policies> object_slice;
|
Chris@16
|
86
|
Chris@16
|
87 //
|
Chris@16
|
88 // is_proxy -- proxy type detection
|
Chris@16
|
89 //
|
Chris@16
|
90 BOOST_PYTHON_IS_XXX_DEF(proxy, boost::python::api::proxy, 1)
|
Chris@16
|
91
|
Chris@16
|
92 template <class T> struct object_initializer;
|
Chris@16
|
93
|
Chris@16
|
94 class object;
|
Chris@16
|
95 typedef PyObject* (object::*bool_type)() const;
|
Chris@16
|
96
|
Chris@16
|
97 template <class U>
|
Chris@16
|
98 class object_operators : public def_visitor<U>
|
Chris@16
|
99 {
|
Chris@16
|
100 protected:
|
Chris@16
|
101 # if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
|
Chris@16
|
102 typedef object const& object_cref;
|
Chris@16
|
103 # else
|
Chris@16
|
104 typedef object object_cref;
|
Chris@16
|
105 # endif
|
Chris@16
|
106 public:
|
Chris@16
|
107 // function call
|
Chris@16
|
108 //
|
Chris@16
|
109 object operator()() const;
|
Chris@16
|
110
|
Chris@16
|
111 # define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, <boost/python/object_call.hpp>))
|
Chris@16
|
112 # include BOOST_PP_ITERATE()
|
Chris@16
|
113
|
Chris@16
|
114 detail::args_proxy operator* () const;
|
Chris@16
|
115 object operator()(detail::args_proxy const &args) const;
|
Chris@16
|
116 object operator()(detail::args_proxy const &args,
|
Chris@16
|
117 detail::kwds_proxy const &kwds) const;
|
Chris@16
|
118
|
Chris@16
|
119 // truth value testing
|
Chris@16
|
120 //
|
Chris@16
|
121 operator bool_type() const;
|
Chris@16
|
122 bool operator!() const; // needed for vc6
|
Chris@16
|
123
|
Chris@16
|
124 // Attribute access
|
Chris@16
|
125 //
|
Chris@16
|
126 const_object_attribute attr(char const*) const;
|
Chris@16
|
127 object_attribute attr(char const*);
|
Chris@16
|
128 const_object_objattribute attr(object const&) const;
|
Chris@16
|
129 object_objattribute attr(object const&);
|
Chris@16
|
130
|
Chris@16
|
131 // Wrap 'in' operator (aka. __contains__)
|
Chris@16
|
132 template <class T>
|
Chris@16
|
133 object contains(T const& key) const;
|
Chris@16
|
134
|
Chris@16
|
135 // item access
|
Chris@16
|
136 //
|
Chris@16
|
137 const_object_item operator[](object_cref) const;
|
Chris@16
|
138 object_item operator[](object_cref);
|
Chris@16
|
139
|
Chris@16
|
140 template <class T>
|
Chris@16
|
141 const_object_item
|
Chris@16
|
142 operator[](T const& key) const
|
Chris@16
|
143 # if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
Chris@16
|
144 ;
|
Chris@16
|
145 # else
|
Chris@16
|
146 {
|
Chris@16
|
147 return (*this)[object(key)];
|
Chris@16
|
148 }
|
Chris@16
|
149 # endif
|
Chris@16
|
150
|
Chris@16
|
151 template <class T>
|
Chris@16
|
152 object_item
|
Chris@16
|
153 operator[](T const& key)
|
Chris@16
|
154 # if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
Chris@16
|
155 ;
|
Chris@16
|
156 # else
|
Chris@16
|
157 {
|
Chris@16
|
158 return (*this)[object(key)];
|
Chris@16
|
159 }
|
Chris@16
|
160 # endif
|
Chris@16
|
161
|
Chris@16
|
162 // slicing
|
Chris@16
|
163 //
|
Chris@16
|
164 const_object_slice slice(object_cref, object_cref) const;
|
Chris@16
|
165 object_slice slice(object_cref, object_cref);
|
Chris@16
|
166
|
Chris@16
|
167 const_object_slice slice(slice_nil, object_cref) const;
|
Chris@16
|
168 object_slice slice(slice_nil, object_cref);
|
Chris@16
|
169
|
Chris@16
|
170 const_object_slice slice(object_cref, slice_nil) const;
|
Chris@16
|
171 object_slice slice(object_cref, slice_nil);
|
Chris@16
|
172
|
Chris@16
|
173 const_object_slice slice(slice_nil, slice_nil) const;
|
Chris@16
|
174 object_slice slice(slice_nil, slice_nil);
|
Chris@16
|
175
|
Chris@16
|
176 template <class T, class V>
|
Chris@16
|
177 const_object_slice
|
Chris@16
|
178 slice(T const& start, V const& end) const
|
Chris@16
|
179 # if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
Chris@16
|
180 ;
|
Chris@16
|
181 # else
|
Chris@16
|
182 {
|
Chris@16
|
183 return this->slice(
|
Chris@16
|
184 slice_bound<T>::type(start)
|
Chris@16
|
185 , slice_bound<V>::type(end));
|
Chris@16
|
186 }
|
Chris@16
|
187 # endif
|
Chris@16
|
188
|
Chris@16
|
189 template <class T, class V>
|
Chris@16
|
190 object_slice
|
Chris@16
|
191 slice(T const& start, V const& end)
|
Chris@16
|
192 # if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
Chris@16
|
193 ;
|
Chris@16
|
194 # else
|
Chris@16
|
195 {
|
Chris@16
|
196 return this->slice(
|
Chris@16
|
197 slice_bound<T>::type(start)
|
Chris@16
|
198 , slice_bound<V>::type(end));
|
Chris@16
|
199 }
|
Chris@16
|
200 # endif
|
Chris@16
|
201
|
Chris@16
|
202 private: // def visitation for adding callable objects as class methods
|
Chris@16
|
203
|
Chris@16
|
204 template <class ClassT, class DocStringT>
|
Chris@16
|
205 void visit(ClassT& cl, char const* name, python::detail::def_helper<DocStringT> const& helper) const
|
Chris@16
|
206 {
|
Chris@16
|
207 // It's too late to specify anything other than docstrings if
|
Chris@16
|
208 // the callable object is already wrapped.
|
Chris@16
|
209 BOOST_STATIC_ASSERT(
|
Chris@16
|
210 (is_same<char const*,DocStringT>::value
|
Chris@16
|
211 || detail::is_string_literal<DocStringT const>::value));
|
Chris@16
|
212
|
Chris@16
|
213 objects::add_to_namespace(cl, name, this->derived_visitor(), helper.doc());
|
Chris@16
|
214 }
|
Chris@16
|
215
|
Chris@16
|
216 friend class python::def_visitor_access;
|
Chris@16
|
217
|
Chris@16
|
218 private:
|
Chris@16
|
219 // there is a confirmed CWPro8 codegen bug here. We prevent the
|
Chris@16
|
220 // early destruction of a temporary by binding a named object
|
Chris@16
|
221 // instead.
|
Chris@16
|
222 # if __MWERKS__ < 0x3000 || __MWERKS__ > 0x3003
|
Chris@16
|
223 typedef object const& object_cref2;
|
Chris@16
|
224 # else
|
Chris@16
|
225 typedef object const object_cref2;
|
Chris@16
|
226 # endif
|
Chris@16
|
227 };
|
Chris@16
|
228
|
Chris@16
|
229
|
Chris@16
|
230 // VC6 and VC7 require this base class in order to generate the
|
Chris@16
|
231 // correct copy constructor for object. We can't define it there
|
Chris@16
|
232 // explicitly or it will complain of ambiguity.
|
Chris@16
|
233 struct object_base : object_operators<object>
|
Chris@16
|
234 {
|
Chris@16
|
235 // copy constructor without NULL checking, for efficiency.
|
Chris@16
|
236 inline object_base(object_base const&);
|
Chris@16
|
237 inline object_base(PyObject* ptr);
|
Chris@16
|
238
|
Chris@16
|
239 inline object_base& operator=(object_base const& rhs);
|
Chris@16
|
240 inline ~object_base();
|
Chris@16
|
241
|
Chris@16
|
242 // Underlying object access -- returns a borrowed reference
|
Chris@16
|
243 inline PyObject* ptr() const;
|
Chris@16
|
244
|
Chris@16
|
245 inline bool is_none() const;
|
Chris@16
|
246
|
Chris@16
|
247 private:
|
Chris@16
|
248 PyObject* m_ptr;
|
Chris@16
|
249 };
|
Chris@16
|
250
|
Chris@16
|
251 # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
Chris@16
|
252 template <class T, class U>
|
Chris@16
|
253 struct is_derived_impl
|
Chris@16
|
254 {
|
Chris@16
|
255 static T x;
|
Chris@16
|
256 template <class X>
|
Chris@16
|
257 static X* to_pointer(X const&);
|
Chris@16
|
258
|
Chris@16
|
259 static char test(U const*);
|
Chris@16
|
260 typedef char (&no)[2];
|
Chris@16
|
261 static no test(...);
|
Chris@16
|
262
|
Chris@16
|
263 BOOST_STATIC_CONSTANT(bool, value = sizeof(test(to_pointer(x))) == 1);
|
Chris@16
|
264 };
|
Chris@16
|
265
|
Chris@16
|
266 template <class T, class U>
|
Chris@16
|
267 struct is_derived
|
Chris@16
|
268 : mpl::bool_<is_derived_impl<T,U>::value>
|
Chris@16
|
269 {};
|
Chris@16
|
270 # else
|
Chris@16
|
271 template <class T, class U>
|
Chris@16
|
272 struct is_derived
|
Chris@16
|
273 : is_convertible<
|
Chris@16
|
274 typename remove_reference<T>::type*
|
Chris@16
|
275 , U const*
|
Chris@16
|
276 >
|
Chris@16
|
277 {};
|
Chris@16
|
278 # endif
|
Chris@16
|
279
|
Chris@16
|
280 template <class T>
|
Chris@16
|
281 typename objects::unforward_cref<T>::type do_unforward_cref(T const& x)
|
Chris@16
|
282 {
|
Chris@16
|
283 # if BOOST_WORKAROUND(__GNUC__, == 2)
|
Chris@16
|
284 typedef typename objects::unforward_cref<T>::type ret;
|
Chris@16
|
285 return ret(x);
|
Chris@16
|
286 # else
|
Chris@16
|
287 return x;
|
Chris@16
|
288 # endif
|
Chris@16
|
289 }
|
Chris@16
|
290
|
Chris@16
|
291 # if BOOST_WORKAROUND(__GNUC__, == 2)
|
Chris@16
|
292 // GCC 2.x has non-const string literals; this hacks around that problem.
|
Chris@16
|
293 template <unsigned N>
|
Chris@16
|
294 char const (& do_unforward_cref(char const(&x)[N]) )[N]
|
Chris@16
|
295 {
|
Chris@16
|
296 return x;
|
Chris@16
|
297 }
|
Chris@16
|
298 # endif
|
Chris@16
|
299
|
Chris@16
|
300 class object;
|
Chris@16
|
301
|
Chris@16
|
302 template <class T>
|
Chris@16
|
303 PyObject* object_base_initializer(T const& x)
|
Chris@16
|
304 {
|
Chris@16
|
305 typedef typename is_derived<
|
Chris@16
|
306 BOOST_DEDUCED_TYPENAME objects::unforward_cref<T>::type
|
Chris@16
|
307 , object
|
Chris@16
|
308 >::type is_obj;
|
Chris@16
|
309
|
Chris@16
|
310 return object_initializer<
|
Chris@16
|
311 BOOST_DEDUCED_TYPENAME unwrap_reference<T>::type
|
Chris@16
|
312 >::get(
|
Chris@16
|
313 x
|
Chris@16
|
314 , is_obj()
|
Chris@16
|
315 );
|
Chris@16
|
316 }
|
Chris@16
|
317
|
Chris@16
|
318 class object : public object_base
|
Chris@16
|
319 {
|
Chris@16
|
320 public:
|
Chris@16
|
321 // default constructor creates a None object
|
Chris@16
|
322 object();
|
Chris@16
|
323
|
Chris@16
|
324 // explicit conversion from any C++ object to Python
|
Chris@16
|
325 template <class T>
|
Chris@16
|
326 explicit object(
|
Chris@16
|
327 T const& x
|
Chris@16
|
328 # if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
Chris@16
|
329 // use some SFINAE to un-confuse MSVC about its
|
Chris@16
|
330 // copy-initialization ambiguity claim.
|
Chris@16
|
331 , typename mpl::if_<is_proxy<T>,int&,int>::type* = 0
|
Chris@16
|
332 # endif
|
Chris@16
|
333 )
|
Chris@16
|
334 : object_base(object_base_initializer(x))
|
Chris@16
|
335 {
|
Chris@16
|
336 }
|
Chris@16
|
337
|
Chris@16
|
338 // Throw error_already_set() if the handle is null.
|
Chris@16
|
339 BOOST_PYTHON_DECL explicit object(handle<> const&);
|
Chris@16
|
340 private:
|
Chris@16
|
341
|
Chris@16
|
342 public: // implementation detail -- for internal use only
|
Chris@16
|
343 explicit object(detail::borrowed_reference);
|
Chris@16
|
344 explicit object(detail::new_reference);
|
Chris@16
|
345 explicit object(detail::new_non_null_reference);
|
Chris@16
|
346 };
|
Chris@16
|
347
|
Chris@16
|
348 // Macros for forwarding constructors in classes derived from
|
Chris@16
|
349 // object. Derived classes will usually want these as an
|
Chris@16
|
350 // implementation detail
|
Chris@16
|
351 # define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \
|
Chris@16
|
352 inline explicit derived(::boost::python::detail::borrowed_reference p) \
|
Chris@16
|
353 : base(p) {} \
|
Chris@16
|
354 inline explicit derived(::boost::python::detail::new_reference p) \
|
Chris@16
|
355 : base(p) {} \
|
Chris@16
|
356 inline explicit derived(::boost::python::detail::new_non_null_reference p) \
|
Chris@16
|
357 : base(p) {}
|
Chris@16
|
358
|
Chris@16
|
359 # if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
|
Chris@16
|
360 # define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_
|
Chris@16
|
361 # else
|
Chris@16
|
362 // MSVC6 has a bug which causes an explicit template constructor to
|
Chris@16
|
363 // be preferred over an appropriate implicit conversion operator
|
Chris@16
|
364 // declared on the argument type. Normally, that would cause a
|
Chris@16
|
365 // runtime failure when using extract<T> to extract a type with a
|
Chris@16
|
366 // templated constructor. This additional constructor will turn that
|
Chris@16
|
367 // runtime failure into an ambiguity error at compile-time due to
|
Chris@16
|
368 // the lack of partial ordering, or at least a link-time error if no
|
Chris@16
|
369 // generalized template constructor is declared.
|
Chris@16
|
370 # define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived, base) \
|
Chris@16
|
371 BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \
|
Chris@16
|
372 template <class T> \
|
Chris@16
|
373 explicit derived(extract<T> const&);
|
Chris@16
|
374 # endif
|
Chris@16
|
375
|
Chris@16
|
376 //
|
Chris@16
|
377 // object_initializer -- get the handle to construct the object with,
|
Chris@16
|
378 // based on whether T is a proxy or derived from object
|
Chris@16
|
379 //
|
Chris@16
|
380 template <bool is_proxy = false, bool is_object_manager = false>
|
Chris@16
|
381 struct object_initializer_impl
|
Chris@16
|
382 {
|
Chris@16
|
383 static PyObject*
|
Chris@16
|
384 get(object const& x, mpl::true_)
|
Chris@16
|
385 {
|
Chris@16
|
386 return python::incref(x.ptr());
|
Chris@16
|
387 }
|
Chris@16
|
388
|
Chris@16
|
389 template <class T>
|
Chris@16
|
390 static PyObject*
|
Chris@16
|
391 get(T const& x, mpl::false_)
|
Chris@16
|
392 {
|
Chris@16
|
393 return python::incref(converter::arg_to_python<T>(x).get());
|
Chris@16
|
394 }
|
Chris@16
|
395 };
|
Chris@16
|
396
|
Chris@16
|
397 template <>
|
Chris@16
|
398 struct object_initializer_impl<true, false>
|
Chris@16
|
399 {
|
Chris@16
|
400 template <class Policies>
|
Chris@16
|
401 static PyObject*
|
Chris@16
|
402 get(proxy<Policies> const& x, mpl::false_)
|
Chris@16
|
403 {
|
Chris@16
|
404 return python::incref(x.operator object().ptr());
|
Chris@16
|
405 }
|
Chris@16
|
406 };
|
Chris@16
|
407
|
Chris@16
|
408 template <>
|
Chris@16
|
409 struct object_initializer_impl<false, true>
|
Chris@16
|
410 {
|
Chris@16
|
411 template <class T, class U>
|
Chris@16
|
412 static PyObject*
|
Chris@16
|
413 get(T const& x, U)
|
Chris@16
|
414 {
|
Chris@16
|
415 return python::incref(get_managed_object(x, boost::python::tag));
|
Chris@16
|
416 }
|
Chris@16
|
417 };
|
Chris@16
|
418
|
Chris@16
|
419 template <>
|
Chris@16
|
420 struct object_initializer_impl<true, true>
|
Chris@16
|
421 {}; // empty implementation should cause an error
|
Chris@16
|
422
|
Chris@16
|
423 template <class T>
|
Chris@16
|
424 struct object_initializer : object_initializer_impl<
|
Chris@16
|
425 is_proxy<T>::value
|
Chris@16
|
426 , converter::is_object_manager<T>::value
|
Chris@16
|
427 >
|
Chris@16
|
428 {};
|
Chris@16
|
429
|
Chris@16
|
430 }
|
Chris@16
|
431 using api::object;
|
Chris@16
|
432 template <class T> struct extract;
|
Chris@16
|
433
|
Chris@16
|
434 //
|
Chris@16
|
435 // implementation
|
Chris@16
|
436 //
|
Chris@16
|
437
|
Chris@16
|
438 namespace detail
|
Chris@16
|
439 {
|
Chris@16
|
440
|
Chris@16
|
441 class call_proxy
|
Chris@16
|
442 {
|
Chris@16
|
443 public:
|
Chris@16
|
444 call_proxy(object target) : m_target(target) {}
|
Chris@16
|
445 operator object() const { return m_target;}
|
Chris@16
|
446
|
Chris@16
|
447 private:
|
Chris@16
|
448 object m_target;
|
Chris@16
|
449 };
|
Chris@16
|
450
|
Chris@16
|
451 class kwds_proxy : public call_proxy
|
Chris@16
|
452 {
|
Chris@16
|
453 public:
|
Chris@16
|
454 kwds_proxy(object o = object()) : call_proxy(o) {}
|
Chris@16
|
455 };
|
Chris@16
|
456 class args_proxy : public call_proxy
|
Chris@16
|
457 {
|
Chris@16
|
458 public:
|
Chris@16
|
459 args_proxy(object o) : call_proxy(o) {}
|
Chris@16
|
460 kwds_proxy operator* () const { return kwds_proxy(*this);}
|
Chris@16
|
461 };
|
Chris@16
|
462 }
|
Chris@16
|
463
|
Chris@16
|
464 template <typename U>
|
Chris@16
|
465 detail::args_proxy api::object_operators<U>::operator* () const
|
Chris@16
|
466 {
|
Chris@16
|
467 object_cref2 x = *static_cast<U const*>(this);
|
Chris@16
|
468 return boost::python::detail::args_proxy(x);
|
Chris@16
|
469 }
|
Chris@16
|
470
|
Chris@16
|
471 template <typename U>
|
Chris@16
|
472 object api::object_operators<U>::operator()(detail::args_proxy const &args) const
|
Chris@16
|
473 {
|
Chris@16
|
474 U const& self = *static_cast<U const*>(this);
|
Chris@16
|
475 PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
|
Chris@16
|
476 args.operator object().ptr(),
|
Chris@16
|
477 0);
|
Chris@16
|
478 return object(boost::python::detail::new_reference(result));
|
Chris@16
|
479
|
Chris@16
|
480 }
|
Chris@16
|
481
|
Chris@16
|
482 template <typename U>
|
Chris@16
|
483 object api::object_operators<U>::operator()(detail::args_proxy const &args,
|
Chris@16
|
484 detail::kwds_proxy const &kwds) const
|
Chris@16
|
485 {
|
Chris@16
|
486 U const& self = *static_cast<U const*>(this);
|
Chris@16
|
487 PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
|
Chris@16
|
488 args.operator object().ptr(),
|
Chris@16
|
489 kwds.operator object().ptr());
|
Chris@16
|
490 return object(boost::python::detail::new_reference(result));
|
Chris@16
|
491
|
Chris@16
|
492 }
|
Chris@16
|
493
|
Chris@16
|
494
|
Chris@16
|
495 template <typename U>
|
Chris@16
|
496 template <class T>
|
Chris@16
|
497 object api::object_operators<U>::contains(T const& key) const
|
Chris@16
|
498 {
|
Chris@16
|
499 return this->attr("__contains__")(object(key));
|
Chris@16
|
500 }
|
Chris@16
|
501
|
Chris@16
|
502
|
Chris@16
|
503 inline object::object()
|
Chris@16
|
504 : object_base(python::incref(Py_None))
|
Chris@16
|
505 {}
|
Chris@16
|
506
|
Chris@16
|
507 // copy constructor without NULL checking, for efficiency
|
Chris@16
|
508 inline api::object_base::object_base(object_base const& rhs)
|
Chris@16
|
509 : m_ptr(python::incref(rhs.m_ptr))
|
Chris@16
|
510 {}
|
Chris@16
|
511
|
Chris@16
|
512 inline api::object_base::object_base(PyObject* p)
|
Chris@16
|
513 : m_ptr(p)
|
Chris@16
|
514 {}
|
Chris@16
|
515
|
Chris@16
|
516 inline api::object_base& api::object_base::operator=(api::object_base const& rhs)
|
Chris@16
|
517 {
|
Chris@16
|
518 Py_INCREF(rhs.m_ptr);
|
Chris@16
|
519 Py_DECREF(this->m_ptr);
|
Chris@16
|
520 this->m_ptr = rhs.m_ptr;
|
Chris@16
|
521 return *this;
|
Chris@16
|
522 }
|
Chris@16
|
523
|
Chris@16
|
524 inline api::object_base::~object_base()
|
Chris@16
|
525 {
|
Chris@16
|
526 Py_DECREF(m_ptr);
|
Chris@16
|
527 }
|
Chris@16
|
528
|
Chris@16
|
529 inline object::object(detail::borrowed_reference p)
|
Chris@16
|
530 : object_base(python::incref((PyObject*)p))
|
Chris@16
|
531 {}
|
Chris@16
|
532
|
Chris@16
|
533 inline object::object(detail::new_reference p)
|
Chris@16
|
534 : object_base(expect_non_null((PyObject*)p))
|
Chris@16
|
535 {}
|
Chris@16
|
536
|
Chris@16
|
537 inline object::object(detail::new_non_null_reference p)
|
Chris@16
|
538 : object_base((PyObject*)p)
|
Chris@16
|
539 {}
|
Chris@16
|
540
|
Chris@16
|
541 inline PyObject* api::object_base::ptr() const
|
Chris@16
|
542 {
|
Chris@16
|
543 return m_ptr;
|
Chris@16
|
544 }
|
Chris@16
|
545
|
Chris@16
|
546 inline bool api::object_base::is_none() const
|
Chris@16
|
547 {
|
Chris@16
|
548 return (m_ptr == Py_None);
|
Chris@16
|
549 }
|
Chris@16
|
550
|
Chris@16
|
551 //
|
Chris@16
|
552 // Converter specialization implementations
|
Chris@16
|
553 //
|
Chris@16
|
554 namespace converter
|
Chris@16
|
555 {
|
Chris@16
|
556 template <class T> struct object_manager_traits;
|
Chris@16
|
557
|
Chris@16
|
558 template <>
|
Chris@16
|
559 struct object_manager_traits<object>
|
Chris@16
|
560 {
|
Chris@16
|
561 BOOST_STATIC_CONSTANT(bool, is_specialized = true);
|
Chris@16
|
562 static bool check(PyObject*) { return true; }
|
Chris@16
|
563
|
Chris@16
|
564 static python::detail::new_non_null_reference adopt(PyObject* x)
|
Chris@16
|
565 {
|
Chris@16
|
566 return python::detail::new_non_null_reference(x);
|
Chris@16
|
567 }
|
Chris@16
|
568 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
Chris@16
|
569 static PyTypeObject const *get_pytype() {return 0;}
|
Chris@16
|
570 #endif
|
Chris@16
|
571 };
|
Chris@16
|
572 }
|
Chris@16
|
573
|
Chris@16
|
574 inline PyObject* get_managed_object(object const& x, tag_t)
|
Chris@16
|
575 {
|
Chris@16
|
576 return x.ptr();
|
Chris@16
|
577 }
|
Chris@16
|
578
|
Chris@16
|
579 }} // namespace boost::python
|
Chris@16
|
580
|
Chris@16
|
581 # include <boost/python/slice_nil.hpp>
|
Chris@16
|
582
|
Chris@16
|
583 #endif // OBJECT_CORE_DWA2002615_HPP
|