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 のモデル
- 既定
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
で指定した引数の寿命に依存させる。- 戻り値
失敗時は
false
(PyErr_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
のモデル- 既定
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
で指定した引数の寿命に依存させる。- 戻り値
失敗時は
0
(PyErr_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;
};