You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
261 lines
7.3 KiB
261 lines
7.3 KiB
// 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
|
|
|