再帰的に分割可能な値のセットを表す型の要件。
次の表は、Range 型 R の要件を示しています。
擬似署名 |
意味 |
---|---|
R::R( const R& ) |
コピー・コンストラクター。 |
R::~R() |
デストラクター。 |
bool R::empty() const |
範囲が空の場合は true です。 |
bool R::is_divisible() const |
範囲を 2 つのサブ範囲に分割できる場合は true です。 |
R::R( R& r, split ) |
基本分割コンストラクター。r を 2 つのサブ範囲に分割します。 |
R::R( R& r, proportional_split proportion ) |
オプション。比例分割コンストラクター。r を proportion に応じて 2 つのサブ範囲に分割します。 |
static const bool R::is_splittable_in_proportion |
オプション。true の場合、範囲の比例分割コンストラクターが定義され、並列アルゴリズムで使用されます。 |
Range は 2 つの部分に再帰的に再分割することができます。再分割は、Range の分割コンストラクターを呼び出して行います。次の 2 種類の分割コンストラクターがあります。
理想的には、それ以上分割するよりもシリアルに実行するほうが効率的な大きさになるまで再帰分割します。Range によって表現されるワークの量はより上位レベルのコンテキストに依存します。したがって、Range をモデル化する典型的な型は、分割する大きさを制御する方法を提供すべきです。例えば、blocked_range テンプレート・クラスには、それ以上分割できない最も大きな範囲を示す grainsize 引数があります。
値のセットに方向性がある場合、分割コンストラクターは範囲の 2 番目の部分を構築して、範囲の最初の部分になるように引数を更新します。この処理により、シリアルに実行する場合、parallel_for、parallel_reduce、および parallel_scan アルゴリズムは通常のシーケンシャル・ループが増加する順番で範囲全体にわたって動作します。
Range は、分割およびコピー・コンストラクターを宣言するため、Range のデフォルト・コンストラクターは自動生成されません。プログラムで Range 型のインスタンスを作成するには、明示的にデフォルト・コンストラクターを定義するか、ほかのコンストラクターを追加する必要があります。
次のコードは、Range コンセプトをモデル化する TrivialNaturalRange 型を定義します。この型は、単一の自然数まで分割可能な半開区間 [lower,upper) を表します。分割は、基本分割コンストラクターまたは比例分割コンストラクターで行うことができます。基本分割コンストラクターは、範囲を半分に分割します。比例分割コンストラクターは、範囲を指定された比率 p で分割し、r を左部分に、新しく構築される TrivialNaturalRange を右部分にします。複雑な TrivialNaturalRange インスタンスが空にならないように特別な注意が払われています。
#include <tbb/tbb_stddef.h> // for split tags struct TrivialNaturalRange { // restore the default constructor TrivialNaturalRange() {} size_t lower; size_t upper; bool empty() const { return lower == upper; } bool is_divisible() const { return upper > lower + 1; } // basic splitting constructor TrivialNaturalRange(TrivialNaturalRange& r, tbb::split) { size_t m = r.lower + (r.upper - r.lower) / 2; upper = r.upper; r.upper = lower = m; } // optional proportional splitting constructor TrivialNaturalRange(TrivialNaturalRange& r, tbb::proportional_split p) { size_t m = r.lower + ((r.upper - r.lower) * p.left()) / (p.left() + p.right()); if (m == r.lower) m++; else if (m == r.upper) m--; upper = r.upper; r.upper = lower = m; } // optional trait that enables proportional split static const bool is_splittable_in_proportion = true; };
TrivialNaturalRange は説明目的のためのものであり、実用的ではありません。代わりに、blocked_range ライブラリー・クラスを使用してください。
blocked_range は、1 次元の範囲をモデル化します。
blocked_range2d は、2 次元の範囲をモデル化します。
blocked_range3d は、3 次元の範囲をモデル化します。
blocked_rangeNd は、N 次元の範囲をモデル化します (プレビュー機能)。
Container Range コンセプトは、範囲としてコンテナーをモデル化します。