最終更新日時(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... raw_slices);
}

概要

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

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

説明用のパックslicesを以下の通り宣言する。

auto [...slices] = submdspan_canonicalize_slices(src, raw_slices...);

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

sizeof...(SliceSpecifiers)sizeof...(Extents)と等しいこと。

適格要件

srcの各次元インデクスkに対して、

事前条件

srcの各次元インデクスkに対して、slices...[k]srcのk番目次元の有効submdspanスライス(valid submdspan slice)であること。

戻り値

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

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

  • slices...[k]の型が縮約スライス型(collapsing slice type)ではないextents<IndexType, Extents...>の各次元インデクスkについて、説明用のs_kslices...[k]としたとき、ext.extent(MAP_RANK(slices, k))が下記に等しいこと。
    • s_kの型がstrided_sliceの特殊化であるとき、s_k.extent == 0 ? 0 : 1 + (s_k.extent - 1) / s_k.stride
    • そうでなければ、srcのk番目の要素に対してsubmdspanスライス範囲である半開区間[L, U)に対して、U - L

#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

処理系

関連項目

参照