// 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 ARG_TO_PYTHON_DWA200265_HPP | |
# define ARG_TO_PYTHON_DWA200265_HPP | |
# include <boost/python/ptr.hpp> | |
# include <boost/python/tag.hpp> | |
# include <boost/python/to_python_indirect.hpp> | |
# include <boost/python/converter/registered.hpp> | |
# include <boost/python/converter/registered_pointee.hpp> | |
# include <boost/python/converter/arg_to_python_base.hpp> | |
# include <boost/python/converter/shared_ptr_to_python.hpp> | |
// Bring in specializations | |
# include <boost/python/converter/builtin_converters.hpp> | |
# include <boost/python/object/function_handle.hpp> | |
# include <boost/python/base_type_traits.hpp> | |
# include <boost/python/detail/indirect_traits.hpp> | |
# include <boost/python/detail/convertible.hpp> | |
# include <boost/python/detail/string_literal.hpp> | |
# include <boost/python/detail/value_is_shared_ptr.hpp> | |
# include <boost/type_traits/cv_traits.hpp> | |
# include <boost/type_traits/composite_traits.hpp> | |
# include <boost/type_traits/function_traits.hpp> | |
# include <boost/mpl/or.hpp> | |
namespace boost { namespace python { namespace converter { | |
template <class T> struct is_object_manager; | |
namespace detail | |
{ | |
template <class T> | |
struct function_arg_to_python : handle<> | |
{ | |
function_arg_to_python(T const& x); | |
}; | |
template <class T> | |
struct reference_arg_to_python : handle<> | |
{ | |
reference_arg_to_python(T& x); | |
private: | |
static PyObject* get_object(T& x); | |
}; | |
template <class T> | |
struct shared_ptr_arg_to_python : handle<> | |
{ | |
shared_ptr_arg_to_python(T const& x); | |
private: | |
static PyObject* get_object(T& x); | |
}; | |
template <class T> | |
struct value_arg_to_python : arg_to_python_base | |
{ | |
// Throw an exception if the conversion can't succeed | |
value_arg_to_python(T const&); | |
}; | |
template <class Ptr> | |
struct pointer_deep_arg_to_python : arg_to_python_base | |
{ | |
// Throw an exception if the conversion can't succeed | |
pointer_deep_arg_to_python(Ptr); | |
}; | |
template <class Ptr> | |
struct pointer_shallow_arg_to_python : handle<> | |
{ | |
// Throw an exception if the conversion can't succeed | |
pointer_shallow_arg_to_python(Ptr); | |
private: | |
static PyObject* get_object(Ptr p); | |
}; | |
// Convert types that manage a Python object to_python | |
template <class T> | |
struct object_manager_arg_to_python | |
{ | |
object_manager_arg_to_python(T const& x) : m_src(x) {} | |
PyObject* get() const | |
{ | |
return python::upcast<PyObject>(get_managed_object(m_src, tag)); | |
} | |
private: | |
T const& m_src; | |
}; | |
template <class T> | |
struct select_arg_to_python | |
{ | |
typedef typename unwrap_reference<T>::type unwrapped_referent; | |
typedef typename unwrap_pointer<T>::type unwrapped_ptr; | |
typedef typename mpl::if_< | |
// Special handling for char const[N]; interpret them as char | |
// const* for the sake of conversion | |
python::detail::is_string_literal<T const> | |
, arg_to_python<char const*> | |
, typename mpl::if_< | |
python::detail::value_is_shared_ptr<T> | |
, shared_ptr_arg_to_python<T> | |
, typename mpl::if_< | |
mpl::or_< | |
is_function<T> | |
, indirect_traits::is_pointer_to_function<T> | |
, is_member_function_pointer<T> | |
> | |
, function_arg_to_python<T> | |
, typename mpl::if_< | |
is_object_manager<T> | |
, object_manager_arg_to_python<T> | |
, typename mpl::if_< | |
is_pointer<T> | |
, pointer_deep_arg_to_python<T> | |
, typename mpl::if_< | |
is_pointer_wrapper<T> | |
, pointer_shallow_arg_to_python<unwrapped_ptr> | |
, typename mpl::if_< | |
is_reference_wrapper<T> | |
, reference_arg_to_python<unwrapped_referent> | |
, value_arg_to_python<T> | |
>::type | |
>::type | |
>::type | |
>::type | |
>::type | |
>::type | |
>::type | |
type; | |
}; | |
} | |
template <class T> | |
struct arg_to_python | |
: detail::select_arg_to_python<T>::type | |
{ | |
typedef typename detail::select_arg_to_python<T>::type base; | |
public: // member functions | |
// Throw an exception if the conversion can't succeed | |
arg_to_python(T const& x); | |
}; | |
// | |
// implementations | |
// | |
namespace detail | |
{ | |
// reject_raw_object_ptr -- cause a compile-time error if the user | |
// should pass a raw Python object pointer | |
using python::detail::yes_convertible; | |
using python::detail::no_convertible; | |
using python::detail::unspecialized; | |
template <class T> struct cannot_convert_raw_PyObject; | |
template <class T, class Convertibility> | |
struct reject_raw_object_helper | |
{ | |
static void error(Convertibility) | |
{ | |
cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead(); | |
} | |
static void error(...) {} | |
}; | |
template <class T> | |
inline void reject_raw_object_ptr(T*) | |
{ | |
reject_raw_object_helper<T,yes_convertible>::error( | |
python::detail::convertible<PyObject const volatile*>::check((T*)0)); | |
typedef typename remove_cv<T>::type value_type; | |
reject_raw_object_helper<T,no_convertible>::error( | |
python::detail::convertible<unspecialized*>::check( | |
(base_type_traits<value_type>*)0 | |
)); | |
} | |
// --------- | |
template <class T> | |
inline function_arg_to_python<T>::function_arg_to_python(T const& x) | |
: handle<>(python::objects::make_function_handle(x)) | |
{ | |
} | |
template <class T> | |
inline value_arg_to_python<T>::value_arg_to_python(T const& x) | |
: arg_to_python_base(&x, registered<T>::converters) | |
{ | |
} | |
template <class Ptr> | |
inline pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr x) | |
: arg_to_python_base(x, registered_pointee<Ptr>::converters) | |
{ | |
detail::reject_raw_object_ptr((Ptr)0); | |
} | |
template <class T> | |
inline PyObject* reference_arg_to_python<T>::get_object(T& x) | |
{ | |
to_python_indirect<T&,python::detail::make_reference_holder> convert; | |
return convert(x); | |
} | |
template <class T> | |
inline reference_arg_to_python<T>::reference_arg_to_python(T& x) | |
: handle<>(reference_arg_to_python<T>::get_object(x)) | |
{ | |
} | |
template <class T> | |
inline shared_ptr_arg_to_python<T>::shared_ptr_arg_to_python(T const& x) | |
: handle<>(shared_ptr_to_python(x)) | |
{ | |
} | |
template <class Ptr> | |
inline pointer_shallow_arg_to_python<Ptr>::pointer_shallow_arg_to_python(Ptr x) | |
: handle<>(pointer_shallow_arg_to_python<Ptr>::get_object(x)) | |
{ | |
detail::reject_raw_object_ptr((Ptr)0); | |
} | |
template <class Ptr> | |
inline PyObject* pointer_shallow_arg_to_python<Ptr>::get_object(Ptr x) | |
{ | |
to_python_indirect<Ptr,python::detail::make_reference_holder> convert; | |
return convert(x); | |
} | |
} | |
template <class T> | |
inline arg_to_python<T>::arg_to_python(T const& x) | |
: base(x) | |
{} | |
}}} // namespace boost::python::converter | |
#endif // ARG_TO_PYTHON_DWA200265_HPP |