最終更新日時:
が更新

履歴 編集

function template
<simd>

std::simd::partial_store(C++26)

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) : 連続範囲rstd::vectorstd::arraystd::spanなど)へ書き込む
  • (3), (4) : 先頭イテレータfirstと要素数nで指定した範囲へ書き込む
  • (5), (6) : 先頭イテレータfirstと番兵lastで指定した範囲へ書き込む

maskを受け取るオーバーロード (2), (4), (6) は、マスクの各要素がtrueである位置の要素のみを書き込む。

  • v : 書き込むデータ並列型の値
  • f : 書き込みの動作を指定するflagsオブジェクト。既定値はflag_default。要素型が異なるメモリへの変換書き込みを許可するflag_convertや、メモリのアライメントを仮定してより効率的な書き込みをおこなうflag_alignedflag_overaligned<N>を指定できる

unchecked_storeとの違いは、出力範囲の要素数が値の要素数より小さくてもよい点である。範囲外の位置へは書き込まれない。

テンプレートパラメータ制約

  • std::ranges::iterator_t<R>std::indirectly_writable<std::ranges::range_value_t<R>>のモデルであること
  • Tstd::ranges::range_value_t<R>へ明示的に変換可能であること

適格要件

  • std::ranges::range_value_t<R>「vectorizable type」であること
  • テンプレートパラメータパックFlagsflag_convertを含まない場合、Tからstd::ranges::range_value_t<R>への変換が値を保存すること

事前条件

  • (3), (4) : 範囲[first, first + n)が有効な範囲であること
  • (5), (6) : 範囲[first, last)が有効な範囲であること
  • Flagsflag_alignedを含む場合、std::ranges::data(r)alignment_v<basic_vec<T, Abi>, std::ranges::range_value_t<R>>でアライメントされた領域を指すこと
  • Flagsflag_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

処理系

関連項目

参照