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に対して、
SliceSpecifiers...[k]がIndexTypeのsubmdspanスライス型であり、かつdecltype(slices...[k])がextents<IndexType, Extents...>のk番目次元の有効submdspanスライス型(validsubmdspanslice type)であること。
事前条件
srcの各次元インデクスkに対して、slices...[k]がsrcのk番目次元の有効submdspanスライス(valid submdspan slice)であること。
戻り値
説明用の型SubExtentsを、下記を満たすextentsの特殊化とする。
SubExtents::rank()がMAP_RANK(slices, Extents::rank())に等しく、かつslices...[k]の型が縮約スライス型(collapsing slice type)ではないExtentsの各次元インデクスkに対して、説明用のS_kをslices...[k]の型としたとき、SubExtents::static_extent(MAP_RANK(slices, k))が下記と等しいこと。- 型
S_kがfull_extent_tのとき、SubExtents::static_extent(k)、そうでなければ、 - 型
S_kがstrided_sliceの特殊化かつメンバ型S_k::extent_typeがconstant_wrapper<IndexType(0)>のとき、値0、そうでなければ - 型
S_kがstrided_sliceの特殊化かつメンバ型extent_typeおよびstride_typeがいずれもconstant_wrapperの特殊化であるとき、1 + ((S_k::extent_type::value - 1) / S_k::stride_type::value) - そうでなければ、
dynamic_extent
- 型
以下を満たすSubExtents型の値extを返す。
slices...[k]の型が縮約スライス型(collapsing slice type)ではないextents<IndexType, Extents...>の各次元インデクスkについて、説明用のs_kをslices...[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
処理系
- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??