最終更新日時:
が更新

履歴 編集

function template
<simd>

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

namespace std::simd {
  template<class V = /*see below*/,
           ranges::contiguous_range R,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr V
    partial_load(R&& r,
                 flags<Flags...> f = {});  // (1) C++26

  template<class V = /*see below*/,
           ranges::contiguous_range R,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr V
    partial_load(R&& r,
                 const typename V::mask_type& mask,
                 flags<Flags...> f = {});  // (2) C++26

  template<class V = /*see below*/,
           contiguous_iterator I,
           class... Flags>
  constexpr V
    partial_load(I first,
                 iter_difference_t<I> n,
                 flags<Flags...> f = {});  // (3) C++26

  template<class V = /*see below*/,
           contiguous_iterator I,
           class... Flags>
  constexpr V
    partial_load(I first,
                 iter_difference_t<I> n,
                 const typename V::mask_type& mask,
                 flags<Flags...> f = {});  // (4) C++26

  template<class V = /*see below*/,
           contiguous_iterator I,
           sized_sentinel_for<I> S,
           class... Flags>
  constexpr V
    partial_load(I first,
                 S last,
                 flags<Flags...> f = {});  // (5) C++26

  template<class V = /*see below*/,
           contiguous_iterator I,
           sized_sentinel_for<I> S,
           class... Flags>
  constexpr V
    partial_load(I first,
                 S last,
                 const typename V::mask_type& mask,
                 flags<Flags...> f = {});  // (6) C++26
}

概要

連続したメモリ領域からbasic_vecへ、要素をまとめて読み込む。入力範囲の要素数が結果の要素数に満たない場合でも安全に読み込め、範囲を超える位置の要素は値初期化された値(0など)となる。

入力範囲の指定方法によって、以下のオーバーロードがある。

  • (1), (2) : 連続範囲rstd::vectorstd::arraystd::spanなど)から読み込む
  • (3), (4) : 先頭イテレータfirstと要素数nで指定した範囲から読み込む
  • (5), (6) : 先頭イテレータfirstと番兵lastで指定した範囲から読み込む

maskを受け取るオーバーロード (2), (4), (6) は、マスクの各要素がtrueである位置の要素のみを読み込み、falseの位置は値初期化された値とする。

  • V : 結果のデータ並列型。省略した場合はbasic_vec<std::ranges::range_value_t<R>>(先頭イテレータ版ではbasic_vec<iter_value_t<I>>)が使われる
  • f : 読み込みの動作を指定するflagsオブジェクト。既定値はflag_default。要素型が異なるメモリからの変換読み込みを許可するflag_convertや、メモリのアライメントを仮定してより効率的な読み込みをおこなうflag_alignedflag_overaligned<N>を指定できる

unchecked_loadとの違いは、入力範囲の要素数が結果の要素数より小さくてもよい点である。範囲外の位置は読み込まれず、値初期化される。

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

  • std::ranges::range_value_t<R>「vectorizable type」であり、V::value_typeへ明示的に変換可能であること
  • Vbasic_vecの有効な特殊化であること
  • テンプレートパラメータパックFlagsflag_convertを含まない場合、std::ranges::range_value_t<R>からV::value_typeへの変換が値を保存すること

事前条件

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

戻り値

i番目の要素が、0以上V::size()未満の各iについて以下で初期化されたbasic_vecオブジェクト。ここでTV::value_typeである。

mask[i] && i < ranges::size(r) ? static_cast<T>(ranges::data(r)[i]) : T()

#include <simd>
#include <array>
#include <print>

namespace simd = std::simd;

int main()
{
  // 要素数が結果の要素数(4)に満たない配列
  std::array<int, 2> data = {1, 2};

  // 不足分は値初期化(0)となる
  auto v = simd::partial_load<simd::vec<int, 4>>(data);

  for (int i = 0; i < v.size(); ++i) {
    std::print("{} ", v[i]);
  }
  std::println("");
}

出力

1 2 0 0 

バージョン

言語

  • C++26

処理系

関連項目

参照