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:SliceSpecifiersのk番目の型 - 値
s_k:slicesのk番目の値 - 値
map-rank:k番目の要素map-rank[k]が下記を満たす、array<size_t, sizeof...(SliceSpecifiers)>型の配列値- 型
S_kがconvertible_to<IndexType>のモデルのときdynamic_extent、そうでなければ j < kにおいて型S_jがconvertible_to<IndexType>のモデルではない個数
- 型
動作説明用の配列map-rank[]は、変換元の次元インデクスkから変換先の次元インデクスへの対応関係を表現している。要素値dynamic_extentは変換により削減される次元を表す。
テンプレートパラメータ制約
sizeof...(slices)がExtents::rank()と等しいこと。
適格要件
srcの各次元インデクスkに対して、下記いずれかのうち1つだけを満たすこと。
- 型
S_kがconvertible_to<IndexType>のモデル - 型
S_kがindex-pair-like<IndexType>のモデル is_convertible_v<S_k, full_extent_t>がtrue- 型
S_kがstrided_sliceの特殊化
事前条件
srcの各次元インデクスkに対して、下記を全て満たすこと。
- 型
S_kがstrided_sliceの特殊化のときs_k.extent == 0、またはs_k.stride > 0
0≤first_<IndexType, k>(slices...)≤last_<k>(src, slices...)≤src.extent(k)
戻り値
説明用の型SubExtentsを、下記を満たすextentsの特殊化とする。
SubExtents::rank()は、型S_kがconvertible_to<IndexType>のモデルではないkの個数に等しく、かつmap-rank[k] != dynamic_extentを満たすExtentsの次元インデクスkについて、SubExtents::static_extent(map-rank[k])が下記と等しいことis_convertible_v<S_k, full_extent_t>がtrueのとき、SubExtents::static_extent(k)、そうでなければ、- 型
S_kがindex-pair-likeのモデルかつtuple_element_t<0, S_k>およびtuple_element_t<1, S_k>がいずれもintegral-constant-likeのモデルであるとき、de-ice(tuple_element_t<1, S_k>) - de-ice(tuple_element_t<0, S_k>)、そうでなければ - 型
S_kがstrided_sliceの特殊化かつメンバ型extent_typeがS_k::extent_type() == 0かつintegral-constant-likeのモデルであるとき、値0、そうでなければ - 型
S_kがstrided_sliceの特殊化かつメンバ型extent_typeおよびstride_typeがいずれもintegral-constant-likeのモデルであるとき、1 + (de-ice(S_k::extent_type()) - 1) / de-ice(S_k::stride_type())、そうでなければ dynamic_extent
以下を満たすSubExtents型の値extを返す。
map-rank[k] != dynamic_extentを満たす次元インデクスkについて、ext.extent(map-rank[k])が下記に等しいこと- 型
S_kがstrided_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
処理系
- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??