]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/python/include/boost/python/converter/object_manager.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / python / include / boost / python / converter / object_manager.hpp
CommitLineData
7c673cae
FG
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//
65namespace boost { namespace python
66{
67 namespace api
68 {
69 class object;
70 }
71}}
72
73namespace boost { namespace python { namespace converter {
74
75
76// Specializations for handle<T>
77template <class T>
78struct 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
95template <class T>
96struct default_object_manager_traits
97{
98 BOOST_STATIC_CONSTANT(
99 bool, is_specialized = python::detail::is_borrowed_ptr<T>::value
100 );
101};
102
103template <class T>
104struct 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
118template <class T>
119struct is_object_manager
120 : mpl::bool_<object_manager_traits<T>::is_specialized>
121{
122};
123
124template <class T>
125struct is_reference_to_object_manager
126 : mpl::false_
127{
128};
129
130template <class T>
131struct is_reference_to_object_manager<T&>
132 : is_object_manager<T>
133{
134};
135
136template <class T>
137struct is_reference_to_object_manager<T const&>
138 : is_object_manager<T>
139{
140};
141
142template <class T>
143struct is_reference_to_object_manager<T volatile&>
144 : is_object_manager<T>
145{
146};
147
148template <class T>
149struct 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