[857] | 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 RETURN_FROM_PYTHON_DWA200265_HPP
|
---|
| 6 | # define RETURN_FROM_PYTHON_DWA200265_HPP
|
---|
| 7 |
|
---|
| 8 | # include <boost/python/converter/from_python.hpp>
|
---|
| 9 | # include <boost/python/converter/rvalue_from_python_data.hpp>
|
---|
| 10 | # include <boost/python/converter/registered.hpp>
|
---|
| 11 | # include <boost/python/converter/registered_pointee.hpp>
|
---|
| 12 | # include <boost/python/converter/object_manager.hpp>
|
---|
| 13 | # include <boost/python/detail/void_ptr.hpp>
|
---|
| 14 | # include <boost/python/detail/void_return.hpp>
|
---|
| 15 | # include <boost/python/errors.hpp>
|
---|
| 16 | # include <boost/python/handle.hpp>
|
---|
| 17 | # include <boost/type_traits/has_trivial_copy.hpp>
|
---|
| 18 | # include <boost/mpl/and.hpp>
|
---|
| 19 | # include <boost/mpl/bool.hpp>
|
---|
| 20 |
|
---|
| 21 | namespace boost { namespace python { namespace converter {
|
---|
| 22 |
|
---|
| 23 | template <class T> struct is_object_manager;
|
---|
| 24 |
|
---|
| 25 | namespace detail
|
---|
| 26 | {
|
---|
| 27 | template <class T>
|
---|
| 28 | struct return_pointer_from_python
|
---|
| 29 | {
|
---|
| 30 | typedef T result_type;
|
---|
| 31 | T operator()(PyObject*) const;
|
---|
| 32 | };
|
---|
| 33 |
|
---|
| 34 | template <class T>
|
---|
| 35 | struct return_reference_from_python
|
---|
| 36 | {
|
---|
| 37 | typedef T result_type;
|
---|
| 38 | T operator()(PyObject*) const;
|
---|
| 39 | };
|
---|
| 40 |
|
---|
| 41 | template <class T>
|
---|
| 42 | struct return_rvalue_from_python
|
---|
| 43 | {
|
---|
| 44 | typedef T result_type;
|
---|
| 45 |
|
---|
| 46 | return_rvalue_from_python();
|
---|
| 47 | result_type operator()(PyObject*);
|
---|
| 48 | private:
|
---|
| 49 | rvalue_from_python_data<T> m_data;
|
---|
| 50 | };
|
---|
| 51 |
|
---|
| 52 | template <class T>
|
---|
| 53 | struct return_object_manager_from_python
|
---|
| 54 | {
|
---|
| 55 | typedef T result_type;
|
---|
| 56 | result_type operator()(PyObject*) const;
|
---|
| 57 | };
|
---|
| 58 |
|
---|
| 59 | template <class T>
|
---|
| 60 | struct select_return_from_python
|
---|
| 61 | {
|
---|
| 62 | BOOST_STATIC_CONSTANT(
|
---|
| 63 | bool, obj_mgr = is_object_manager<T>::value);
|
---|
| 64 |
|
---|
| 65 | BOOST_STATIC_CONSTANT(
|
---|
| 66 | bool, ptr = is_pointer<T>::value);
|
---|
| 67 |
|
---|
| 68 | BOOST_STATIC_CONSTANT(
|
---|
| 69 | bool, ref = is_reference<T>::value);
|
---|
| 70 |
|
---|
| 71 | typedef typename mpl::if_c<
|
---|
| 72 | obj_mgr
|
---|
| 73 | , return_object_manager_from_python<T>
|
---|
| 74 | , typename mpl::if_c<
|
---|
| 75 | ptr
|
---|
| 76 | , return_pointer_from_python<T>
|
---|
| 77 | , typename mpl::if_c<
|
---|
| 78 | ref
|
---|
| 79 | , return_reference_from_python<T>
|
---|
| 80 | , return_rvalue_from_python<T>
|
---|
| 81 | >::type
|
---|
| 82 | >::type
|
---|
| 83 | >::type type;
|
---|
| 84 | };
|
---|
| 85 | }
|
---|
| 86 |
|
---|
| 87 | template <class T>
|
---|
| 88 | struct return_from_python
|
---|
| 89 | : detail::select_return_from_python<T>::type
|
---|
| 90 | {
|
---|
| 91 | };
|
---|
| 92 |
|
---|
| 93 | // Specialization as a convenience for call and call_method
|
---|
| 94 | template <>
|
---|
| 95 | struct return_from_python<void>
|
---|
| 96 | {
|
---|
| 97 | typedef python::detail::returnable<void>::type result_type;
|
---|
| 98 |
|
---|
| 99 | result_type operator()(PyObject* x) const
|
---|
| 100 | {
|
---|
| 101 | (void_result_from_python)(x);
|
---|
| 102 | # ifdef BOOST_NO_VOID_RETURNS
|
---|
| 103 | return result_type();
|
---|
| 104 | # endif
|
---|
| 105 | }
|
---|
| 106 | };
|
---|
| 107 |
|
---|
| 108 | //
|
---|
| 109 | // Implementations
|
---|
| 110 | //
|
---|
| 111 | namespace detail
|
---|
| 112 | {
|
---|
| 113 | template <class T>
|
---|
| 114 | inline return_rvalue_from_python<T>::return_rvalue_from_python()
|
---|
| 115 | : m_data(
|
---|
| 116 | const_cast<registration*>(®istered<T>::converters)
|
---|
| 117 | )
|
---|
| 118 | {
|
---|
| 119 | }
|
---|
| 120 |
|
---|
| 121 | template <class T>
|
---|
| 122 | inline typename return_rvalue_from_python<T>::result_type
|
---|
| 123 | return_rvalue_from_python<T>::operator()(PyObject* obj)
|
---|
| 124 | {
|
---|
| 125 | // Take possession of the source object here. If the result is in
|
---|
| 126 | // fact going to be a copy of an lvalue embedded in the object,
|
---|
| 127 | // and we take possession inside rvalue_result_from_python, it
|
---|
| 128 | // will be destroyed too early.
|
---|
| 129 | handle<> holder(obj);
|
---|
| 130 |
|
---|
| 131 | return *(T*)
|
---|
| 132 | (rvalue_result_from_python)(obj, m_data.stage1);
|
---|
| 133 | }
|
---|
| 134 |
|
---|
| 135 | template <class T>
|
---|
| 136 | inline T return_reference_from_python<T>::operator()(PyObject* obj) const
|
---|
| 137 | {
|
---|
| 138 | return python::detail::void_ptr_to_reference(
|
---|
| 139 | (reference_result_from_python)(obj, registered<T>::converters)
|
---|
| 140 | , (T(*)())0);
|
---|
| 141 | }
|
---|
| 142 |
|
---|
| 143 | template <class T>
|
---|
| 144 | inline T return_pointer_from_python<T>::operator()(PyObject* obj) const
|
---|
| 145 | {
|
---|
| 146 | return T(
|
---|
| 147 | (pointer_result_from_python)(obj, registered_pointee<T>::converters)
|
---|
| 148 | );
|
---|
| 149 | }
|
---|
| 150 |
|
---|
| 151 | template <class T>
|
---|
| 152 | inline T return_object_manager_from_python<T>::operator()(PyObject* obj) const
|
---|
| 153 | {
|
---|
| 154 | return T(
|
---|
| 155 | object_manager_traits<T>::adopt(expect_non_null(obj))
|
---|
| 156 | );
|
---|
| 157 | }
|
---|
| 158 | }
|
---|
| 159 |
|
---|
| 160 | }}} // namespace boost::python::converter
|
---|
| 161 |
|
---|
| 162 | #endif // RETURN_FROM_PYTHON_DWA200265_HPP
|
---|