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

source code of boost/boost/python/to_python_value.hpp