os/ossrv/ossrv_pub/boost_apis/boost/python/extract.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright David Abrahams 2002.
     2 // Distributed under the Boost Software License, Version 1.0. (See
     3 // accompanying file LICENSE_1_0.txt or copy at
     4 // http://www.boost.org/LICENSE_1_0.txt)
     5 #ifndef EXTRACT_DWA200265_HPP
     6 # define EXTRACT_DWA200265_HPP
     7 
     8 # include <boost/python/detail/prefix.hpp>
     9 
    10 # include <boost/python/converter/object_manager.hpp>
    11 # include <boost/python/converter/from_python.hpp>
    12 # include <boost/python/converter/rvalue_from_python_data.hpp>
    13 # include <boost/python/converter/registered.hpp>
    14 # include <boost/python/converter/registered_pointee.hpp>
    15 
    16 # include <boost/python/object_core.hpp>
    17 # include <boost/python/refcount.hpp>
    18 
    19 # include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
    20 # include <boost/python/detail/void_ptr.hpp>
    21 # include <boost/python/detail/void_return.hpp>
    22 # include <boost/utility.hpp>
    23 # include <boost/call_traits.hpp>
    24 
    25 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 900)
    26 // workaround for VC++ 6.x or 7.0
    27 # define BOOST_EXTRACT_WORKAROUND ()
    28 #else
    29 # define BOOST_EXTRACT_WORKAROUND
    30 #endif
    31 
    32 namespace boost { namespace python {
    33 
    34 namespace api
    35 {
    36   class object;
    37 }
    38 
    39 namespace converter
    40 {
    41   template <class Ptr>
    42   struct extract_pointer
    43   {
    44       typedef Ptr result_type;
    45       extract_pointer(PyObject*);
    46       
    47       bool check() const;
    48       Ptr operator()() const;
    49       
    50    private:
    51       PyObject* m_source;
    52       void* m_result;
    53   };
    54   
    55   template <class Ref>
    56   struct extract_reference
    57   {
    58       typedef Ref result_type;
    59       extract_reference(PyObject*);
    60       
    61       bool check() const;
    62       Ref operator()() const;
    63       
    64    private:
    65       PyObject* m_source;
    66       void* m_result;
    67   };
    68   
    69   template <class T>
    70   struct extract_rvalue : private noncopyable
    71   {
    72       typedef typename mpl::if_<
    73           python::detail::copy_ctor_mutates_rhs<T>
    74         , T&
    75         , typename call_traits<T>::param_type
    76       >::type result_type;
    77 
    78       extract_rvalue(PyObject*);
    79 
    80       bool check() const;
    81       result_type operator()() const;
    82    private:
    83       PyObject* m_source;
    84       mutable rvalue_from_python_data<T> m_data;
    85   };
    86   
    87   template <class T>
    88   struct extract_object_manager
    89   {
    90       typedef T result_type;
    91       extract_object_manager(PyObject*);
    92 
    93       bool check() const;
    94       result_type operator()() const;
    95    private:
    96       PyObject* m_source;
    97   };
    98   
    99   template <class T>
   100   struct select_extract
   101   {
   102       BOOST_STATIC_CONSTANT(
   103           bool, obj_mgr = is_object_manager<T>::value);
   104 
   105       BOOST_STATIC_CONSTANT(
   106           bool, ptr = is_pointer<T>::value);
   107     
   108       BOOST_STATIC_CONSTANT(
   109           bool, ref = is_reference<T>::value);
   110 
   111       typedef typename mpl::if_c<
   112           obj_mgr
   113           , extract_object_manager<T>
   114           , typename mpl::if_c<
   115               ptr
   116               , extract_pointer<T>
   117               , typename mpl::if_c<
   118                   ref
   119                   , extract_reference<T>
   120                   , extract_rvalue<T>
   121                 >::type
   122             >::type
   123          >::type type;
   124   };
   125 }
   126 
   127 template <class T>
   128 struct extract
   129     : converter::select_extract<T>::type
   130 {
   131  private:
   132     typedef typename converter::select_extract<T>::type base;
   133  public:
   134     typedef typename base::result_type result_type;
   135     
   136     operator result_type() const
   137     {
   138         return (*this)();
   139     }
   140     
   141     extract(PyObject*);
   142     extract(api::object const&);
   143 };
   144 
   145 //
   146 // Implementations
   147 //
   148 template <class T>
   149 inline extract<T>::extract(PyObject* o)
   150     : base(o)
   151 {
   152 }
   153 
   154 template <class T>
   155 inline extract<T>::extract(api::object const& o)
   156     : base(o.ptr())
   157 {
   158 }
   159 
   160 namespace converter
   161 {
   162   template <class T>
   163   inline extract_rvalue<T>::extract_rvalue(PyObject* x)
   164       : m_source(x)
   165       , m_data(
   166           (rvalue_from_python_stage1)(x, registered<T>::converters)
   167           )
   168   {
   169   }
   170   
   171   template <class T>
   172   inline bool
   173   extract_rvalue<T>::check() const
   174   {
   175       return m_data.stage1.convertible;
   176   }
   177 
   178   template <class T>
   179   inline typename extract_rvalue<T>::result_type
   180   extract_rvalue<T>::operator()() const
   181   {
   182       return *(T*)(
   183           // Only do the stage2 conversion once
   184           m_data.stage1.convertible ==  m_data.storage.bytes
   185              ? m_data.storage.bytes
   186              : (rvalue_from_python_stage2)(m_source, m_data.stage1, registered<T>::converters)
   187           );
   188   }
   189 
   190   template <class Ref>
   191   inline extract_reference<Ref>::extract_reference(PyObject* obj)
   192       : m_source(obj)
   193       , m_result(
   194           (get_lvalue_from_python)(obj, registered<Ref>::converters)
   195           )
   196   {
   197   }
   198 
   199   template <class Ref>
   200   inline bool extract_reference<Ref>::check() const
   201   {
   202       return m_result != 0;
   203   }
   204 
   205   template <class Ref>
   206   inline Ref extract_reference<Ref>::operator()() const
   207   {
   208       if (m_result == 0)
   209           (throw_no_reference_from_python)(m_source, registered<Ref>::converters);
   210       
   211       return python::detail::void_ptr_to_reference(m_result, (Ref(*)())0);
   212   }
   213 
   214   template <class Ptr>
   215   inline extract_pointer<Ptr>::extract_pointer(PyObject* obj)
   216       : m_source(obj)
   217       , m_result(
   218           obj == Py_None ? 0 : (get_lvalue_from_python)(obj, registered_pointee<Ptr>::converters)
   219           )
   220   {
   221   }
   222 
   223   template <class Ptr>
   224   inline bool extract_pointer<Ptr>::check() const
   225   {
   226       return m_source == Py_None || m_result != 0;
   227   }
   228 
   229   template <class Ptr>
   230   inline Ptr extract_pointer<Ptr>::operator()() const
   231   {
   232       if (m_result == 0 && m_source != Py_None)
   233           (throw_no_pointer_from_python)(m_source, registered_pointee<Ptr>::converters);
   234       
   235       return Ptr(m_result);
   236   }
   237 
   238   template <class T>
   239   inline extract_object_manager<T>::extract_object_manager(PyObject* obj)
   240       : m_source(obj)
   241   {
   242   }
   243 
   244   template <class T>
   245   inline bool extract_object_manager<T>::check() const
   246   {
   247       return object_manager_traits<T>::check(m_source);
   248   }
   249 
   250   template <class T>
   251   inline T extract_object_manager<T>::operator()() const
   252   {
   253       return T(
   254           object_manager_traits<T>::adopt(python::incref(m_source))
   255           );
   256   }
   257 }
   258   
   259 }} // namespace boost::python::converter
   260 
   261 #endif // EXTRACT_DWA200265_HPP