boost/python/slice.hpp
はじめに
Python の slice 型に対する TypeWrapper をエクスポートする。
クラス
slice
クラス
-
class slice : public object
Python の組み込み
slice
型をラップして拡張スライシングプロトコルをエクスポートする。インターフェイス以下に定義するコンストラクタとメンバ関数のセマンティクスを完全に理解するには、TypeWrapper コンセプトの定義を読むことである。slice
はobject
から公開派生しているので、object
の公開インターフェイスはslice
のインスタンスにも当てはまる。
slice
クラスの概要
namespace boost { namespace python
{
class slice : public object
{
public:
slice(); // 空の slice を作成する。[::] と等価
template <typename Int1, typename Int2>
slice(Int1 start, Int2 stop);
template <typename Int1, typename Int2, typename Int3>
slice(Int1 start, Int2 stop, Int3 step);
// この slice を作成したときの引数にアクセスする。
object start();
object stop();
object step();
// slice::get_indices() の戻り値の型
template <typename RandomAccessIterator>
struct range
{
RandomAccessIterator start;
RandomAccessIterator stop;
int step;
};
template <typename RandomAccessIterator>
range<RandomAccessIterator>
get_indices(
RandomAccessIterator const& begin,
RandomAccessIterator const& end);
};
}}
slice
クラスのコンストラクタ
-
slice()
- 効果
既定の stop 、start 、step 値で
slice
を構築する。Pythonの式base[::]
で作成したスライスオブジェクトと等価。- 例外
なし。
-
template<typename Int1, typename Int2>
slice(Int1 start, Int2 stop) start
およびstop
はslice_nil
型、またはobject
型へ変換可能。- 効果
既定の step 値と与えられた
start
、stop
値で新しいslice
を構築する。Python の組み込み関数 slice(start, stop) 、または Python の式base[start:stop]
で作成したスライスオブジェクトと等価。- 例外
error_already_set -- 引数を
object
型へ変換できない場合(Python のTypeError
例外を設定する)。
-
template<typename Int1, typename Int2, typename Int3>
slice(Int1 start, Int2 stop, Int3 step) - 要件
start
、stop
およびstep
はslice_nil
、またはobject
型へ変換可能。- 効果
start
、stop
、step
値で新しいslice
を構築する。Python の組み込み関数 slice(start, stop, step) 、または Python の式base[start:stop:step]
で作成したスライスオブジェクトと等価。- 例外
error_already_set -- 引数を
object
型へ変換できない場合(Python のTypeError
例外を設定する)。
slice
クラスのオブザーバ関数
-
object start() const
-
object stop() const
-
object step() const
- 効果
なし。
- 例外
なし。
- 戻り値
スライスを作成したときに使用した引数。スライスを作成したときに引数を省略したか
slice_nil
を使用した場合、その引数はPy_None
への参照でありデフォルトコンストラクトされたobject
と等値である。原則的にはスライスオブジェクトを作成するのに任意の型を使用できるが、現実的には大抵は整数である。
-
template<typename RandomAccessIterator>
range<RandomAccessIterator> get_indices(RandomAccessIterator const &begin, RandomAccessIterator const &end) const - Param
半開区間を形成する STL 準拠のランダムアクセスイテレータの組。
- 効果
引数の
[begin,end)
範囲内の完全閉範囲を定義する RandomAccessIterator の組を作成する。Py_None
か負の添字の効果、および 1 以外の step サイズをどう扱うか説明を求められたときに、この関数がスライスの添字を変換する。- 戻り値
非 0 の step 値と、この関数の引数が与える範囲を指し閉区間を定義する RandomAccessIterator の組で初期化した
slice::range
。- 例外
error_already_set -- このスライスの引数が
Py_None
への参照でもint
へ変換可能でもない場合。Python のTypeError
例外を:term:送出する。std::invalid_argument -- 結果の範囲が空の場合。
slice::get_indices
を呼び出すときは常にtry { ...; } catch (std::invalid_argument) {}
で囲んでこのケースを処理し適切に処置しなければならない。
- 根拠
閉区間。開空間を使ったとすると、step サイズが 1 以外の場合、終端のイテレータが末尾の直後より後方の位置や指定した範囲より前方を指す状態が必要となる。
空のスライスに対する例外。空の範囲を表す閉区間を定義することは不可能であるので、未定義の動作を防止するために他の形式のエラーチェックが必要となる。例外が捕捉されない場合、単に既定の例外処理機構により Python に変換される。
例
using namespace boost::python;
// Python リストの拡張スライス。
// 警告:組み込み型に対する拡張スライシングは Python 2.3 より前ではサポートされていない
list odd_elements(list l)
{
return l[slice(_,_,2)];
}
// std::vector のスライスに対して合計をとる。
double partial_sum(std::vector<double> const& Foo, const slice index)
{
slice::range<std::vector<double>::const_iterator> bounds;
try {
bounds = index.get_indices<>(Foo.begin(), Foo.end());
}
catch (std::invalid_argument) {
return 0.0;
}
double sum = 0.0;
while (bounds.start != bounds.stop) {
sum += *bounds.start;
std::advance( bounds.start, bounds.step);
}
sum += *bounds.start;
return sum;
}