namespace std::simd {
// 特殊なインデックス値
inline constexpr simd-size-type zero_element = /*処理系定義*/; // (1) C++26
inline constexpr simd-size-type uninit_element = /*処理系定義*/; // (2) C++26
// 静的置換
template<simd-size-type N = /*see below*/, simd-vec-type V, class IdxMap>
constexpr resize_t<N, V> permute(const V& v, IdxMap&& idxmap); // (3) C++26
template<simd-size-type N = /*see below*/, simd-mask-type V, class IdxMap>
constexpr resize_t<N, V> permute(const V& v, IdxMap&& idxmap); // (4) C++26
// 動的置換
template<simd-vec-type V, simd-integral I>
constexpr resize_t<I::size(), V> permute(const V& v, const I& indices); // (5) C++26
template<simd-mask-type V, simd-integral I>
constexpr resize_t<I::size(), V> permute(const V& v, const I& indices); // (6) C++26
}
概要
permuteは、basic_vecやbasic_maskの要素を、指定したインデックスのマッピングに従って並べ替える(置換する)関数である。結果の各要素は、元のデータ並列オブジェクトのいずれかの要素からコピーされる。
- (3), (4) 静的置換 : インデックスをマッピングする関数
idxmapを渡す。結果のi番目の要素は、元のオブジェクトのidxmap(i)番目(またはidxmap(i, V::size())番目)の要素で初期化される。マッピング関数はコンパイル時に評価される必要がある。テンプレート引数Nによって結果の要素数を変更でき、既定では元の要素数(V::size())となる - (5), (6) 動的置換 : インデックスをまとめたデータ並列型
indicesを渡す。結果のi番目の要素は、元のオブジェクトのindices[i]番目の要素で初期化される。インデックスは実行時に決定してよい。結果の要素数はindicesの要素数(I::size())となる
静的置換のマッピング関数idxmapは、通常のインデックスのほかに、以下の特殊値を返してよい。
- (1)
zero_element: その要素を、要素型のゼロ値(value_type())で初期化する - (2)
uninit_element: その要素を、未規定の値のままにする
テンプレートパラメータ制約
- (3), (4) :
std::invoke_result_t<IdxMap&, simd-size-type>とstd::invoke_result_t<IdxMap&, simd-size-type, simd-size-type>の少なくとも一方がstd::integralのモデルであること
適格要件
- (3), (4) : すべての
i([0, N)の範囲)について、idxmapを適用した結果が定数式であり、その値がzero_element・uninit_element・[0, V::size())の範囲のいずれかであること
事前条件
- (5), (6) :
indicesのすべての値が[0, V::size())の範囲にあること
戻り値
- (3), (4) :
i番目の要素が、idxmapの適用結果に応じて、元のオブジェクトの対応要素・ゼロ値・未規定値のいずれかで初期化されたデータ並列オブジェクト - (5), (6) :
i番目の要素がv[indices[i]]で初期化されたデータ並列オブジェクト
例外
投げない
例
#include <simd>
#include <print>
namespace simd = std::simd;
int main()
{
simd::vec<int, 4> v([](int i) { return i; }); // {0, 1, 2, 3}
// 静的置換: 逆順に並べ替える
auto r = simd::permute(v, [](int i) { return 3 - i; }); // {3, 2, 1, 0}
for (int i = 0; i < r.size(); ++i)
std::print("{} ", r[i]);
std::println("");
// 動的置換: 実行時のインデックスで並べ替える
simd::vec<int, 4> idx([](int i) { return (i + 1) % 4; }); // {1, 2, 3, 0}
auto d = simd::permute(v, idx); // {1, 2, 3, 0}
for (int i = 0; i < d.size(); ++i)
std::print("{} ", d[i]);
std::println("");
}
出力
3 2 1 0
1 2 3 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で
- P2664R11 Proposal to extend
std::simdwith permutation API- C++26で置換API(
permute)が追加された
- C++26で置換API(