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
							 |