再帰的に分割可能な値のセットを表す型の要件。
次の表は、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 コンセプトをモデル化する TrivialIntegerRange 型を定義します。この型は、一桁の整数まで分割可能な半開区間 [lower,upper) を表します。分割は、基本分割コンストラクターまたは比例分割コンストラクターで行うことができます。基本分割コンストラクターは、範囲を半分に分割します。比例分割コンストラクターは、範囲を指定された比率 p で分割し、r を左部分に、新しく構築される TrivialIntegerRange を右部分にします。複雑な TrivialIntegerRange インスタンスが空にならないように特別な注意が払われています。
struct TrivialIntegerRange { int lower; int upper; bool empty() const {return lower==upper;} bool is_divisible() const {return upper>lower+1;} // 基本分割コンストラクター TrivialIntegerRange( TrivialIntegerRange& r, split ) { int m = (r.lower+r.upper)/2; lower = m; upper = r.upper; r.upper = m; } // オプションの比例分割コンストラクター TrivialIntegerRange( TrivialIntegerRange& r, proportional_split p ) { int m = ((r.lower+r.upper)*p.right())/(p.left()+p.right()); if (m == 0) m = 1; else if (m == r.upper) m = r.upper - 1; lower = m; upper = r.upper; r.upper = m; } // 比例分割を有効にするオプションの特性 static const bool is_splittable_in_proportion = true; };
TrivialIntegerRange はデモ用です。grainsize 引数がないため、あまり実用的ではありません。代わりに、blocked_range ライブラリー・クラスを使用してください。
blocked_range モデルは、1 次元の範囲をモデル化します。
blocked_range2d モデルは、2 次元の範囲をモデル化します。
blocked_range3d モデルは、3 次元の範囲をモデル化します。
Container Range コンセプトは、範囲としてコンテナーをモデル化します。