]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/python/include/boost/python/converter/object_manager.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / python / include / boost / python / converter / object_manager.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_MANAGER_DWA2002614_HPP
6 # define OBJECT_MANAGER_DWA2002614_HPP
7
8 # include <boost/python/handle.hpp>
9 # include <boost/python/cast.hpp>
10 # include <boost/python/converter/pyobject_traits.hpp>
11 # include <boost/type_traits/object_traits.hpp>
12 # include <boost/mpl/if.hpp>
13 # include <boost/python/detail/indirect_traits.hpp>
14 # include <boost/mpl/bool.hpp>
15
16 // Facilities for dealing with types which always manage Python
17 // objects. Some examples are object, list, str, et. al. Different
18 // to_python/from_python conversion rules apply here because in
19 // contrast to other types which are typically embedded inside a
20 // Python object, these are wrapped around a Python object. For most
21 // object managers T, a C++ non-const T reference argument does not
22 // imply the existence of a T lvalue embedded in the corresponding
23 // Python argument, since mutating member functions on T actually only
24 // modify the held Python object.
25 //
26 // handle<T> is an object manager, though strictly speaking it should
27 // not be. In other words, even though mutating member functions of
28 // hanlde<T> actually modify the handle<T> and not the T object,
29 // handle<T>& arguments of wrapped functions will bind to "rvalues"
30 // wrapping the actual Python argument, just as with other object
31 // manager classes. Making an exception for handle<T> is simply not
32 // worth the trouble.
33 //
34 // borrowed<T> cv* is an object manager so that we can use the general
35 // to_python mechanisms to convert raw Python object pointers to
36 // python, without the usual semantic problems of using raw pointers.
37
38
39 // Object Manager Concept requirements:
40 //
41 // T is an Object Manager
42 // p is a PyObject*
43 // x is a T
44 //
45 // * object_manager_traits<T>::is_specialized == true
46 //
47 // * T(detail::borrowed_reference(p))
48 // Manages p without checking its type
49 //
50 // * get_managed_object(x, boost::python::tag)
51 // Convertible to PyObject*
52 //
53 // Additional requirements if T can be converted from_python:
54 //
55 // * T(object_manager_traits<T>::adopt(p))
56 // steals a reference to p, or throws a TypeError exception if
57 // p doesn't have an appropriate type. May assume p is non-null
58 //
59 // * X::check(p)
60 // convertible to bool. True iff T(X::construct(p)) will not
61 // throw.
62
63 // Forward declarations
64 //
65 namespace boost { namespace python
66 {
67 namespace api
68 {
69 class object;
70 }
71 }}
72
73 namespace boost { namespace python { namespace converter {
74
75
76 // Specializations for handle<T>
77 template <class T>
78 struct handle_object_manager_traits
79 : pyobject_traits<typename T::element_type>
80 {
81 private:
82 typedef pyobject_traits<typename T::element_type> base;
83
84 public:
85 BOOST_STATIC_CONSTANT(bool, is_specialized = true);
86
87 // Initialize with a null_ok pointer for efficiency, bypassing the
88 // null check since the source is always non-null.
89 static null_ok<typename T::element_type>* adopt(PyObject* p)
90 {
91 return python::allow_null(base::checked_downcast(p));
92 }
93 };
94
95 template <class T>
96 struct default_object_manager_traits
97 {
98 BOOST_STATIC_CONSTANT(
99 bool, is_specialized = python::detail::is_borrowed_ptr<T>::value
100 );
101 };
102
103 template <class T>
104 struct object_manager_traits
105 : mpl::if_c<
106 is_handle<T>::value
107 , handle_object_manager_traits<T>
108 , default_object_manager_traits<T>
109 >::type
110 {
111 };
112
113 //
114 // Traits for detecting whether a type is an object manager or a
115 // (cv-qualified) reference to an object manager.
116 //
117
118 template <class T>
119 struct is_object_manager
120 : mpl::bool_<object_manager_traits<T>::is_specialized>
121 {
122 };
123
124 template <class T>
125 struct is_reference_to_object_manager
126 : mpl::false_
127 {
128 };
129
130 template <class T>
131 struct is_reference_to_object_manager<T&>
132 : is_object_manager<T>
133 {
134 };
135
136 template <class T>
137 struct is_reference_to_object_manager<T const&>
138 : is_object_manager<T>
139 {
140 };
141
142 template <class T>
143 struct is_reference_to_object_manager<T volatile&>
144 : is_object_manager<T>
145 {
146 };
147
148 template <class T>
149 struct is_reference_to_object_manager<T const volatile&>
150 : is_object_manager<T>
151 {
152 };
153
154 }}} // namespace boost::python::converter
155
156 #endif // OBJECT_MANAGER_DWA2002614_HPP