Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:37

0001 // Copyright David Abrahams 2002.
0002 // Distributed under the Boost Software License, Version 1.0. (See
0003 // accompanying file LICENSE_1_0.txt or copy at
0004 // http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef RETURN_FROM_PYTHON_DWA200265_HPP
0006 # define RETURN_FROM_PYTHON_DWA200265_HPP
0007 
0008 # include <boost/python/converter/from_python.hpp>
0009 # include <boost/python/converter/rvalue_from_python_data.hpp>
0010 # include <boost/python/converter/registered.hpp>
0011 # include <boost/python/converter/registered_pointee.hpp>
0012 # include <boost/python/converter/object_manager.hpp>
0013 # include <boost/python/detail/void_ptr.hpp>
0014 # include <boost/python/detail/void_return.hpp>
0015 # include <boost/python/errors.hpp>
0016 # include <boost/python/handle.hpp>
0017 # include <boost/python/detail/type_traits.hpp>
0018 # include <boost/mpl/and.hpp>
0019 # include <boost/mpl/bool.hpp>
0020 
0021 namespace boost { namespace python { namespace converter { 
0022 
0023 template <class T> struct is_object_manager;
0024 
0025 namespace detail
0026 {
0027   template <class T>
0028   struct return_pointer_from_python
0029   {
0030       typedef T result_type;
0031       T operator()(PyObject*) const;
0032   };
0033   
0034   template <class T>
0035   struct return_reference_from_python
0036   {
0037       typedef T result_type;
0038       T operator()(PyObject*) const;
0039   };
0040   
0041   template <class T>
0042   struct return_rvalue_from_python
0043   {
0044       typedef T result_type;
0045 
0046       return_rvalue_from_python();
0047       result_type operator()(PyObject*);
0048    private:
0049       rvalue_from_python_data<T> m_data;
0050   };
0051   
0052   template <class T>
0053   struct return_object_manager_from_python
0054   {
0055       typedef T result_type;
0056       result_type operator()(PyObject*) const;
0057   };
0058   
0059   template <class T>
0060   struct select_return_from_python
0061   {
0062       BOOST_STATIC_CONSTANT(
0063           bool, obj_mgr = is_object_manager<T>::value);
0064 
0065       BOOST_STATIC_CONSTANT(
0066           bool, ptr = is_pointer<T>::value);
0067     
0068       BOOST_STATIC_CONSTANT(
0069           bool, ref = is_reference<T>::value);
0070 
0071       typedef typename mpl::if_c<
0072           obj_mgr
0073           , return_object_manager_from_python<T>
0074           , typename mpl::if_c<
0075               ptr
0076               , return_pointer_from_python<T>
0077               , typename mpl::if_c<
0078                   ref
0079                   , return_reference_from_python<T>
0080                   , return_rvalue_from_python<T>
0081                 >::type
0082             >::type
0083          >::type type;
0084   };
0085 }
0086 
0087 template <class T>
0088 struct return_from_python
0089     : detail::select_return_from_python<T>::type
0090 {
0091 };
0092 
0093 // Specialization as a convenience for call and call_method
0094 template <>
0095 struct return_from_python<void>
0096 {
0097     typedef python::detail::returnable<void>::type result_type;
0098     
0099     result_type operator()(PyObject* x) const
0100     {
0101         (void_result_from_python)(x);
0102 # ifdef BOOST_NO_VOID_RETURNS
0103         return result_type();
0104 # endif 
0105     }
0106 };
0107 
0108 //
0109 // Implementations
0110 //
0111 namespace detail
0112 {
0113   template <class T>
0114   inline return_rvalue_from_python<T>::return_rvalue_from_python()
0115       : m_data(
0116           const_cast<registration*>(&registered<T>::converters)
0117           )
0118   {
0119   }
0120   
0121   template <class T>
0122   inline typename return_rvalue_from_python<T>::result_type
0123   return_rvalue_from_python<T>::operator()(PyObject* obj)
0124   {
0125     // Take possession of the source object here.  If the result is in
0126     // fact going to be a copy of an lvalue embedded in the object,
0127     // and we take possession inside rvalue_result_from_python, it
0128     // will be destroyed too early.
0129     handle<> holder(obj);
0130 
0131       return *(T*)
0132           (rvalue_result_from_python)(obj, m_data.stage1);
0133   }
0134 
0135   template <class T>
0136   inline T return_reference_from_python<T>::operator()(PyObject* obj) const
0137   {
0138       return python::detail::void_ptr_to_reference(
0139           (reference_result_from_python)(obj, registered<T>::converters)
0140           , (T(*)())0);
0141   }
0142 
0143   template <class T>
0144   inline T return_pointer_from_python<T>::operator()(PyObject* obj) const
0145   {
0146       return T(
0147           (pointer_result_from_python)(obj, registered_pointee<T>::converters)
0148           );
0149   }
0150 
0151   template <class T>
0152   inline T return_object_manager_from_python<T>::operator()(PyObject* obj) const
0153   {
0154       return T(
0155           object_manager_traits<T>::adopt(expect_non_null(obj))
0156           );
0157   }
0158 }
0159   
0160 }}} // namespace boost::python::converter
0161 
0162 #endif // RETURN_FROM_PYTHON_DWA200265_HPP