boost/python/with_custodian_and_ward.hpp

はじめに

このヘッダは、関数の Python 引数および戻り値オブジェクトの 2 つの間の寿命依存性を確立する機能を提供する。非後見人(ward)オブジェクトは管理人(custodian)オブジェクトが弱い参照をサポートしている限り(Boost.Python の拡張クラスはすべて弱い参照をサポートする)管理人オブジェクトが破壊されるまで破壊されない。管理人オブジェクトが弱い参照をサポートしておらず None でもない場合、適切な例外が投げられる。2 つのクラステンプレート with_custodian_and_ward および with_custodian_and_ward_postcall の違いはそれらが効果を発揮する場所である。

不注意で懸垂ポインタを作成してしまう可能性を減らすため、既定では寿命の束縛は背後にある C++ オブジェクトが呼び出される前に行う。しかしながら結果のオブジェクトは呼び出すまで無効であるので、呼び出し後に寿命の束縛を行う with_custodian_and_ward_postcall を提供している。また with_custodian_and_ward<>::precall の後だが背後にある C++ オブジェクトが実際にポインタを格納するより前に C++ 例外が投げられた場合、管理人オブジェクトと非後見人オブジェクトの寿命は意図的にともに束縛されるため、ラップする関数のセマンティクスに応じて代わりに with_custodian_and_ward_postcall を選択するとよい。

関数呼び出し境界を超えて生のポインタの所有権を譲渡する関数をラップする場合、これは適したツールではないことに注意していただきたい。必要があればよくある質問と回答を参照されたい。

クラス

with_custodian_and_ward クラステンプレート

template<std::size_t custodian, std::size_t ward, class Base = default_call_policies>
struct with_custodian_and_ward : Base
テンプレートパラメータ
  • custodian --

    確立する寿命関係において依存される側を指すテンプレート引数の 1 から始まる添字。メンバ関数をラップする場合、引数 1 は対象オブジェクト(*this)である。対象の Python オブジェクト型が弱い参照をサポートしない場合、ラップする C++ オブジェクトを呼び出すと Python の TypeError 例外を送出することに注意していただきたい。1

    要件

    std::size_t 型の正のコンパイル時定数。

  • ward --

    確立する寿命関係において依存する側を指すテンプレート引数の 1 から始まる添字。メンバ関数をラップする場合、引数 1 は対象オブジェクト(*this)である。

    要件

    std::size_t 型の正のコンパイル時定数。

  • Base --

    ポリシーの合成に使用する。

    要件

    CallPolicies のモデル

    既定

    default_call_policies

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

namespace boost { namespace python
{
   template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
   struct with_custodian_and_ward : Base
   {
      static bool precall(PyObject* args);
   };
}}

with_custodian_and_ward クラスの静的関数

bool precall(PyObject *args)
要件

PyTuple_Check(args) != 0

効果

ward で指定した引数の寿命を custodian で指定した引数の寿命に依存させる。

戻り値

失敗時は falsePyErr_Occurred() != 0)。それ以外は true

with_custodian_and_ward_postcall クラステンプレート

template<std::size_t custodian, std::size_t ward, class Base = default_call_policies>
struct with_custodian_and_ward_postcall : Base
テンプレートパラメータ
  • custodian --

    確立する寿命関係において依存される側を指すテンプレート引数の添字。0 は戻り値、1 は第 1 引数を表す。メンバ関数をラップする場合、1 は対象オブジェクト(*this)である。対象の Python オブジェクト型が弱い参照をサポートしない場合、ラップする C++ オブジェクトを呼び出すと Python の TypeError 例外を送出することに注意していただきたい。2

    要件

    std::size_t 型の正のコンパイル時定数。

  • ward --

    確立する寿命関係において依存する側を指すテンプレート引数の添字。0 は戻り値、1 は第 1 引数を表す。メンバ関数をラップする場合、引数 1 は対象オブジェクト(*this)である。

    要件

    std::size_t 型の正のコンパイル時定数。

  • Base --

    ポリシーの合成に使用する。

    要件

    CallPolicies のモデル

    既定

    default_call_policies

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

namespace boost { namespace python
{
   template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
   struct with_custodian_and_ward_postcall : Base
   {
      static PyObject* postcall(PyObject* args, PyObject* result);
   };
}}

with_custodian_and_ward_postcall クラスの静的関数

PyObject *postcall(PyObject *args, PyObject *result)
要件

PyTuple_Check(args) != 0 かつ result != 0

効果

ward で指定した引数の寿命を custodian で指定した引数の寿命に依存させる。

戻り値

失敗時は 0PyErr_Occurred() != 0)。それ以外は true

以下はライブラリの return_internal_reference の実装に with_custodian_and_ward_postcall を使用している例である。

template <std::size_t owner_arg = 1, class Base = default_call_policies>
struct return_internal_reference
    : with_custodian_and_ward_postcall<0, owner_arg, Base>
{
   typedef reference_existing_object result_converter;
};
1

訳注 custodian および ward テンプレート引数に 0 や引数列の範囲を超える値を指定することはできません。また両者に同じ値を指定することもできません。

2

訳注 custodian および ward テンプレート引数に引数列の範囲を超える値を指定することはできません。また両者に同じ値を指定することもできません。