最終更新日時:
が更新

履歴 編集

function template
<mdspan>

std::canonical_slices(C++26)

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

概要

多次元配列サイズextentsと各次元からの要素取り出し(スライス)情報を正規化する。

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

submdspanスライス型

符号付きもしくは符号なし整数型IndexTypeに対して、下記のうち少なくとも1つを満たすとき、型SはIndexTypeのsubmdspanスライス型(submdspan slice type)となる。

  • is_convertible_v<S, full_extent_t>がtrue
  • is_convertible_v<S, IndexType>がtrue
  • Sがextent_sliceの特殊化であり、XがS::offset_type, S::extent_type, S::stride_typeを表すときis_convertible_v<X, IndexType>がいずれもtrue
  • Sがrange_sliceの特殊化であり、Xがメンバ変数S::first, S::last, S::strideの型を表すときis_convertible_v<X, IndexType>がいずれもtrue
  • 以下を全て満たす
    • 型Sのオブジェクトsに対して、宣言auto [...ls] = std::move(s);が有効
    • sizeof...(ls)が2に等しい
    • (is_convertible_v<decltype(std::move(ls)), IndexType> && ...)がtrue

正則submdspanスライス型

符号付きもしくは符号なし整数型IndexTypeに対して、型SがIndexTypeもしくは値0以上の任意の値vを保持するconstant_wrapper<v>であるとき、型SはIndexTypeの正則submdspanインデクス型となる。

符号付きもしくは符号なし整数型IndexTypeに対して、下記のうちただ1つだけを満たすとき、型SはIndexTypeの正則submdspanスライス型(canonical submdspan slice type)となる。

  • Sがfull_extent_t
  • SがIndexTypeの正則submdspanインデクス型である
  • Sがextent_sliceの特殊化であり、下記を全て満たす
    • S::offset_type, S::extent_type, S::stride_typeが、全てIndexTypeの正則submdspanインデクス型である
    • S::stride_typeおよびS::extent_typeがいずれもconstant_wrapperの特殊化であるとき、S::stride_type::valueが0より大きい

縮約スライス型とMAP_RANK

ある型がfull_extent_tないしextent_sliceの特殊化いずれでもないとき、縮約スライス型(collapsing slice type)となる。

パックpと整数iに対して、説明用のMAP_RANK(p, i)を0 <= j < iのうち縮約スライス型ではない要素p...[j]の個数とする。

submdspanスライス範囲

extentsの特殊化である型Eのオブジェクトeと、E::index_typeの正則submdspanスライス型である型Sのオブジェクトsに対して、eのk番目次元に対するsのsubmdspanスライス範囲(submdspan slice range)は下記の半開区間となる。

  • Sがfull_extent_tのとき、[0, e.extent(k))
  • Sがextent_sliceの特殊化であり、E::index_type(s.extent)が0のとき、[E::index_type(s.offset), E::index_type(s.offset))、そうでなければ、
  • Sがextent_sliceの特殊化のとき、[E::index_type(s.offset), E::index_type(s.offset + 1 + (s.extent - 1) * s.stride))、そうでなければ、
  • [E::index_type(s), E::index_type(s) + 1)

有効submdspanスライス型

extentsの特殊化である型Eに対して、型SがE::index_typeの正則スライス型であり、かつE::static_extent(k)に等しいxに対してxがdynamic_extentに等しいか下記を満たすとき、型SはEのk番目次元の有効submdspanスライス型(valid submdspan slice type)となる。

  • Sがextent_sliceの特殊化であるとき、o, e, tを下記のように定めて :

    • oがx以下
    • eがx以下
    • eが1より大きいとき、tが0より大きい
    • eが0より大きいとき、o + 1 + (e - 1) * tがx以下

    ここでoは、S::offset_typeがconstant_wrapperの特殊化であればS::offset_type::value、そうでなければ0とする。eは、S::extent_typeがconstant_wrapperの特殊化であればS::extent_type::value、そうでなければ0とする。tは、S::stride_typeがconstant_wrapperの特殊化であればS::stride_type::value、そうでなければ1とする。

  • Sがconstant_wrapperの特殊化であるとき、S::valueがxより小さい

有効submdspanスライス

extentsの特殊化である型Eのオブジェクトeと、型Sのオブジェクトsに対して、下記を満たすときsはeのk番目次元の有効submdspanスライス(valid submdspan slice)となる。

  • SがEのk番目次元の有効submdspanスライス型
  • eのk番目区間が、eのk番目次元に対してsのsubmdspanスライス範囲を含む
  • Sがextent_sliceの特殊化であるとき :
    • s.extentが値0以上であり、かつ
    • s.extentが値2より小さい、もしくはs.strideが値0より大きい

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

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

適格要件

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

  • SliceSpecifiers...[k]がIndexTypeのsubmdspanスライス型であり、かつ
  • decltype(canonical-slice<IndexType>(slices...[k]))がextents<IndexType, Extents...>のk番目次元の有効submdspanスライス型(valid submdspan slice type)であること。

事前条件

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

戻り値

make_tuple(canonical-slice<IndexType>(slices)...)

バージョン

言語

  • C++26

処理系

関連項目

参照