ossrv_pub/boost_apis/boost/python/extract.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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