1 // Copyright David Abrahams 2002.
2 // Copyright Stefan Seefeld 2016.
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 #ifndef boost_python_to_python_value_hpp_
8 #define boost_python_to_python_value_hpp_
10 #include <boost/python/detail/prefix.hpp>
12 #include <boost/python/refcount.hpp>
13 #include <boost/python/tag.hpp>
14 #include <boost/python/handle.hpp>
16 #include <boost/python/converter/registry.hpp>
17 #include <boost/python/converter/registered.hpp>
18 #include <boost/python/converter/builtin_converters.hpp>
19 #include <boost/python/converter/object_manager.hpp>
20 #include <boost/python/converter/shared_ptr_to_python.hpp>
22 #include <boost/python/detail/value_is_shared_ptr.hpp>
23 #include <boost/python/detail/value_arg.hpp>
25 #include <boost/type_traits/transform_traits.hpp>
27 #include <boost/mpl/if.hpp>
28 #include <boost/mpl/or.hpp>
29 #include <boost/type_traits/is_const.hpp>
31 namespace boost { namespace python {
35 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
37 template <bool is_const_ref>
38 struct object_manager_get_pytype
41 static PyTypeObject const* get( U& (*)() =0)
43 return converter::object_manager_traits<U>::get_pytype();
48 struct object_manager_get_pytype<true>
51 static PyTypeObject const* get( U const& (*)() =0)
53 return converter::object_manager_traits<U>::get_pytype();
60 struct object_manager_to_python_value
62 typedef typename value_arg<T>::type argument_type;
64 PyObject* operator()(argument_type) const;
65 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
66 typedef boost::mpl::bool_<is_handle<T>::value> is_t_handle;
67 typedef boost::detail::indirect_traits::is_reference_to_const<T> is_t_const;
68 PyTypeObject const* get_pytype() const {
69 return get_pytype_aux((is_t_handle*)0);
72 inline static PyTypeObject const* get_pytype_aux(mpl::true_*) {return converter::object_manager_traits<T>::get_pytype();}
74 inline static PyTypeObject const* get_pytype_aux(mpl::false_* )
76 return object_manager_get_pytype<is_t_const::value>::get((T(*)())0);
81 // This information helps make_getter() decide whether to try to
82 // return an internal reference or not. I don't like it much,
83 // but it will have to serve for now.
84 BOOST_STATIC_CONSTANT(bool, uses_registry = false);
89 struct registry_to_python_value
91 typedef typename value_arg<T>::type argument_type;
93 PyObject* operator()(argument_type) const;
94 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
95 PyTypeObject const* get_pytype() const {return converter::registered<T>::converters.to_python_target_type();}
98 // This information helps make_getter() decide whether to try to
99 // return an internal reference or not. I don't like it much,
100 // but it will have to serve for now.
101 BOOST_STATIC_CONSTANT(bool, uses_registry = true);
105 struct shared_ptr_to_python_value
107 typedef typename value_arg<T>::type argument_type;
109 PyObject* operator()(argument_type) const;
110 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
111 PyTypeObject const* get_pytype() const {return get_pytype((boost::type<argument_type>*)0);}
113 // This information helps make_getter() decide whether to try to
114 // return an internal reference or not. I don't like it much,
115 // but it will have to serve for now.
116 BOOST_STATIC_CONSTANT(bool, uses_registry = false);
118 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
120 PyTypeObject const* get_pytype(boost::type<shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
122 PyTypeObject const* get_pytype(boost::type<const shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
123 # if __cplusplus >= 201103L
125 PyTypeObject const* get_pytype(boost::type<std::shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
127 PyTypeObject const* get_pytype(boost::type<const std::shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
134 struct to_python_value
136 detail::value_is_shared_ptr<T>
137 , detail::shared_ptr_to_python_value<T>
140 converter::is_object_manager<T>
141 , converter::is_reference_to_object_manager<T>
143 , detail::object_manager_to_python_value<T>
144 , detail::registry_to_python_value<T>
156 inline PyObject* registry_to_python_value<T>::operator()(argument_type x) const
158 return converter::registered<argument_type>::converters.to_python(&x);
162 inline PyObject* object_manager_to_python_value<T>::operator()(argument_type x) const
164 return python::upcast<PyObject>(
166 get_managed_object(x, tag))
171 inline PyObject* shared_ptr_to_python_value<T>::operator()(argument_type x) const
173 return converter::shared_ptr_to_python(x);
177 }} // namespace boost::python