boost/python/handle.hpp

はじめに

<boost/python/handle.hpp> は参照カウント付きの Python オブジェクトを管理するスマートポインタである handle クラステンプレートを提供する。

クラス

handle クラステンプレート

template<class T>
class handle

handle は Python のオブジェクト型へのスマートポインタであり、T* 型のポインタを保持する(T はそのテンプレート引数)。TPyObject の派生型か、先頭 sizeof(PyObject) バイトが PyObject とレイアウト互換な POD 型のいずれかでなければならない。Python/'C' API と高水準コードの境界で handle<> を使用することだ。一般的なインターフェイスに対しては Python のオブジェクトよりも object を使用すべきだ。

このドキュメントで「upcast」は、YT の派生型の場合 static_castD<T*> で、そうでない場合 C スタイルのキャストでポインタ Y* を基底クラスポインタ T* へ変換する操作を指す。しかしながらYの先頭 sizeof(PyObject) バイトが PyObject とレイアウト互換でなければ、「upcast」は違法である。

handle クラステンプレートの概要

namespace boost { namespace python
{
  template <class T>
  class handle
  {
      typedef unspecified-member-function-pointer bool_type;

   public: // 型
      typedef T element_type;

   public: // メンバ関数
      ~handle();

      template <class Y>
      explicit handle(detail::borrowed<null_ok<Y> >* p);

      template <class Y>
      explicit handle(null_ok<detail::borrowed<Y> >* p);

      template <class Y>
      explicit handle(detail::borrowed<Y>* p);

      template <class Y>
      explicit handle(null_ok<Y>* p);

      template <class Y>
      explicit handle(Y* p);

      handle();

      handle& operator=(handle const& r);

      template<typename Y>
      handle& operator=(handle<Y> const & r); // 例外を投げない


      template <typename Y>
      handle(handle<Y> const& r);

      handle(handle const& r);

      T* operator-> () const;
      T& operator* () const;
      T* get() const;
      void reset();
      T* release();

      operator bool_type() const; // 例外を投げない
   private:
      T* m_p;
  };

  template <class T> struct null_ok;
  namespace detail { template <class T> struct borrowed; }
}}

handle クラステンプレートのコンストラクタおよびデストラクタ

virtual ~handle()
効果

Py_XDECREF(upcast<PyObject*>(m_p))

template<class Y>
explicit handle(detail::borrowed<null_ok<Y>> *p)
効果

Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(p)

template<class Y>
explicit handle(null_ok<detail::borrowed<Y>> *p)
効果

Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(p)

template<class Y>
explicit handle(detail::borrowed<Y> *p)
効果

Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(expect_non_null(p))

template<class Y>
explicit handle(null_ok<Y> *p)
効果

m_p = upcast<T*>(p)

template<class Y>
explicit handle(Y *p)
効果

m_p = upcast<T*>(expect_non_null(p))

handle()
効果

m_p = 0

template<typename Y>
handle(handle<Y> const &r)
handle(handle const &r)
効果

m_p = r.m_p; Py_XINCREF(upcast<PyObject*>(m_p))

handle クラステンプレートの変更関数

handle &operator=(handle const &r)
template<typename Y>
handle &operator=(handle<Y> const &r) noexcept
効果

Py_XINCREF(upcast<PyObject*>(r.m_p)); Py_XDECREF(upcast<PyObject*>(m_p)); m_p = r.m_p

T *release()
効果

T * x = m_p; m_p = 0; return x

void reset()
効果

*this = handle<T>()

handle クラステンプレートのオブザーバ関数

T *operator->() const
T *get() const
戻り値

m_p

T &operator*() const
戻り値

*m_p

operator bool_type() const noexcept
戻り値

m_p == 0 の場合 0。それ以外の場合、true へ変換可能なポインタ。

関数

borrowed

template<class T>
detail::borrowed<T> *borrowed(T *p)
template <class T>
detail::borrowed<T>* borrowed(T* p)
{
    return (detail::borrowed<T>*)p;
}

allow_null

template<class T>
null_ok<T> *allow_null(T *p)
template <class T>
null_ok<T>* allow_null(T* p)
{
    return (null_ok<T>*)p;
}