]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/python/include/boost/python/object_core.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / python / include / boost / python / object_core.hpp
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 OBJECT_CORE_DWA2002615_HPP
6 # define OBJECT_CORE_DWA2002615_HPP
7
8 # define BOOST_PYTHON_OBJECT_HAS_IS_NONE // added 2010-03-15 by rwgk
9
10 # include <boost/python/detail/prefix.hpp>
11
12 # include <boost/type.hpp>
13
14 # include <boost/python/call.hpp>
15 # include <boost/python/handle_fwd.hpp>
16 # include <boost/python/errors.hpp>
17 # include <boost/python/refcount.hpp>
18 # include <boost/python/detail/preprocessor.hpp>
19 # include <boost/python/tag.hpp>
20 # include <boost/python/def_visitor.hpp>
21
22 # include <boost/python/detail/raw_pyobject.hpp>
23 # include <boost/python/detail/dependent.hpp>
24
25 # include <boost/python/object/forward.hpp>
26 # include <boost/python/object/add_to_namespace.hpp>
27
28 # include <boost/preprocessor/iterate.hpp>
29 # include <boost/preprocessor/debug/line.hpp>
30
31 # include <boost/python/detail/is_xxx.hpp>
32 # include <boost/python/detail/string_literal.hpp>
33 # include <boost/python/detail/def_helper_fwd.hpp>
34
35 # include <boost/type_traits/is_same.hpp>
36 # include <boost/type_traits/is_convertible.hpp>
37 # include <boost/type_traits/remove_reference.hpp>
38
39 namespace boost { namespace python {
40
41 namespace detail
42 {
43 class kwds_proxy;
44 class args_proxy;
45 }
46
47 namespace converter
48 {
49 template <class T> struct arg_to_python;
50 }
51
52 // Put this in an inner namespace so that the generalized operators won't take over
53 namespace api
54 {
55
56 // This file contains the definition of the object class and enough to
57 // construct/copy it, but not enough to do operations like
58 // attribute/item access or addition.
59
60 template <class Policies> class proxy;
61
62 struct const_attribute_policies;
63 struct attribute_policies;
64 struct const_objattribute_policies;
65 struct objattribute_policies;
66 struct const_item_policies;
67 struct item_policies;
68 struct const_slice_policies;
69 struct slice_policies;
70 class slice_nil;
71
72 typedef proxy<const_attribute_policies> const_object_attribute;
73 typedef proxy<attribute_policies> object_attribute;
74 typedef proxy<const_objattribute_policies> const_object_objattribute;
75 typedef proxy<objattribute_policies> object_objattribute;
76 typedef proxy<const_item_policies> const_object_item;
77 typedef proxy<item_policies> object_item;
78 typedef proxy<const_slice_policies> const_object_slice;
79 typedef proxy<slice_policies> object_slice;
80
81 //
82 // is_proxy -- proxy type detection
83 //
84 BOOST_PYTHON_IS_XXX_DEF(proxy, boost::python::api::proxy, 1)
85
86 template <class T> struct object_initializer;
87
88 class object;
89 typedef PyObject* (object::*bool_type)() const;
90
91 template <class U>
92 class object_operators : public def_visitor<U>
93 {
94 protected:
95 typedef object const& object_cref;
96 public:
97 // function call
98 //
99 object operator()() const;
100
101 # define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, <boost/python/object_call.hpp>))
102 # include BOOST_PP_ITERATE()
103
104 detail::args_proxy operator* () const;
105 object operator()(detail::args_proxy const &args) const;
106 object operator()(detail::args_proxy const &args,
107 detail::kwds_proxy const &kwds) const;
108
109 // truth value testing
110 //
111 operator bool_type() const;
112 bool operator!() const; // needed for vc6
113
114 // Attribute access
115 //
116 const_object_attribute attr(char const*) const;
117 object_attribute attr(char const*);
118 const_object_objattribute attr(object const&) const;
119 object_objattribute attr(object const&);
120
121 // Wrap 'in' operator (aka. __contains__)
122 template <class T>
123 object contains(T const& key) const;
124
125 // item access
126 //
127 const_object_item operator[](object_cref) const;
128 object_item operator[](object_cref);
129
130 template <class T>
131 const_object_item
132 operator[](T const& key) const;
133
134 template <class T>
135 object_item
136 operator[](T const& key);
137
138 // slicing
139 //
140 const_object_slice slice(object_cref, object_cref) const;
141 object_slice slice(object_cref, object_cref);
142
143 const_object_slice slice(slice_nil, object_cref) const;
144 object_slice slice(slice_nil, object_cref);
145
146 const_object_slice slice(object_cref, slice_nil) const;
147 object_slice slice(object_cref, slice_nil);
148
149 const_object_slice slice(slice_nil, slice_nil) const;
150 object_slice slice(slice_nil, slice_nil);
151
152 template <class T, class V>
153 const_object_slice
154 slice(T const& start, V const& end) const;
155
156 template <class T, class V>
157 object_slice
158 slice(T const& start, V const& end);
159
160 private: // def visitation for adding callable objects as class methods
161
162 template <class ClassT, class DocStringT>
163 void visit(ClassT& cl, char const* name, python::detail::def_helper<DocStringT> const& helper) const
164 {
165 // It's too late to specify anything other than docstrings if
166 // the callable object is already wrapped.
167 BOOST_STATIC_ASSERT(
168 (is_same<char const*,DocStringT>::value
169 || detail::is_string_literal<DocStringT const>::value));
170
171 objects::add_to_namespace(cl, name, this->derived_visitor(), helper.doc());
172 }
173
174 friend class python::def_visitor_access;
175
176 private:
177 // there is a confirmed CWPro8 codegen bug here. We prevent the
178 // early destruction of a temporary by binding a named object
179 // instead.
180 # if __MWERKS__ < 0x3000 || __MWERKS__ > 0x3003
181 typedef object const& object_cref2;
182 # else
183 typedef object const object_cref2;
184 # endif
185 };
186
187
188 // VC6 and VC7 require this base class in order to generate the
189 // correct copy constructor for object. We can't define it there
190 // explicitly or it will complain of ambiguity.
191 struct object_base : object_operators<object>
192 {
193 // copy constructor without NULL checking, for efficiency.
194 inline object_base(object_base const&);
195 inline object_base(PyObject* ptr);
196
197 inline object_base& operator=(object_base const& rhs);
198 inline ~object_base();
199
200 // Underlying object access -- returns a borrowed reference
201 inline PyObject* ptr() const;
202
203 inline bool is_none() const;
204
205 private:
206 PyObject* m_ptr;
207 };
208
209 template <class T, class U>
210 struct is_derived
211 : is_convertible<
212 typename remove_reference<T>::type*
213 , U const*
214 >
215 {};
216
217 template <class T>
218 typename objects::unforward_cref<T>::type do_unforward_cref(T const& x)
219 {
220 return x;
221 }
222
223 class object;
224
225 template <class T>
226 PyObject* object_base_initializer(T const& x)
227 {
228 typedef typename is_derived<
229 BOOST_DEDUCED_TYPENAME objects::unforward_cref<T>::type
230 , object
231 >::type is_obj;
232
233 return object_initializer<
234 BOOST_DEDUCED_TYPENAME unwrap_reference<T>::type
235 >::get(
236 x
237 , is_obj()
238 );
239 }
240
241 class object : public object_base
242 {
243 public:
244 // default constructor creates a None object
245 object();
246
247 // explicit conversion from any C++ object to Python
248 template <class T>
249 explicit object(T const& x)
250 : object_base(object_base_initializer(x))
251 {
252 }
253
254 // Throw error_already_set() if the handle is null.
255 BOOST_PYTHON_DECL explicit object(handle<> const&);
256 private:
257
258 public: // implementation detail -- for internal use only
259 explicit object(detail::borrowed_reference);
260 explicit object(detail::new_reference);
261 explicit object(detail::new_non_null_reference);
262 };
263
264 // Macros for forwarding constructors in classes derived from
265 // object. Derived classes will usually want these as an
266 // implementation detail
267 # define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived, base) \
268 inline explicit derived(::boost::python::detail::borrowed_reference p) \
269 : base(p) {} \
270 inline explicit derived(::boost::python::detail::new_reference p) \
271 : base(p) {} \
272 inline explicit derived(::boost::python::detail::new_non_null_reference p) \
273 : base(p) {}
274
275 //
276 // object_initializer -- get the handle to construct the object with,
277 // based on whether T is a proxy or derived from object
278 //
279 template <bool is_proxy = false, bool is_object_manager = false>
280 struct object_initializer_impl
281 {
282 static PyObject*
283 get(object const& x, mpl::true_)
284 {
285 return python::incref(x.ptr());
286 }
287
288 template <class T>
289 static PyObject*
290 get(T const& x, mpl::false_)
291 {
292 return python::incref(converter::arg_to_python<T>(x).get());
293 }
294 };
295
296 template <>
297 struct object_initializer_impl<true, false>
298 {
299 template <class Policies>
300 static PyObject*
301 get(proxy<Policies> const& x, mpl::false_)
302 {
303 return python::incref(x.operator object().ptr());
304 }
305 };
306
307 template <>
308 struct object_initializer_impl<false, true>
309 {
310 template <class T, class U>
311 static PyObject*
312 get(T const& x, U)
313 {
314 return python::incref(get_managed_object(x, boost::python::tag));
315 }
316 };
317
318 template <>
319 struct object_initializer_impl<true, true>
320 {}; // empty implementation should cause an error
321
322 template <class T>
323 struct object_initializer : object_initializer_impl<
324 is_proxy<T>::value
325 , converter::is_object_manager<T>::value
326 >
327 {};
328
329 }
330 using api::object;
331 template <class T> struct extract;
332
333 //
334 // implementation
335 //
336
337 namespace detail
338 {
339
340 class call_proxy
341 {
342 public:
343 call_proxy(object target) : m_target(target) {}
344 operator object() const { return m_target;}
345
346 private:
347 object m_target;
348 };
349
350 class kwds_proxy : public call_proxy
351 {
352 public:
353 kwds_proxy(object o = object()) : call_proxy(o) {}
354 };
355 class args_proxy : public call_proxy
356 {
357 public:
358 args_proxy(object o) : call_proxy(o) {}
359 kwds_proxy operator* () const { return kwds_proxy(*this);}
360 };
361 }
362
363 template <typename U>
364 detail::args_proxy api::object_operators<U>::operator* () const
365 {
366 object_cref2 x = *static_cast<U const*>(this);
367 return boost::python::detail::args_proxy(x);
368 }
369
370 template <typename U>
371 object api::object_operators<U>::operator()(detail::args_proxy const &args) const
372 {
373 U const& self = *static_cast<U const*>(this);
374 PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
375 args.operator object().ptr(),
376 0);
377 return object(boost::python::detail::new_reference(result));
378
379 }
380
381 template <typename U>
382 object api::object_operators<U>::operator()(detail::args_proxy const &args,
383 detail::kwds_proxy const &kwds) const
384 {
385 U const& self = *static_cast<U const*>(this);
386 PyObject *result = PyObject_Call(get_managed_object(self, boost::python::tag),
387 args.operator object().ptr(),
388 kwds.operator object().ptr());
389 return object(boost::python::detail::new_reference(result));
390
391 }
392
393
394 template <typename U>
395 template <class T>
396 object api::object_operators<U>::contains(T const& key) const
397 {
398 return this->attr("__contains__")(object(key));
399 }
400
401
402 inline object::object()
403 : object_base(python::incref(Py_None))
404 {}
405
406 // copy constructor without NULL checking, for efficiency
407 inline api::object_base::object_base(object_base const& rhs)
408 : m_ptr(python::incref(rhs.m_ptr))
409 {}
410
411 inline api::object_base::object_base(PyObject* p)
412 : m_ptr(p)
413 {}
414
415 inline api::object_base& api::object_base::operator=(api::object_base const& rhs)
416 {
417 Py_INCREF(rhs.m_ptr);
418 Py_DECREF(this->m_ptr);
419 this->m_ptr = rhs.m_ptr;
420 return *this;
421 }
422
423 inline api::object_base::~object_base()
424 {
425 assert( Py_REFCNT(m_ptr) > 0 );
426 Py_DECREF(m_ptr);
427 }
428
429 inline object::object(detail::borrowed_reference p)
430 : object_base(python::incref((PyObject*)p))
431 {}
432
433 inline object::object(detail::new_reference p)
434 : object_base(expect_non_null((PyObject*)p))
435 {}
436
437 inline object::object(detail::new_non_null_reference p)
438 : object_base((PyObject*)p)
439 {}
440
441 inline PyObject* api::object_base::ptr() const
442 {
443 return m_ptr;
444 }
445
446 inline bool api::object_base::is_none() const
447 {
448 return (m_ptr == Py_None);
449 }
450
451 //
452 // Converter specialization implementations
453 //
454 namespace converter
455 {
456 template <class T> struct object_manager_traits;
457
458 template <>
459 struct object_manager_traits<object>
460 {
461 BOOST_STATIC_CONSTANT(bool, is_specialized = true);
462 static bool check(PyObject*) { return true; }
463
464 static python::detail::new_non_null_reference adopt(PyObject* x)
465 {
466 return python::detail::new_non_null_reference(x);
467 }
468 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
469 static PyTypeObject const *get_pytype() {return 0;}
470 #endif
471 };
472 }
473
474 inline PyObject* get_managed_object(object const& x, tag_t)
475 {
476 return x.ptr();
477 }
478
479 }} // namespace boost::python
480
481 # include <boost/python/slice_nil.hpp>
482
483 #endif // OBJECT_CORE_DWA2002615_HPP