最終更新日時(UTC):
が更新

履歴 編集

function template
<mdspan>

std::submdspan_extents(C++26)

namespace std {
  template<class IndexType, class ... Extents, class ... SliceSpecifiers>
  constexpr auto submdspan_extents(const extents<IndexType, Extents...>& src, SliceSpecifiers ... slices);
}

概要

多次元配列サイズextentsと各次元からの要素取り出し(スライス)方式を指定して、新しい多次元配列サイズextentsを取得する。

各次元からの要素取り出し方式は、submdspanを参照のこと。

動作説明用

  • S_k : SliceSpecifiersk番目の型
  • s_k : slicesk番目の値
  • map-rank : k番目の要素map-rank[k]が下記を満たす、array<size_t, sizeof...(SliceSpecifiers)>型の配列値

動作説明用の配列map-rank[]は、変換元の次元インデクスkから変換先の次元インデクスへの対応関係を表現している。要素値dynamic_extentは変換により削減される次元を表す。

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

sizeof...(slices)Extents::rank()と等しいこと。

適格要件

srcの各次元インデクスkに対して、下記いずれかのうち1つだけを満たすこと。

事前条件

srcの各次元インデクスkに対して、下記を全て満たすこと。

戻り値

説明用の型SubExtentsを、下記を満たすextentsの特殊化とする。

以下を満たすSubExtents型の値extを返す。

  • map-rank[k] != dynamic_extentを満たす次元インデクスkについて、ext.extent(map-rank[k])が下記に等しいこと
    • S_kstrided_sliceの特殊化であるとき、s_k.extent == 0 ? 0 : 1 + (de-ice(s_k.extent) - 1) / de-ice(s_k.stride)
    • そうでなければ、last_<k>(src, slices...) - first_<IndexType, k>(slices...)

#include <cassert>
#include <concepts>
#include <mdspan>
#include <type_traits>

template <int N>
constexpr auto Int = std::integral_constant<int, N>{};

int main()
{
  std::extents<size_t, 10> exts{};

  auto ext0 = std::submdspan_extents(exts, 0);
  static_assert(std::same_as<decltype(ext0), std::extents<size_t>>);

  auto ext1 = std::submdspan_extents(exts, std::full_extent);
  static_assert(std::same_as<decltype(ext1), std::extents<size_t, 10>>);

  auto ext2 = std::submdspan_extents(exts, std::pair{Int<2>, Int<8>});
  static_assert(std::same_as<decltype(ext2), std::extents<size_t, 6>>);

  auto ext3 = std::submdspan_extents(exts, std::strided_slice{0, Int<0>, 1});
  static_assert(std::same_as<decltype(ext3), std::dextents<size_t, 1>>);
  assert(ext3.extent(0) == 0);

  auto ext4 = std::submdspan_extents(exts, std::strided_slice{0, Int<10>, Int<3>});
  static_assert(std::same_as<decltype(ext4), std::extents<size_t, 4>>);

  auto ext5 = std::submdspan_extents(exts, std::pair{2, 8});
  static_assert(std::same_as<decltype(ext5), std::dextents<size_t, 1>>);
  assert(ext5.extent(0) == 6);
}

出力

バージョン

言語

  • C++26

処理系

関連項目

参照