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/python/detail/type_traits.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 operator ()boost::python::converter::return_from_python99 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> return_rvalue_from_python()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 operator ()(PyObject * obj)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> operator ()(PyObject * obj) const136 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> operator ()(PyObject * obj) const144 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> operator ()(PyObject * obj) const152 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 163