namespace std::simd {
template<class T,
class Abi,
ranges::contiguous_range R,
class... Flags>
requires ranges::sized_range<R>
constexpr void
partial_store(const basic_vec<T, Abi>& v,
R&& r,
flags<Flags...> f = {}); // (1) C++26
template<class T,
class Abi,
ranges::contiguous_range R,
class... Flags>
requires ranges::sized_range<R>
constexpr void
partial_store(const basic_vec<T, Abi>& v,
R&& r,
const typename basic_vec<T, Abi>::mask_type& mask,
flags<Flags...> f = {}); // (2) C++26
template<class T,
class Abi,
contiguous_iterator I,
class... Flags>
constexpr void
partial_store(const basic_vec<T, Abi>& v,
I first,
iter_difference_t<I> n,
flags<Flags...> f = {}); // (3) C++26
template<class T,
class Abi,
contiguous_iterator I,
class... Flags>
constexpr void
partial_store(const basic_vec<T, Abi>& v,
I first,
iter_difference_t<I> n,
const typename basic_vec<T, Abi>::mask_type& mask,
flags<Flags...> f = {}); // (4) C++26
template<class T,
class Abi,
contiguous_iterator I,
sized_sentinel_for<I> S,
class... Flags>
constexpr void
partial_store(const basic_vec<T, Abi>& v,
I first,
S last,
flags<Flags...> f = {}); // (5) C++26
template<class T,
class Abi,
contiguous_iterator I,
sized_sentinel_for<I> S,
class... Flags>
constexpr void
partial_store(const basic_vec<T, Abi>& v,
I first,
S last,
const typename basic_vec<T, Abi>::mask_type& mask,
flags<Flags...> f = {}); // (6) C++26
}
概要
basic_vecの要素を、連続したメモリ領域へまとめて書き込む。出力範囲の要素数が値の要素数に満たない場合でも安全に書き込め、範囲を超える位置の要素は書き込まれない。
出力範囲の指定方法によって、以下のオーバーロードがある。
- (1), (2) : 連続範囲
r(std::vectorやstd::array、std::spanなど)へ書き込む - (3), (4) : 先頭イテレータ
firstと要素数nで指定した範囲へ書き込む - (5), (6) : 先頭イテレータ
firstと番兵lastで指定した範囲へ書き込む
maskを受け取るオーバーロード (2), (4), (6) は、マスクの各要素がtrueである位置の要素のみを書き込む。
v: 書き込むデータ並列型の値f: 書き込みの動作を指定するflagsオブジェクト。既定値はflag_default。要素型が異なるメモリへの変換書き込みを許可するflag_convertや、メモリのアライメントを仮定してより効率的な書き込みをおこなうflag_aligned/flag_overaligned<N>を指定できる
unchecked_storeとの違いは、出力範囲の要素数が値の要素数より小さくてもよい点である。範囲外の位置へは書き込まれない。
テンプレートパラメータ制約
std::ranges::iterator_t<R>がstd::indirectly_writable<std::ranges::range_value_t<R>>のモデルであることTがstd::ranges::range_value_t<R>へ明示的に変換可能であること
適格要件
std::ranges::range_value_t<R>が「vectorizable type」であること- テンプレートパラメータパック
Flagsがflag_convertを含まない場合、Tからstd::ranges::range_value_t<R>への変換が値を保存すること
事前条件
- (3), (4) : 範囲
[first, first + n)が有効な範囲であること - (5), (6) : 範囲
[first, last)が有効な範囲であること Flagsがflag_alignedを含む場合、std::ranges::data(r)がalignment_v<basic_vec<T, Abi>, std::ranges::range_value_t<R>>でアライメントされた領域を指すことFlagsがflag_overaligned<N>を含む場合、std::ranges::data(r)がNでアライメントされた領域を指すこと
効果
0以上basic_vec<T, Abi>::size()未満の各iについて、mask[i] && i < std::ranges::size(r)がtrueであれば、以下を評価する。
ranges::data(r)[i] = static_cast<ranges::range_value_t<R>>(v[i]);
戻り値
なし。
例
#include <simd>
#include <array>
#include <print>
namespace simd = std::simd;
int main()
{
simd::vec<int, 4> v([](int i) { return (i + 1) * 10; }); // {10, 20, 30, 40}
// 出力範囲(2要素)は値の要素数(4)より小さくてもよい
std::array<int, 2> data{};
simd::partial_store(v, data);
for (int x : data) {
std::print("{} ", x);
}
std::println("");
}
出力
10 20
バージョン
言語
- 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で