262 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			262 lines
		
	
	
		
			7.5 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 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 |