// Copyright David Abrahams 2002. | |
// Distributed under the Boost Software License, Version 1.0. (See | |
// accompanying file LICENSE_1_0.txt or copy at | |
// http://www.boost.org/LICENSE_1_0.txt) | |
#ifndef RETURN_FROM_PYTHON_DWA200265_HPP | |
# define RETURN_FROM_PYTHON_DWA200265_HPP | |
# include <boost/python/converter/from_python.hpp> | |
# include <boost/python/converter/rvalue_from_python_data.hpp> | |
# include <boost/python/converter/registered.hpp> | |
# include <boost/python/converter/registered_pointee.hpp> | |
# include <boost/python/converter/object_manager.hpp> | |
# include <boost/python/detail/void_ptr.hpp> | |
# include <boost/python/detail/void_return.hpp> | |
# include <boost/python/errors.hpp> | |
# include <boost/python/handle.hpp> | |
# include <boost/type_traits/has_trivial_copy.hpp> | |
# include <boost/mpl/and.hpp> | |
# include <boost/mpl/bool.hpp> | |
namespace boost { namespace python { namespace converter { | |
template <class T> struct is_object_manager; | |
namespace detail | |
{ | |
template <class T> | |
struct return_pointer_from_python | |
{ | |
typedef T result_type; | |
T operator()(PyObject*) const; | |
}; | |
template <class T> | |
struct return_reference_from_python | |
{ | |
typedef T result_type; | |
T operator()(PyObject*) const; | |
}; | |
template <class T> | |
struct return_rvalue_from_python | |
{ | |
typedef T result_type; | |
return_rvalue_from_python(); | |
result_type operator()(PyObject*); | |
private: | |
rvalue_from_python_data<T> m_data; | |
}; | |
template <class T> | |
struct return_object_manager_from_python | |
{ | |
typedef T result_type; | |
result_type operator()(PyObject*) const; | |
}; | |
template <class T> | |
struct select_return_from_python | |
{ | |
BOOST_STATIC_CONSTANT( | |
bool, obj_mgr = is_object_manager<T>::value); | |
BOOST_STATIC_CONSTANT( | |
bool, ptr = is_pointer<T>::value); | |
BOOST_STATIC_CONSTANT( | |
bool, ref = is_reference<T>::value); | |
typedef typename mpl::if_c< | |
obj_mgr | |
, return_object_manager_from_python<T> | |
, typename mpl::if_c< | |
ptr | |
, return_pointer_from_python<T> | |
, typename mpl::if_c< | |
ref | |
, return_reference_from_python<T> | |
, return_rvalue_from_python<T> | |
>::type | |
>::type | |
>::type type; | |
}; | |
} | |
template <class T> | |
struct return_from_python | |
: detail::select_return_from_python<T>::type | |
{ | |
}; | |
// Specialization as a convenience for call and call_method | |
template <> | |
struct return_from_python<void> | |
{ | |
typedef python::detail::returnable<void>::type result_type; | |
result_type operator()(PyObject* x) const | |
{ | |
(void_result_from_python)(x); | |
# ifdef BOOST_NO_VOID_RETURNS | |
return result_type(); | |
# endif | |
} | |
}; | |
// | |
// Implementations | |
// | |
namespace detail | |
{ | |
template <class T> | |
inline return_rvalue_from_python<T>::return_rvalue_from_python() | |
: m_data( | |
const_cast<registration*>(®istered<T>::converters) | |
) | |
{ | |
} | |
template <class T> | |
inline typename return_rvalue_from_python<T>::result_type | |
return_rvalue_from_python<T>::operator()(PyObject* obj) | |
{ | |
// Take possession of the source object here. If the result is in | |
// fact going to be a copy of an lvalue embedded in the object, | |
// and we take possession inside rvalue_result_from_python, it | |
// will be destroyed too early. | |
handle<> holder(obj); | |
return *(T*) | |
(rvalue_result_from_python)(obj, m_data.stage1); | |
} | |
template <class T> | |
inline T return_reference_from_python<T>::operator()(PyObject* obj) const | |
{ | |
return python::detail::void_ptr_to_reference( | |
(reference_result_from_python)(obj, registered<T>::converters) | |
, (T(*)())0); | |
} | |
template <class T> | |
inline T return_pointer_from_python<T>::operator()(PyObject* obj) const | |
{ | |
return T( | |
(pointer_result_from_python)(obj, registered_pointee<T>::converters) | |
); | |
} | |
template <class T> | |
inline T return_object_manager_from_python<T>::operator()(PyObject* obj) const | |
{ | |
return T( | |
object_manager_traits<T>::adopt(expect_non_null(obj)) | |
); | |
} | |
} | |
}}} // namespace boost::python::converter | |
#endif // RETURN_FROM_PYTHON_DWA200265_HPP |