]>
Commit | Line | Data |
---|---|---|
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 OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP | |
6 | # define OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP | |
7 | ||
8 | # include <boost/python/detail/prefix.hpp> | |
9 | # include <boost/python/detail/referent_storage.hpp> | |
10 | # include <boost/python/detail/destroy.hpp> | |
11 | # include <boost/python/detail/construct.hpp> | |
12 | # include <boost/python/converter/object_manager.hpp> | |
13 | # include <boost/python/detail/raw_pyobject.hpp> | |
14 | # include <boost/python/tag.hpp> | |
15 | ||
16 | // | |
17 | // arg_from_python converters for Python type wrappers, to be used as | |
18 | // base classes for specializations. | |
19 | // | |
20 | namespace boost { namespace python { namespace converter { | |
21 | ||
22 | template <class T> | |
23 | struct object_manager_value_arg_from_python | |
24 | { | |
25 | typedef T result_type; | |
26 | ||
27 | object_manager_value_arg_from_python(PyObject*); | |
28 | bool convertible() const; | |
29 | T operator()() const; | |
30 | private: | |
31 | PyObject* m_source; | |
32 | }; | |
33 | ||
34 | // Used for converting reference-to-object-manager arguments from | |
35 | // python. The process used here is a little bit odd. Upon | |
36 | // construction, we build the object manager object in the m_result | |
37 | // object, *forcing* it to accept the source Python object by casting | |
38 | // its pointer to detail::borrowed_reference. This is supposed to | |
39 | // bypass any type checking of the source object. The convertible | |
40 | // check then extracts the owned object and checks it. If the check | |
41 | // fails, nothing else in the program ever gets to touch this strange | |
42 | // "forced" object. | |
43 | template <class Ref> | |
44 | struct object_manager_ref_arg_from_python | |
45 | { | |
46 | typedef Ref result_type; | |
47 | ||
48 | object_manager_ref_arg_from_python(PyObject*); | |
49 | bool convertible() const; | |
50 | Ref operator()() const; | |
51 | ~object_manager_ref_arg_from_python(); | |
52 | private: | |
53 | typename python::detail::referent_storage<Ref>::type m_result; | |
54 | }; | |
55 | ||
56 | // | |
57 | // implementations | |
58 | // | |
59 | ||
60 | template <class T> | |
61 | inline object_manager_value_arg_from_python<T>::object_manager_value_arg_from_python(PyObject* x) | |
62 | : m_source(x) | |
63 | { | |
64 | } | |
65 | ||
66 | template <class T> | |
67 | inline bool object_manager_value_arg_from_python<T>::convertible() const | |
68 | { | |
69 | return object_manager_traits<T>::check(m_source); | |
70 | } | |
71 | ||
72 | template <class T> | |
73 | inline T object_manager_value_arg_from_python<T>::operator()() const | |
74 | { | |
75 | return T(python::detail::borrowed_reference(m_source)); | |
76 | } | |
77 | ||
78 | template <class Ref> | |
79 | inline object_manager_ref_arg_from_python<Ref>::object_manager_ref_arg_from_python(PyObject* x) | |
80 | { | |
81 | # if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243 | |
82 | // needed for warning suppression | |
83 | python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x); | |
1e59de90 | 84 | python::detail::construct_referent<Ref>(m_result.bytes, x_); |
7c673cae | 85 | # else |
1e59de90 | 86 | python::detail::construct_referent<Ref>(m_result.bytes, (python::detail::borrowed_reference)x); |
7c673cae FG |
87 | # endif |
88 | } | |
89 | ||
90 | template <class Ref> | |
91 | inline object_manager_ref_arg_from_python<Ref>::~object_manager_ref_arg_from_python() | |
92 | { | |
93 | python::detail::destroy_referent<Ref>(this->m_result.bytes); | |
94 | } | |
95 | ||
96 | namespace detail | |
97 | { | |
98 | template <class T> | |
99 | inline bool object_manager_ref_check(T const& x) | |
100 | { | |
101 | return object_manager_traits<T>::check(get_managed_object(x, tag)); | |
102 | } | |
103 | } | |
104 | ||
105 | template <class Ref> | |
106 | inline bool object_manager_ref_arg_from_python<Ref>::convertible() const | |
107 | { | |
108 | return detail::object_manager_ref_check( | |
109 | python::detail::void_ptr_to_reference(this->m_result.bytes, (Ref(*)())0)); | |
110 | } | |
111 | ||
112 | template <class Ref> | |
113 | inline Ref object_manager_ref_arg_from_python<Ref>::operator()() const | |
114 | { | |
115 | return python::detail::void_ptr_to_reference( | |
116 | this->m_result.bytes, (Ref(*)())0); | |
117 | } | |
118 | ||
119 | }}} // namespace boost::python::converter | |
120 | ||
121 | #endif // OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP |