- mdspan[meta header]
- function template[meta id-type]
- std[meta namespace]
- cpp26[meta cpp]
namespace std {
template<class IndexType, class... Extents, class... SliceSpecifiers>
constexpr auto subextents(const extents<IndexType, Extents...>& src,
SliceSpecifiers... raw_slices);
}- extents[link extents.md]
多次元配列サイズextentsと各次元からの要素取り出し(スライス)方式を指定して、新しい多次元配列サイズextentsを取得する。
各次元からの要素取り出し方式は、submdspanを参照のこと。
説明用のパックslicesを以下の通り宣言する。
auto [...slices] = canonical_slices(src, raw_slices...);- canonical_slices[link canonical_slices.md]
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のとき、Extents::static_extent(k)、そうでなければ、 - 型
S_kがextent_sliceの特殊化かつメンバ型S_k::extent_typeがconstant_wrapperの特殊化であるとき、S_k::extent_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の型がextent_sliceの特殊化であるとき、s_k.extent- そうでなければ、
srcのk番目の要素に対してsubmdspanスライス範囲である半開区間[L, U)に対して、U - L
#include <cassert>
#include <concepts>
#include <mdspan>
#include <type_traits>
#include <utility>
template <int N>
constexpr auto Int = std::integral_constant<int, N>{};
int main()
{
std::extents<size_t, 10> exts{};
auto ext0 = std::subextents(exts, 0);
static_assert(std::same_as<decltype(ext0), std::extents<size_t>>);
auto ext1 = std::subextents(exts, std::full_extent);
static_assert(std::same_as<decltype(ext1), std::extents<size_t, 10>>);
auto ext2 = std::subextents(exts, std::pair{Int<2>, Int<8>});
static_assert(std::same_as<decltype(ext2), std::extents<size_t, 6>>);
auto ext3 = std::subextents(exts, std::extent_slice{0, Int<0>, 1});
static_assert(std::same_as<decltype(ext3), std::extents<size_t, 0>>);
auto ext4 = std::subextents(exts, std::extent_slice{0, Int<4>, 3});
static_assert(std::same_as<decltype(ext4), std::extents<size_t, 4>>);
auto ext5 = std::subextents(exts, std::pair{2, 8});
static_assert(std::same_as<decltype(ext5), std::dextents<size_t, 1>>);
assert(ext5.extent(0) == 6);
}- std::subextents[color ff0000]
- std::full_extent[link full_extent_t.md]
- std::extent_slice[link extent_slice.md]
- std::integral_constant[link /reference/type_traits/integral_constant.md]
- C++26
- Clang: ??
- GCC: 17 [mark verified]
- Visual C++: ??
- P2630R4 Submdspan
- P3663R3 Future-proof
submdspan_mapping - LWG Issue 4491. Rename
submdspan_extentsandsubmdspan_canonicalize_slices- この関数はC++26のリリース前に
submdspan_extentsからsubextentsへ改名された
- この関数はC++26のリリース前に
- P3982R2 Split
strided_sliceintoextent_sliceandrange_slicefor C++26- C++26のリリース前に、
extent_sliceのextentメンバ変数が取り出す要素数を表すようになったことで、戻り値の要素数がストライド幅による除算なしで求まるようになった
- C++26のリリース前に、