Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Copyright David Abrahams 2002.
0002 // Copyright Stefan Seefeld 2016.
0003 // Distributed under the Boost Software License, Version 1.0. (See
0004 // accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef boost_python_to_python_value_hpp_
0008 #define boost_python_to_python_value_hpp_
0009 
0010 #include <boost/python/detail/prefix.hpp>
0011 
0012 #include <boost/python/refcount.hpp>
0013 #include <boost/python/tag.hpp>
0014 #include <boost/python/handle.hpp>
0015 
0016 #include <boost/python/converter/registry.hpp>
0017 #include <boost/python/converter/registered.hpp>
0018 #include <boost/python/converter/builtin_converters.hpp>
0019 #include <boost/python/converter/object_manager.hpp>
0020 #include <boost/python/converter/shared_ptr_to_python.hpp>
0021 
0022 #include <boost/python/detail/type_traits.hpp>
0023 #include <boost/python/detail/value_is_shared_ptr.hpp>
0024 #include <boost/python/detail/value_arg.hpp>
0025 
0026 #include <boost/mpl/if.hpp>
0027 #include <boost/mpl/or.hpp>
0028 
0029 namespace boost { namespace python { 
0030 
0031 namespace detail
0032 {
0033 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0034 
0035 template <bool is_const_ref>
0036 struct object_manager_get_pytype
0037 {
0038    template <class U>
0039    static PyTypeObject const* get( U& (*)() =0)
0040    {
0041       return converter::object_manager_traits<U>::get_pytype();
0042    }
0043 };
0044 
0045 template <>
0046 struct object_manager_get_pytype<true>
0047 {
0048    template <class U>
0049    static PyTypeObject const* get( U const& (*)() =0)
0050    {
0051       return converter::object_manager_traits<U>::get_pytype();
0052    }
0053 };
0054 
0055 #endif
0056 
0057   template <class T>
0058   struct object_manager_to_python_value
0059   {
0060       typedef typename value_arg<T>::type argument_type;
0061     
0062       PyObject* operator()(argument_type) const;
0063 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0064       typedef boost::mpl::bool_<is_handle<T>::value> is_t_handle;
0065       typedef boost::detail::indirect_traits::is_reference_to_const<T> is_t_const;
0066       PyTypeObject const* get_pytype() const {
0067           return get_pytype_aux((is_t_handle*)0);
0068       }
0069 
0070       inline static PyTypeObject const* get_pytype_aux(mpl::true_*) {return converter::object_manager_traits<T>::get_pytype();}
0071       
0072       inline static PyTypeObject const* get_pytype_aux(mpl::false_* ) 
0073       {
0074           return object_manager_get_pytype<is_t_const::value>::get((T(*)())0);
0075       }
0076       
0077 #endif 
0078 
0079       // This information helps make_getter() decide whether to try to
0080       // return an internal reference or not. I don't like it much,
0081       // but it will have to serve for now.
0082       BOOST_STATIC_CONSTANT(bool, uses_registry = false);
0083   };
0084 
0085   
0086   template <class T>
0087   struct registry_to_python_value
0088   {
0089       typedef typename value_arg<T>::type argument_type;
0090     
0091       PyObject* operator()(argument_type) const;
0092 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0093       PyTypeObject const* get_pytype() const {return converter::registered<T>::converters.to_python_target_type();}
0094 #endif
0095 
0096       // This information helps make_getter() decide whether to try to
0097       // return an internal reference or not. I don't like it much,
0098       // but it will have to serve for now.
0099       BOOST_STATIC_CONSTANT(bool, uses_registry = true);
0100   };
0101 
0102   template <class T>
0103   struct shared_ptr_to_python_value
0104   {
0105       typedef typename value_arg<T>::type argument_type;
0106     
0107       PyObject* operator()(argument_type) const;
0108 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0109       PyTypeObject const* get_pytype() const {return get_pytype((boost::type<argument_type>*)0);}
0110 #endif 
0111       // This information helps make_getter() decide whether to try to
0112       // return an internal reference or not. I don't like it much,
0113       // but it will have to serve for now.
0114       BOOST_STATIC_CONSTANT(bool, uses_registry = false);
0115   private:
0116 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0117     template <class U>
0118     PyTypeObject const* get_pytype(boost::type<shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
0119     template <class U>
0120     PyTypeObject const* get_pytype(boost::type<const shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
0121 # if !defined(BOOST_NO_CXX11_SMART_PTR)
0122     template <class U>
0123     PyTypeObject const* get_pytype(boost::type<std::shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
0124     template <class U>
0125     PyTypeObject const* get_pytype(boost::type<const std::shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
0126 # endif
0127 #endif
0128   };
0129 }
0130 
0131 template <class T>
0132 struct to_python_value
0133     : mpl::if_<
0134           detail::value_is_shared_ptr<T>
0135         , detail::shared_ptr_to_python_value<T>
0136         , typename mpl::if_<
0137               mpl::or_<
0138                   converter::is_object_manager<T>
0139                 , converter::is_reference_to_object_manager<T>
0140               >
0141             , detail::object_manager_to_python_value<T>
0142             , detail::registry_to_python_value<T>
0143           >::type
0144       >::type
0145 {
0146 };
0147 
0148 //
0149 // implementation 
0150 //
0151 namespace detail
0152 {
0153   template <class T>
0154   inline PyObject* registry_to_python_value<T>::operator()(argument_type x) const
0155   {
0156       return converter::registered<argument_type>::converters.to_python(&x);
0157   }
0158 
0159   template <class T>
0160   inline PyObject* object_manager_to_python_value<T>::operator()(argument_type x) const
0161   {
0162       return python::upcast<PyObject>(
0163           python::xincref(
0164               get_managed_object(x, tag))
0165           );
0166   }
0167 
0168   template <class T>
0169   inline PyObject* shared_ptr_to_python_value<T>::operator()(argument_type x) const
0170   {
0171       return converter::shared_ptr_to_python(x);
0172   }
0173 }
0174 
0175 }} // namespace boost::python
0176 
0177 #endif