163 lines
4.3 KiB
Plaintext
163 lines
4.3 KiB
Plaintext
|
// 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
|