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 TO_PYTHON_VALUE_DWA200221_HPP
|
Chris@16
|
6 # define TO_PYTHON_VALUE_DWA200221_HPP
|
Chris@16
|
7
|
Chris@16
|
8 # include <boost/python/detail/prefix.hpp>
|
Chris@16
|
9
|
Chris@16
|
10 # include <boost/python/refcount.hpp>
|
Chris@16
|
11 # include <boost/python/tag.hpp>
|
Chris@16
|
12 # include <boost/python/handle.hpp>
|
Chris@16
|
13
|
Chris@16
|
14 # include <boost/python/converter/registry.hpp>
|
Chris@16
|
15 # include <boost/python/converter/registered.hpp>
|
Chris@16
|
16 # include <boost/python/converter/builtin_converters.hpp>
|
Chris@16
|
17 # include <boost/python/converter/object_manager.hpp>
|
Chris@16
|
18 # include <boost/python/converter/shared_ptr_to_python.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 # include <boost/python/detail/value_is_shared_ptr.hpp>
|
Chris@16
|
21 # include <boost/python/detail/value_arg.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 # include <boost/type_traits/transform_traits.hpp>
|
Chris@16
|
24
|
Chris@16
|
25 # include <boost/mpl/if.hpp>
|
Chris@16
|
26 # include <boost/mpl/or.hpp>
|
Chris@16
|
27 # include <boost/type_traits/is_const.hpp>
|
Chris@16
|
28
|
Chris@16
|
29 namespace boost { namespace python {
|
Chris@16
|
30
|
Chris@16
|
31 namespace detail
|
Chris@16
|
32 {
|
Chris@16
|
33 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
Chris@16
|
34
|
Chris@16
|
35 template <bool is_const_ref>
|
Chris@16
|
36 struct object_manager_get_pytype
|
Chris@16
|
37 {
|
Chris@16
|
38 template <class U>
|
Chris@16
|
39 static PyTypeObject const* get( U& (*)() =0)
|
Chris@16
|
40 {
|
Chris@16
|
41 return converter::object_manager_traits<U>::get_pytype();
|
Chris@16
|
42 }
|
Chris@16
|
43 };
|
Chris@16
|
44
|
Chris@16
|
45 template <>
|
Chris@16
|
46 struct object_manager_get_pytype<true>
|
Chris@16
|
47 {
|
Chris@16
|
48 template <class U>
|
Chris@16
|
49 static PyTypeObject const* get( U const& (*)() =0)
|
Chris@16
|
50 {
|
Chris@16
|
51 return converter::object_manager_traits<U>::get_pytype();
|
Chris@16
|
52 }
|
Chris@16
|
53 };
|
Chris@16
|
54
|
Chris@16
|
55 #endif
|
Chris@16
|
56
|
Chris@16
|
57 template <class T>
|
Chris@16
|
58 struct object_manager_to_python_value
|
Chris@16
|
59 {
|
Chris@16
|
60 typedef typename value_arg<T>::type argument_type;
|
Chris@16
|
61
|
Chris@16
|
62 PyObject* operator()(argument_type) const;
|
Chris@16
|
63 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
Chris@16
|
64 typedef boost::mpl::bool_<is_handle<T>::value> is_t_handle;
|
Chris@16
|
65 typedef boost::detail::indirect_traits::is_reference_to_const<T> is_t_const;
|
Chris@16
|
66 PyTypeObject const* get_pytype() const {
|
Chris@16
|
67 return get_pytype_aux((is_t_handle*)0);
|
Chris@16
|
68 }
|
Chris@16
|
69
|
Chris@16
|
70 inline static PyTypeObject const* get_pytype_aux(mpl::true_*) {return converter::object_manager_traits<T>::get_pytype();}
|
Chris@16
|
71
|
Chris@16
|
72 inline static PyTypeObject const* get_pytype_aux(mpl::false_* )
|
Chris@16
|
73 {
|
Chris@16
|
74 return object_manager_get_pytype<is_t_const::value>::get((T(*)())0);
|
Chris@16
|
75 }
|
Chris@16
|
76
|
Chris@16
|
77 #endif
|
Chris@16
|
78
|
Chris@16
|
79 // This information helps make_getter() decide whether to try to
|
Chris@16
|
80 // return an internal reference or not. I don't like it much,
|
Chris@16
|
81 // but it will have to serve for now.
|
Chris@16
|
82 BOOST_STATIC_CONSTANT(bool, uses_registry = false);
|
Chris@16
|
83 };
|
Chris@16
|
84
|
Chris@16
|
85
|
Chris@16
|
86 template <class T>
|
Chris@16
|
87 struct registry_to_python_value
|
Chris@16
|
88 {
|
Chris@16
|
89 typedef typename value_arg<T>::type argument_type;
|
Chris@16
|
90
|
Chris@16
|
91 PyObject* operator()(argument_type) const;
|
Chris@16
|
92 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
Chris@16
|
93 PyTypeObject const* get_pytype() const {return converter::registered<T>::converters.to_python_target_type();}
|
Chris@16
|
94 #endif
|
Chris@16
|
95
|
Chris@16
|
96 // This information helps make_getter() decide whether to try to
|
Chris@16
|
97 // return an internal reference or not. I don't like it much,
|
Chris@16
|
98 // but it will have to serve for now.
|
Chris@16
|
99 BOOST_STATIC_CONSTANT(bool, uses_registry = true);
|
Chris@16
|
100 };
|
Chris@16
|
101
|
Chris@16
|
102 template <class T>
|
Chris@16
|
103 struct shared_ptr_to_python_value
|
Chris@16
|
104 {
|
Chris@16
|
105 typedef typename value_arg<T>::type argument_type;
|
Chris@16
|
106
|
Chris@16
|
107 PyObject* operator()(argument_type) const;
|
Chris@16
|
108 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
Chris@16
|
109 PyTypeObject const* get_pytype() const {return get_pytype((boost::type<argument_type>*)0);}
|
Chris@16
|
110 #endif
|
Chris@16
|
111 // This information helps make_getter() decide whether to try to
|
Chris@16
|
112 // return an internal reference or not. I don't like it much,
|
Chris@16
|
113 // but it will have to serve for now.
|
Chris@16
|
114 BOOST_STATIC_CONSTANT(bool, uses_registry = false);
|
Chris@16
|
115 private:
|
Chris@16
|
116 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
Chris@16
|
117 template <class U>
|
Chris@16
|
118 PyTypeObject const* get_pytype(boost::type<shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
|
Chris@16
|
119 template <class U>
|
Chris@16
|
120 PyTypeObject const* get_pytype(boost::type<const shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
|
Chris@16
|
121 #endif
|
Chris@16
|
122 };
|
Chris@16
|
123 }
|
Chris@16
|
124
|
Chris@16
|
125 template <class T>
|
Chris@16
|
126 struct to_python_value
|
Chris@16
|
127 : mpl::if_<
|
Chris@16
|
128 detail::value_is_shared_ptr<T>
|
Chris@16
|
129 , detail::shared_ptr_to_python_value<T>
|
Chris@16
|
130 , typename mpl::if_<
|
Chris@16
|
131 mpl::or_<
|
Chris@16
|
132 converter::is_object_manager<T>
|
Chris@16
|
133 , converter::is_reference_to_object_manager<T>
|
Chris@16
|
134 >
|
Chris@16
|
135 , detail::object_manager_to_python_value<T>
|
Chris@16
|
136 , detail::registry_to_python_value<T>
|
Chris@16
|
137 >::type
|
Chris@16
|
138 >::type
|
Chris@16
|
139 {
|
Chris@16
|
140 };
|
Chris@16
|
141
|
Chris@16
|
142 //
|
Chris@16
|
143 // implementation
|
Chris@16
|
144 //
|
Chris@16
|
145 namespace detail
|
Chris@16
|
146 {
|
Chris@16
|
147 template <class T>
|
Chris@16
|
148 inline PyObject* registry_to_python_value<T>::operator()(argument_type x) const
|
Chris@16
|
149 {
|
Chris@16
|
150 typedef converter::registered<argument_type> r;
|
Chris@16
|
151 # if BOOST_WORKAROUND(__GNUC__, < 3)
|
Chris@16
|
152 // suppresses an ICE, somehow
|
Chris@16
|
153 (void)r::converters;
|
Chris@16
|
154 # endif
|
Chris@16
|
155 return converter::registered<argument_type>::converters.to_python(&x);
|
Chris@16
|
156 }
|
Chris@16
|
157
|
Chris@16
|
158 template <class T>
|
Chris@16
|
159 inline PyObject* object_manager_to_python_value<T>::operator()(argument_type x) const
|
Chris@16
|
160 {
|
Chris@16
|
161 return python::upcast<PyObject>(
|
Chris@16
|
162 python::xincref(
|
Chris@16
|
163 get_managed_object(x, tag))
|
Chris@16
|
164 );
|
Chris@16
|
165 }
|
Chris@16
|
166
|
Chris@16
|
167 template <class T>
|
Chris@16
|
168 inline PyObject* shared_ptr_to_python_value<T>::operator()(argument_type x) const
|
Chris@16
|
169 {
|
Chris@16
|
170 return converter::shared_ptr_to_python(x);
|
Chris@16
|
171 }
|
Chris@16
|
172 }
|
Chris@16
|
173
|
Chris@16
|
174 }} // namespace boost::python
|
Chris@16
|
175
|
Chris@16
|
176 #endif // TO_PYTHON_VALUE_DWA200221_HPP
|