namespace std::simd {
template<class V = /*see below*/, ranges::contiguous_range R,
simd-integral I, class... Flags>
requires ranges::sized_range<R>
constexpr V
partial_gather_from(R&& in,
const I& indices,
flags<Flags...> f = {}); // (1) C++26
template<class V = /*see below*/, ranges::contiguous_range R,
simd-integral I, class... Flags>
requires ranges::sized_range<R>
constexpr V
partial_gather_from(R&& in,
const typename I::mask_type& mask,
const I& indices,
flags<Flags...> f = {}); // (2) C++26
}
概要
連続したメモリ領域inから、インデックスを表すデータ並列型indicesで指定した飛び飛びの位置の要素を集めて(gather)、basic_vecへ読み込む。結果のi番目の要素は、inのindices[i]番目の要素となる。インデックスが範囲外を指す場合でも安全に読み込め、その位置は値初期化された値(0など)となる。
- (1) : 全要素を集める
-
(2) :
maskの各要素がtrueである位置の要素のみを集め、falseの位置は値初期化された値とする -
V: 結果のデータ並列型。省略した場合はvec<std::ranges::range_value_t<R>, I::size()>が使われる indices: 各要素が読み込み位置のインデックスを表す、整数要素のデータ並列型f: gatherの動作を指定するflagsオブジェクト。既定値はflag_default。要素型が異なるメモリからの変換読み込みを許可するflag_convertや、メモリのアライメントを仮定するflag_aligned/flag_overaligned<N>を指定できる
unchecked_gather_fromとの違いは、インデックスがinの範囲外を指してもよい点である。範囲外の位置は読み込まれず、値初期化される。
テンプレートパラメータ制約
std::ranges::range_value_t<R>が「vectorizable type」であり、V::value_typeへ明示的に変換可能であること。
適格要件
std::ranges::range_value_t<R>が「vectorizable type」であることVがbasic_vecの有効な特殊化であることV::size() == I::size()がtrueであること- テンプレートパラメータパック
Flagsがflag_convertを含まない場合、std::ranges::range_value_t<R>からV::value_typeへの変換が値を保存すること
事前条件
Flagsがflag_alignedを含む場合、std::ranges::data(in)がalignment_v<V, std::ranges::range_value_t<R>>でアライメントされた領域を指すことFlagsがflag_overaligned<N>を含む場合、std::ranges::data(in)がNでアライメントされた領域を指すこと
戻り値
i番目の要素が、0以上I::size()未満の各iについて以下で初期化されたbasic_vecオブジェクト。ここでTはV::value_typeである。
mask[i] && indices[i] < ranges::size(in) ? static_cast<T>(ranges::data(in)[indices[i]]) : T()
例
#include <simd>
#include <array>
#include <print>
namespace simd = std::simd;
int main()
{
std::array<int, 4> data = {10, 11, 12, 13};
// インデックス {0, 2, 4, 6} のうち、範囲外(4, 6)は値初期化(0)となる
simd::vec<int, 4> indices([](int i) { return i * 2; });
auto v = simd::partial_gather_from<simd::vec<int, 4>>(data, indices);
for (int i = 0; i < v.size(); ++i) {
std::print("{} ", v[i]);
}
std::println("");
}
出力
10 12 0 0
バージョン
言語
- C++26
処理系
- Clang: 22 ❌
- GCC: 16.1 ❌
- Visual C++: 2026 Update 2 ❌
関連項目
参照
- P1928R15 std::simd — merge data-parallel types from the Parallelism TS 2
- C++26で
std::simdライブラリに追加された
- C++26で