boost/python/iterator.hpp
はじめに
<boost/python/iterator.hpp>
は、C++ のコンテナとイテレータから Python のイテレータを作成するための型と関数を提供する。ある class_
がランダムアクセスイテレータをサポートする場合、この機能を使用するより __getitem__(シーケンスプロトコルともいう)を実装したほうがよい。Python は自動的にイテレータ型を作成し(iter() を見よ)、各アクセスは範囲チェックが行われ、不正な C++ イテレータを介してアクセスする可能性もない。
クラス
iterator
クラステンプレート
-
template<class Container, class NextPolicies = unspecified>
struct iterator : object iterator<C, P>
のインスタンスは、呼び出し可能な Python オブジェクトへの参照を保持する。このオブジェクトは Python から呼び出され、C
へ変換可能な単一の引数c
を受け取り、[c.begin(),c.end()) を走査する Python イテレータを作成する。省略可能な CallPolicies であるP
は、走査中に要素をどのように返すか制御するのに使用する。以下の説明において、
c
はContainer
のインスタンスである。- テンプレートパラメータ
Container --
結果はその引数を
c
に変換し、c.begin() および c.end() を呼び出しイテレータを得る。Container
のconst
版begin
およびend
関数を呼び出すにはconst
でなければならない。- 要件
[c.begin(),c.end()) が合法なイテレータ範囲である。
NextPolicies --
結果のイテレータの
next
メソッドに適用される。- 要件
CallPolicies のデフォルトコンストラクト可能なモデル。
- 既定
常に内部的な C++ イテレータを逆参照した結果のコピーを作成する、未規定の CallPolicies モデル。
iterator
クラステンプレートの概要
namespace boost { namespace python
{
template <class Container
, class NextPolicies = unspecified>
struct iterator : object
{
iterator();
};
}}
iterator
クラステンプレートのコンストラクタ
-
iterator()
- 効果
基底クラスを以下の結果で初期化する。
range<NextPolicies>(&iterators<Container>::begin, &iterators<Container>::end)
- 事後条件
this->get() は、上記のとおり Python のイテレータを作成する Python の呼び出し可能オブジェクトを指す。
- 根拠
ラップする C++ クラスが
begin
およびend
を持つようなありふれた場合について、イテレータを容易に作成する方法を提供する。
iterators
クラステンプレート
-
template<class C>
struct iterators 引数の
begin
およびend
メンバ関数を確実に呼び出す方法を提供するユーティリティクラスである。C++ 標準ライブラリにおけるコンテナについて、メンバ関数のアドレスを取る移植可能な方法はないので、それらをラップする場合にiterators<>
は特に有効である。以下の表において、
x
はC
のインスタンスである。要求する合法な式
型
x.begin()
C
がconst
な型であればC::const_iterator
へ変換可能。そうでなければC::iterator
へ変換可能。x.end()
C
がconst
な型であればC::const_iterator
へ変換可能。そうでなければC::iterator
へ変換可能。
iterators
クラステンプレートの概要
namespace boost { namespace python
{
template <class C>
struct iterators
{
typedef typename C::[const_]iterator iterator;
static iterator begin(C& x);
static iterator end(C& x);
};
}}
iterators
クラステンプレートの入れ子型
C
が const
型の場合、
typedef typename C::const_iterator iterator;
それ以外の場合、
typedef typename C::iterator iterator;
iterators
クラステンプレートの静的関数
関数
-
template<class NextPolicies, class Target, class Accessor1, class Accessor2>
object range(Accessor1 start, Accessor2 finish) -
template<class NextPolicies, class Accessor1, class Accessor2>
object range(Accessor1 start, Accessor2 finish) -
template<class Accessor1, class Accessor2>
object range(Accessor1 start, Accessor2 finish) - 要件
NextPolicies
は、デフォルトコンストラクト可能な CallPolicies モデル。- 効果
第 1 形式は Python の呼び出し可能オブジェクトを作成する。このオブジェクトは呼び出されるとその引数を
Target
オブジェクトx
に変換し、[bind(start, _1)(x),bind(finish, _1)(x)) を走査する Python のイテレータを作成する。イテレータのnext
関数にはNextPolicies
を適用する。第 2 形式は、以下のようにAccessor1
からTarget
を推論する点以外は第 1 形式と同じである。Accessor1
が関数型の場合、Target
はその第 1 引数の型。Accessor1
がデータメンバポインタR (T::*)
の場合、Target
はT
と同じ。Accessor1
がメンバ関数ポインタR (T::*)(arguments...) cv-opt
(cv-opt
は省略可能なcv-qualifier
)の場合、Target
はT
と同じ。
第 3 形式は、
NextPolicies
が常に内部的な C++ イテレータを逆参照した結果のコピーを作成する CallPolicies の未規定のモデルであること以外は第 2 形式と同じである。- 根拠
boost::bind() を使用することで、関数、メンバ関数、データメンバポインタを通じて C++ イテレータへアクセスできる。ラップしたクラス型のシーケンス要素のコピーが高コストな場合、
NextPolicies
のカスタマイズが有効である(例えばreturn_internal_reference
を使用する)。Accessor1
が関数オブジェクトであるか、対象型の基底クラスが他から推論される場合は、Target
のカスタマイズが有効である。
例
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <vector>
using namespace boost::python;
BOOST_PYTHON_MODULE(demo)
{
class_<std::vector<double> >("dvec")
.def("__iter__", iterator<std::vector<double> >())
;
}
より包括的な例が以下にある。
http://www.boost.org/libs/python/test/iterator.cpp
http://www.boost.org/libs/python/test/input_iterator.cpp
http://www.boost.org/libs/python/test/input_iterator.py