os/ossrv/ossrv_pub/boost_apis/boost/python/handle.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 HANDLE_DWA200269_HPP
sl@0
     6
# define HANDLE_DWA200269_HPP
sl@0
     7
sl@0
     8
# include <boost/python/detail/prefix.hpp>
sl@0
     9
sl@0
    10
# include <boost/python/cast.hpp>
sl@0
    11
# include <boost/python/errors.hpp>
sl@0
    12
# include <boost/python/borrowed.hpp>
sl@0
    13
# include <boost/python/handle_fwd.hpp>
sl@0
    14
# include <boost/python/refcount.hpp>
sl@0
    15
# include <boost/python/tag.hpp>
sl@0
    16
# include <boost/python/detail/raw_pyobject.hpp>
sl@0
    17
sl@0
    18
namespace boost { namespace python { 
sl@0
    19
sl@0
    20
template <class T> struct null_ok;
sl@0
    21
sl@0
    22
template <class T>
sl@0
    23
inline null_ok<T>* allow_null(T* p)
sl@0
    24
{
sl@0
    25
    return (null_ok<T>*)p;
sl@0
    26
}
sl@0
    27
sl@0
    28
namespace detail
sl@0
    29
{
sl@0
    30
  template <class T>
sl@0
    31
  inline T* manage_ptr(detail::borrowed<null_ok<T> >* p, int)
sl@0
    32
  {
sl@0
    33
      return python::xincref((T*)p);
sl@0
    34
  }
sl@0
    35
  
sl@0
    36
  template <class T>
sl@0
    37
  inline T* manage_ptr(null_ok<detail::borrowed<T> >* p, int)
sl@0
    38
  {
sl@0
    39
      return python::xincref((T*)p);
sl@0
    40
  }
sl@0
    41
  
sl@0
    42
  template <class T>
sl@0
    43
  inline T* manage_ptr(detail::borrowed<T>* p, long)
sl@0
    44
  {
sl@0
    45
      return python::incref(expect_non_null((T*)p));
sl@0
    46
  }
sl@0
    47
  
sl@0
    48
  template <class T>
sl@0
    49
  inline T* manage_ptr(null_ok<T>* p, long)
sl@0
    50
  {
sl@0
    51
      return (T*)p;
sl@0
    52
  }
sl@0
    53
  
sl@0
    54
  template <class T>
sl@0
    55
  inline T* manage_ptr(T* p, ...)
sl@0
    56
  {
sl@0
    57
      return expect_non_null(p);
sl@0
    58
  }
sl@0
    59
}
sl@0
    60
sl@0
    61
template <class T>
sl@0
    62
class handle
sl@0
    63
{
sl@0
    64
    typedef T* (handle::* bool_type )() const;
sl@0
    65
sl@0
    66
 public: // types
sl@0
    67
    typedef T element_type;
sl@0
    68
    
sl@0
    69
 public: // member functions
sl@0
    70
    handle();
sl@0
    71
    ~handle();
sl@0
    72
sl@0
    73
    template <class Y>
sl@0
    74
    explicit handle(Y* p)
sl@0
    75
        : m_p(
sl@0
    76
            python::upcast<T>(
sl@0
    77
                detail::manage_ptr(p, 0)
sl@0
    78
                )
sl@0
    79
            )
sl@0
    80
    {
sl@0
    81
    }
sl@0
    82
sl@0
    83
    handle& operator=(handle const& r)
sl@0
    84
    {
sl@0
    85
        python::xdecref(m_p);
sl@0
    86
        m_p = python::xincref(r.m_p);
sl@0
    87
        return *this;
sl@0
    88
    }
sl@0
    89
sl@0
    90
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
sl@0
    91
sl@0
    92
    template<typename Y>
sl@0
    93
    handle& operator=(handle<Y> const & r) // never throws
sl@0
    94
    {
sl@0
    95
        python::xdecref(m_p);
sl@0
    96
        m_p = python::xincref(python::upcast<T>(r.get()));
sl@0
    97
        return *this;
sl@0
    98
    }
sl@0
    99
sl@0
   100
#endif
sl@0
   101
sl@0
   102
    template <typename Y>
sl@0
   103
    handle(handle<Y> const& r)
sl@0
   104
        : m_p(python::xincref(python::upcast<T>(r.get())))
sl@0
   105
    {
sl@0
   106
    }
sl@0
   107
    
sl@0
   108
    handle(handle const& r)
sl@0
   109
        : m_p(python::xincref(r.m_p))
sl@0
   110
    {
sl@0
   111
    }
sl@0
   112
    
sl@0
   113
    T* operator-> () const;
sl@0
   114
    T& operator* () const;
sl@0
   115
    T* get() const;
sl@0
   116
    T* release();
sl@0
   117
    void reset();
sl@0
   118
    
sl@0
   119
    operator bool_type() const // never throws
sl@0
   120
    {
sl@0
   121
        return m_p ? &handle<T>::get : 0;
sl@0
   122
    }
sl@0
   123
    bool operator! () const; // never throws
sl@0
   124
sl@0
   125
 public: // implementation details -- do not touch
sl@0
   126
    // Defining this in the class body suppresses a VC7 link failure
sl@0
   127
    inline handle(detail::borrowed_reference x)
sl@0
   128
        : m_p(
sl@0
   129
            python::incref(
sl@0
   130
                downcast<T>((PyObject*)x)
sl@0
   131
                ))
sl@0
   132
    {
sl@0
   133
    }
sl@0
   134
    
sl@0
   135
 private: // data members
sl@0
   136
    T* m_p;
sl@0
   137
};
sl@0
   138
sl@0
   139
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
sl@0
   140
} // namespace python
sl@0
   141
#endif
sl@0
   142
sl@0
   143
template<class T> inline T * get_pointer(python::handle<T> const & p)
sl@0
   144
{
sl@0
   145
    return p.get();
sl@0
   146
}
sl@0
   147
sl@0
   148
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
sl@0
   149
namespace python {
sl@0
   150
#else
sl@0
   151
sl@0
   152
// We don't want get_pointer above to hide the others
sl@0
   153
using boost::get_pointer;
sl@0
   154
sl@0
   155
#endif
sl@0
   156
sl@0
   157
typedef handle<PyTypeObject> type_handle;
sl@0
   158
sl@0
   159
//
sl@0
   160
// Compile-time introspection
sl@0
   161
//
sl@0
   162
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
sl@0
   163
template<typename T>
sl@0
   164
class is_handle
sl@0
   165
{
sl@0
   166
 public:
sl@0
   167
    BOOST_STATIC_CONSTANT(bool, value = false); 
sl@0
   168
};
sl@0
   169
sl@0
   170
template<typename T>
sl@0
   171
class is_handle<handle<T> >
sl@0
   172
{
sl@0
   173
 public:
sl@0
   174
    BOOST_STATIC_CONSTANT(bool, value = true);
sl@0
   175
};
sl@0
   176
# else
sl@0
   177
namespace detail
sl@0
   178
{
sl@0
   179
  typedef char (&yes_handle_t)[1];
sl@0
   180
  typedef char (&no_handle_t)[2];
sl@0
   181
      
sl@0
   182
  no_handle_t is_handle_test(...);
sl@0
   183
sl@0
   184
  template<typename T>
sl@0
   185
  yes_handle_t is_handle_test(boost::type< handle<T> >);
sl@0
   186
}
sl@0
   187
sl@0
   188
template<typename T>
sl@0
   189
class is_handle
sl@0
   190
{
sl@0
   191
 public:
sl@0
   192
    BOOST_STATIC_CONSTANT(
sl@0
   193
        bool, value = (
sl@0
   194
            sizeof(detail::is_handle_test(boost::type<T>()))
sl@0
   195
            == sizeof(detail::yes_handle_t)));
sl@0
   196
};
sl@0
   197
# endif
sl@0
   198
sl@0
   199
//
sl@0
   200
// implementations
sl@0
   201
//
sl@0
   202
template <class T>
sl@0
   203
inline handle<T>::handle()
sl@0
   204
    : m_p(0)
sl@0
   205
{
sl@0
   206
}
sl@0
   207
sl@0
   208
template <class T>
sl@0
   209
inline handle<T>::~handle()
sl@0
   210
{
sl@0
   211
    python::xdecref(m_p);
sl@0
   212
}
sl@0
   213
sl@0
   214
template <class T>
sl@0
   215
inline T* handle<T>::operator->() const
sl@0
   216
{
sl@0
   217
    return m_p;
sl@0
   218
}
sl@0
   219
sl@0
   220
template <class T>
sl@0
   221
inline T& handle<T>::operator*() const
sl@0
   222
{
sl@0
   223
    return *m_p;
sl@0
   224
}
sl@0
   225
sl@0
   226
template <class T>
sl@0
   227
inline T* handle<T>::get() const
sl@0
   228
{
sl@0
   229
    return m_p;
sl@0
   230
}
sl@0
   231
    
sl@0
   232
template <class T>
sl@0
   233
inline bool handle<T>::operator!() const
sl@0
   234
{
sl@0
   235
    return m_p == 0;
sl@0
   236
}
sl@0
   237
sl@0
   238
template <class T>
sl@0
   239
inline T* handle<T>::release()
sl@0
   240
{
sl@0
   241
    T* result = m_p;
sl@0
   242
    m_p = 0;
sl@0
   243
    return result;
sl@0
   244
}
sl@0
   245
sl@0
   246
template <class T>
sl@0
   247
inline void handle<T>::reset()
sl@0
   248
{
sl@0
   249
    python::xdecref(m_p);
sl@0
   250
    m_p = 0;
sl@0
   251
}
sl@0
   252
sl@0
   253
// Because get_managed_object must return a non-null PyObject*, we
sl@0
   254
// return Py_None if the handle is null.
sl@0
   255
template <class T>
sl@0
   256
inline PyObject* get_managed_object(handle<T> const& h, tag_t)
sl@0
   257
{
sl@0
   258
    return h.get() ? python::upcast<PyObject>(h.get()) : Py_None;
sl@0
   259
}
sl@0
   260
sl@0
   261
}} // namespace boost::python
sl@0
   262
sl@0
   263
sl@0
   264
#endif // HANDLE_DWA200269_HPP