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