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
 | 
