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 ARG_TO_PYTHON_DWA200265_HPP
0006 # define ARG_TO_PYTHON_DWA200265_HPP
0007 
0008 # include <boost/python/ptr.hpp>
0009 # include <boost/python/tag.hpp>
0010 # include <boost/python/to_python_indirect.hpp>
0011 
0012 # include <boost/python/converter/registered.hpp>
0013 # include <boost/python/converter/registered_pointee.hpp>
0014 # include <boost/python/converter/arg_to_python_base.hpp>
0015 # include <boost/python/converter/shared_ptr_to_python.hpp>
0016 // Bring in specializations
0017 # include <boost/python/converter/builtin_converters.hpp>
0018 
0019 # include <boost/python/object/function_handle.hpp>
0020 
0021 # include <boost/python/base_type_traits.hpp>
0022 
0023 # include <boost/python/detail/indirect_traits.hpp>
0024 # include <boost/python/detail/convertible.hpp>
0025 # include <boost/python/detail/string_literal.hpp>
0026 # include <boost/python/detail/value_is_shared_ptr.hpp>
0027 # include <boost/python/detail/type_traits.hpp>
0028 
0029 # include <boost/mpl/or.hpp>
0030 
0031 namespace boost { namespace python { namespace converter { 
0032 
0033 template <class T> struct is_object_manager;
0034 
0035 namespace detail
0036 {
0037   template <class T>
0038   struct function_arg_to_python : handle<>
0039   {
0040       function_arg_to_python(T const& x);
0041   };
0042 
0043   template <class T>
0044   struct reference_arg_to_python : handle<>
0045   {
0046       reference_arg_to_python(T& x);
0047    private:
0048       static PyObject* get_object(T& x);
0049   };
0050 
0051   template <class T>
0052   struct shared_ptr_arg_to_python : handle<>
0053   {
0054       shared_ptr_arg_to_python(T const& x);
0055    private:
0056       static PyObject* get_object(T& x);
0057   };
0058 
0059   template <class T>
0060   struct value_arg_to_python : arg_to_python_base
0061   {
0062       // Throw an exception if the conversion can't succeed
0063       value_arg_to_python(T const&);
0064   };
0065 
0066   template <class Ptr>
0067   struct pointer_deep_arg_to_python : arg_to_python_base
0068   {
0069       // Throw an exception if the conversion can't succeed
0070       pointer_deep_arg_to_python(Ptr);
0071   };
0072 
0073   template <class Ptr>
0074   struct pointer_shallow_arg_to_python : handle<>
0075   {
0076       // Throw an exception if the conversion can't succeed
0077       pointer_shallow_arg_to_python(Ptr);
0078    private:
0079       static PyObject* get_object(Ptr p);
0080   };
0081 
0082   // Convert types that manage a Python object to_python
0083   template <class T>
0084   struct object_manager_arg_to_python
0085   {
0086       object_manager_arg_to_python(T const& x) : m_src(x) {}
0087       
0088       PyObject* get() const
0089       {
0090           return python::upcast<PyObject>(get_managed_object(m_src, tag));
0091       }
0092       
0093    private:
0094       T const& m_src;
0095   };
0096 
0097   template <class T>
0098   struct select_arg_to_python
0099   {
0100       typedef typename unwrap_reference<T>::type unwrapped_referent;
0101       typedef typename unwrap_pointer<T>::type unwrapped_ptr;
0102 
0103       typedef typename mpl::if_<
0104           // Special handling for char const[N]; interpret them as char
0105           // const* for the sake of conversion
0106           python::detail::is_string_literal<T const>
0107         , arg_to_python<char const*>
0108 
0109         , typename mpl::if_<
0110               python::detail::value_is_shared_ptr<T>
0111             , shared_ptr_arg_to_python<T>
0112       
0113             , typename mpl::if_<
0114                 mpl::or_<
0115                     boost::python::detail::is_function<T>
0116                   , indirect_traits::is_pointer_to_function<T>
0117                   , boost::python::detail::is_member_function_pointer<T>
0118                 >
0119                 , function_arg_to_python<T>
0120 
0121                 , typename mpl::if_<
0122                       is_object_manager<T>
0123                     , object_manager_arg_to_python<T>
0124 
0125                     , typename mpl::if_<
0126                           boost::python::detail::is_pointer<T>
0127                         , pointer_deep_arg_to_python<T>
0128 
0129                         , typename mpl::if_<
0130                               is_pointer_wrapper<T>
0131                             , pointer_shallow_arg_to_python<unwrapped_ptr>
0132 
0133                             , typename mpl::if_<
0134                                   is_reference_wrapper<T>
0135                                 , reference_arg_to_python<unwrapped_referent>
0136                                 , value_arg_to_python<T>
0137                               >::type
0138                           >::type
0139                       >::type
0140                   >::type
0141               >::type
0142           >::type
0143       >::type
0144       
0145       type;
0146   };
0147 }
0148 
0149 template <class T>
0150 struct arg_to_python
0151     : detail::select_arg_to_python<T>::type
0152 {
0153     typedef typename detail::select_arg_to_python<T>::type base;
0154  public: // member functions
0155     // Throw an exception if the conversion can't succeed
0156     arg_to_python(T const& x);
0157 };
0158 
0159 //
0160 // implementations
0161 //
0162 namespace detail
0163 {
0164   // reject_raw_object_ptr -- cause a compile-time error if the user
0165   // should pass a raw Python object pointer
0166   using python::detail::yes_convertible;
0167   using python::detail::no_convertible;
0168   using python::detail::unspecialized;
0169   
0170   template <class T> struct cannot_convert_raw_PyObject;
0171 
0172   template <class T, class Convertibility>
0173   struct reject_raw_object_helper
0174   {
0175       static void error(Convertibility)
0176       {
0177           cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
0178       }
0179       static void error(...) {}
0180   };
0181   
0182   template <class T>
0183   inline void reject_raw_object_ptr(T*)
0184   {
0185       reject_raw_object_helper<T,yes_convertible>::error(
0186           python::detail::convertible<PyObject const volatile*>::check((T*)0));
0187       
0188       typedef typename remove_cv<T>::type value_type;
0189       
0190       reject_raw_object_helper<T,no_convertible>::error(
0191           python::detail::convertible<unspecialized*>::check(
0192               (base_type_traits<value_type>*)0
0193               ));
0194   }
0195   // ---------
0196       
0197   template <class T>
0198   inline function_arg_to_python<T>::function_arg_to_python(T const& x)
0199       : handle<>(python::objects::make_function_handle(x))
0200   {
0201   }
0202 
0203   template <class T>
0204   inline value_arg_to_python<T>::value_arg_to_python(T const& x)
0205       : arg_to_python_base(&x, registered<T>::converters)
0206   {
0207   }
0208 
0209   template <class Ptr>
0210   inline pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr x)
0211       : arg_to_python_base(x, registered_pointee<Ptr>::converters)
0212   {
0213       detail::reject_raw_object_ptr((Ptr)0);
0214   }
0215 
0216   template <class T>
0217   inline PyObject* reference_arg_to_python<T>::get_object(T& x)
0218   {
0219       to_python_indirect<T&,python::detail::make_reference_holder> convert;
0220       return convert(x);
0221   }
0222 
0223   template <class T>
0224   inline reference_arg_to_python<T>::reference_arg_to_python(T& x)
0225       : handle<>(reference_arg_to_python<T>::get_object(x))
0226   {
0227   }
0228 
0229   template <class T>
0230   inline shared_ptr_arg_to_python<T>::shared_ptr_arg_to_python(T const& x)
0231       : handle<>(shared_ptr_to_python(x))
0232   {
0233   }
0234 
0235   template <class Ptr>
0236   inline pointer_shallow_arg_to_python<Ptr>::pointer_shallow_arg_to_python(Ptr x)
0237       : handle<>(pointer_shallow_arg_to_python<Ptr>::get_object(x))
0238   {
0239       detail::reject_raw_object_ptr((Ptr)0);
0240   }
0241 
0242   template <class Ptr>
0243   inline PyObject* pointer_shallow_arg_to_python<Ptr>::get_object(Ptr x)
0244   {
0245       to_python_indirect<Ptr,python::detail::make_reference_holder> convert;
0246       return convert(x);
0247   }
0248 }
0249 
0250 template <class T>
0251 inline arg_to_python<T>::arg_to_python(T const& x)
0252     : base(x)
0253 {}
0254 
0255 }}} // namespace boost::python::converter
0256 
0257 #endif // ARG_TO_PYTHON_DWA200265_HPP