yohhoyの日記

技術的メモをしていきたい日記

0次元std::mdspan

C++2b(C++23)標準ライブラリの多次元ビューstd::mdspanクラステンプレート(→id:yohhoy:20230303)では、0次元(rank-0)ビューをサポートする。

意味論上は “単一変数へのポインタ” に相当する。(´-`).。oO(使うことあるか?)
2024-02-01追記:C++2c(C++26)標準で追加された、部分ビューを取り出すstd::submdspan関数(→id:yohhoy:20240201)の結果として利用される。

// C++2b(C++23)
#include <cassert>
#include <mdspan>

// 0次元ビュー
using Span0D = std::mdspan<int, std::extents<size_t>>;
static_assert(Span0D::rank() == 0);

int value = 42;
Span0D m0{&value};  // OK
// CTAD利用時は std::mdspan m0{&value};

// 多次元インデクス空間サイズ==1
assert(m0.size() == 1);
assert(m0.mapping().required_span_size() == 1);

// 唯一の有効インデクスはオフセット位置0に対応
assert(m0.mapping()( ) == 0);
assert(m0[ ] == 42);

メモ:std::mdspanの "rank" を「テンソル(tensor)の階数(rank)」相当と考えれば、rank-0=スカラー(scalar)/rank-1=ベクトル(vector)/rank-2=行列(matrix) と自然に解釈できる。(thanks to @onihusube9さん

N4928(C++2b WD) 24.7.3.1/p1, 24.7.3.5.3.2/p2, 24.7.3.6.3/p1-4より一部引用(下線部は強調)。

1 A multidimensional index space is a Cartesian product of integer intervals. Each interval can be represented by a half-open range [Li, Ui), where Li and Ui are the lower and upper bounds of the ith dimension. The rank of a multidimensional index space is the number of intervals it represents. The size of a multidimensional index space is the product of Ui - Li for each dimension i if its rank is greater than 0, and 1 otherwise.

constexpr reference access(data_handle_type p, size_t i) const noexcept;

2 Effects: Equivalent to: return p[i];

template<class... OtherIndexTypes>
  constexpr reference operator[](OtherIndexTypes... indices) const;

1 Constraints:

  • (snip)
  • sizeof...(OtherIndexTypes) == rank() is true.

2 Let I be extents_type::index-cast(std::move(indices)).
3 Preconditions: I is a multidimensional index in extents().
[Note 1: This implies that map_(I) < map_.required_span_size() is true. -- end note]
4 Effects: Equivalent to:

return acc_.access(ptr_, map_(static_cast<index_type>(std::move(indices))...));

関連URL