Skip to content

Commit 2e31db6

Browse files
committed
mdspan: P3663R3対応 (#1567)
1 parent 1524520 commit 2e31db6

18 files changed

Lines changed: 414 additions & 331 deletions

File tree

reference/mdspan.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
| [`full_extent`](mdspan/full_extent_t.md) | 指定次元の全要素取り出しを指示するタグ値 (variable) | C++26 |
5050
| [`submdspan_mapping_result`](mdspan/submdspan_mapping_result.md) | 多次元配列部分ビューのレイアウトマッピング情報 (class template) | C++26 |
5151
| [`submdspan_extents`](mdspan/submdspan_extents.md) | 多次元配列部分ビューの多次元配列サイズを計算する (function template) | C++26 |
52+
| [`submdspan_canonicalize_slices`](mdspan/submdspan_canonicalize_slices.md) | 多次元配列部分ビュー取得時の多次元インデクスを正規化する (function template) | C++26 |
5253
| [`submdspan`](mdspan/submdspan.md) | 多次元配列部分ビューを取得する (function template) | C++26 |
5354

5455

@@ -67,3 +68,4 @@
6768
- [P2630R4 Submdspan](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2630r4.html)
6869
- [P2642R6 Padded mdspan layouts](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2642r6.pdf)
6970
- [P2897R7 `aligned_accessor`: An mdspan accessor expressing pointer over-alignment](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2897r7.html)
71+
- [P3663R3 Future-proof `submdspan_mapping`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3663r3.html)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# canonical-index
2+
* [meta exposition-only]
3+
* mdspan[meta header]
4+
* function template[meta id-type]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
template<class IndexType, class S>
9+
constexpr auto canonical-index(S s);
10+
```
11+
12+
## 概要
13+
`canonical-index`は、[`submdspan`](submdspan.md)動作仕様定義で用いられる説明専用の関数テンプレートである。
14+
15+
16+
## 適格要件
17+
`S`が[`integral-constant-like`](/reference/span/integral-constant-like.md)のモデルであるとき、`extents<IndexType>::`[`index-cast`](extents/index-cast.md)`(`[`std::move`](/reference/utility/move.md)`(s))`を`IndexType`型の値として表現できること。
18+
19+
20+
## 事前条件
21+
`extents<IndexType>::`[`index-cast`](extents/index-cast.md)`(`[`std::move`](/reference/utility/move.md)`(s))`を`IndexType`型の値として表現できること。
22+
23+
24+
## 効果
25+
以下と等価
26+
27+
- `S`が[`integral-constant-like`](/reference/span/integral-constant-like.md)のモデルであるとき、`return` [`cw`](/reference/type_traits/constant_wrapper.md.nolink)`<IndexType(S::value)>`
28+
- そうではないとき、`return IndexType(`[`std::move`](/reference/utility/move.md)`(s))`
29+
30+
31+
## バージョン
32+
### 言語
33+
- C++26
34+
35+
36+
## 関連項目
37+
- [`submdspan_canonicalize_slices`](submdspan_canonicalize_slices.md)
38+
39+
40+
## 参照
41+
- [P3663R3 Future-proof `submdspan_mapping`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3663r3.html)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# canonical-slice
2+
* [meta exposition-only]
3+
* mdspan[meta header]
4+
* function template[meta id-type]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
template<class IndexType, class S>
9+
constexpr auto canonical-slice(S s);
10+
```
11+
12+
## 概要
13+
`canonical-slice`は、[`submdspan`](submdspan.md)動作仕様定義で用いられる説明専用の関数テンプレートである。
14+
15+
16+
## 適格要件
17+
`S`が`IndexType`の`submdspan`スライス型であること。
18+
19+
20+
## 効果
21+
以下と等価
22+
23+
```cpp
24+
if constexpr (is_convertible_v<S, full_extent_t>) {
25+
return static_cast<full_extent_t>(std::move(s));
26+
} else if constexpr (is_convertible_v<S, IndexType>) {
27+
return canonical-index<IndexType>(std::move(s));
28+
} else if constexpr (is-strided-slice<S>) {
29+
auto c_extent = canonical-index<IndexType>(std::move(s.extent));
30+
auto c_offset = canonical-index<IndexType>(std::move(s.offset));
31+
if constexpr (is_same_v<decltype(c_extent), constant_wrapper<IndexType(0)>>) {
32+
return strided_slice{
33+
.offset = c_offset,
34+
.extent = c_extent,
35+
.stride = cw<IndexType(1)>
36+
};
37+
} else {
38+
return strided_slice{
39+
.offset = c_offset,
40+
.extent = c_extent,
41+
.stride = canonical-index<IndexType>(std::move(s.stride))
42+
};
43+
}
44+
} else {
45+
auto [s_first, s_last] = std::move(s);
46+
auto c_first = canonical-index<IndexType>(std::move(s_first));
47+
auto c_last = canonical-index<IndexType>(std::move(s_last));
48+
return strided_slice{
49+
.offset = c_first,
50+
.extent = canonical-index<IndexType>(c_last - c_first),
51+
.stride = cw<IndexType(1)>
52+
};
53+
}
54+
```
55+
* full_extent_t[link full_extent_t.md]
56+
* strided_slice[link strided_slice.md]
57+
* canonical-index[link canonical-index.md]
58+
* is_convertible_v[link /reference/type_traits/is_convertible.md]
59+
* is_same_v[link /reference/type_traits/is_same.md]
60+
* constant_wrapper[link /reference/type_traits/constant_wrapper.md.nolink]
61+
* cw[link /reference/type_traits/constant_wrapper.md.nolink]
62+
* std::move[link /reference/utility/move.md]
63+
64+
ここで`is-strided-slice`は、型`S`[`strided_slice`](strided_slice.md)の特殊化であることを表す説明専用コンセプトとする。
65+
66+
67+
## バージョン
68+
### 言語
69+
- C++26
70+
71+
72+
## 関連項目
73+
- [`submdspan_canonicalize_slices`](submdspan_canonicalize_slices.md)
74+
75+
76+
## 参照
77+
- [P3663R3 Future-proof `submdspan_mapping`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3663r3.html)

reference/mdspan/de-ice.md

Lines changed: 0 additions & 26 deletions
This file was deleted.

reference/mdspan/first_.md

Lines changed: 0 additions & 40 deletions
This file was deleted.

reference/mdspan/last_.md

Lines changed: 0 additions & 41 deletions
This file was deleted.

reference/mdspan/layout_left/mapping/submdspan_mapping.md

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
```cpp
99
template<class... SliceSpecifiers>
1010
constexpr auto submdspan-mapping-impl( // exposition only
11-
SliceSpecifiers ... slices) const -> see below;
11+
SliceSpecifiers... slices) const -> see below;
1212

1313
template<class... SliceSpecifiers>
1414
friend constexpr auto submdspan_mapping(
@@ -22,60 +22,47 @@ friend constexpr auto submdspan_mapping(
2222
## 概要
2323
[`submdspan`](../../submdspan.md)関数をサポートするためのカスタマイゼーションポイント。
2424
25-
説明用の型`index_type`を[`Extents::index_type`](../../extents.md)、型`S_k`を`SliceSpecifiers`の`k`番目の型とする。
26-
2725
2826
## テンプレートパラメータ制約
29-
`sizeof...(slices)`が[`Extents::rank()`](../../extents/rank.md)と等しいこと。
27+
`sizeof...(SliceSpecifiers)`が[`Extents::rank()`](../../extents/rank.md)と等しいこと。
3028
3129
3230
## 適格要件
33-
`extents()`の各次元インデクス`k`において、下記いずれかのうち1つだけを満たすこと。
34-
35-
- 型`S_k`が[`convertible_to`](/reference/concepts/convertible_to.md)`<index_type>`のモデル
36-
- 型`S_k`が[`index-pair-like`](../../index-pair-like.md)`<index_type>`のモデル
37-
- [`is_convertible_v`](/reference/type_traits/is_convertible.md)`<S_k,` [`full_extent_t`](../../full_extent_t.md)`>`が`true`
38-
- 型`S_k`が[`strided_slice`](../../strided_slice.md)の特殊化
31+
`extents()`の各次元インデクス`k`において、`SliceSpecifiers...[k]`が`Extents`のk番目次元の[有効`submdspan`スライス型(valid `submdspan` slice type)](../../submdspan_canonicalize_slices.md)であること。
3932
4033
4134
## 事前条件
42-
`extents()`の各次元インデクス`k`において、`s_k`を`slices`の`k`番目の値としたとき、下記を全て満たすこと。
43-
44-
- 型`S_k`が[`strided_slice`](../../strided_slice.md)の特殊化のとき
45-
- `s_k.extent == 0`、または
46-
- `s_k.stride > 0`
47-
- `0` ≤ [`first_`](../../first_.md)`<index_type, k>(slices...)` ≤ [`last_`](../../last_.md)`<k>(extents(), slices...)` ≤ `extents().`[`extent(k)`](../../extents/extent.md)
35+
`extents()`の各次元インデクス`k`において、`slices...[k]`が`extents()`のk番目次元の有効スライスであること。
4836
4937
5038
## 戻り値
5139
説明用の値や型を次の通り定義する。
5240
5341
- 値`sub_ext` : 式[`submdspan_extents`](../../submdspan_extents.md)`(extents(), slices...)`の結果
5442
- 型`SubExtents` : `decltype(sub_ext)`
55-
- 値`sub_strides` : `extents()`の各次元インデクス`k`において、[`map-rank[k]`](../../submdspan_extents.md)が[`dynamic_extent`](/reference/span/dynamic_extent.md)ではない`k`に対し`sub_strides[map-rank[k]]`が下記を満たす、[`array`](/reference/array/array.md)`<SubExtents::index_type,` [`SubExtents::rank()`](../../extents/rank.md)`>`型の配列値
56-
- 型`S_k`が[`strided_slice`](../../strided_slice.md)の特殊化かつ`s_k.stride < s_k.extent`の場合、[`stride(k)`](stride.md) `*` [`de-ice`](../../de-ice.md)`(s_k.stride)`
43+
- 値`sub_strides` : `slices...[k]`の型が縮約スライス型(collapsing slice type)ではない`extents()`の各次元インデクス`k`において`sub_strides[MAP_RANK(slices, k)]`が下記を満たす、[`array`](/reference/array/array.md)`<SubExtents::index_type,` [`SubExtents::rank()`](../../extents/rank.md)`>`型の配列値
44+
- 説明用の`s`を`slices...[k]`としたとき、`s`の型が[`strided_slice`](../../strided_slice.md)の特殊化かつ`s.stride < s.extent`の場合、[`stride(k)`](stride.md) `* s.stride`
5745
- そうでなければ、[`stride(k)`](stride.md)
58-
- パラメータパック`P` : [`is_same_v`](/reference/type_traits/is_same.md)`<`[`make_index_sequence`](/reference/utility/make_index_sequence.md)`<rank()>,` [`index_sequence`](/reference/utility/index_sequence.md)`<P...>> == true`
59-
- 値`offset` : `size_t`型の値[`(*this)`](op_call.md)`(`[`first_`](../../first_.md)`<index_type, P>(slices...)...)`
46+
- パック`ls` : `extents()`の次元`r`に対して、`r`番目の要素が`slices...[r]`の`submdspan`スライス範囲の下限に等しい`index_type`型の値パック
47+
- 値`offset` : `extents()`における任意の次元インデクス`k`に対して`ls...[k]`が`extents().extent(k)`と等しいとき、`required_span_size()`に等しい`size_t`型の値。そうでなければ、[`operator()`](op_call.md)に等しい`size_t`型の値。
6048
61-
下記を満たす型`S`を、単位ストライド幅スライス(unit-stride slice)と定義する。
49+
下記を満たす型`S`を、単位ストライド幅スライス型(unit-stride slice type)と定義する。
6250
63-
- 型`S`が[`strided_slice`](../../strided_slice.md)の特殊化であり型`S::stride_type`が[`integral-constant-like`](/reference/span/integral-constant-like.md)のモデルかつ`S::stride_type::value`が`1`に等しい、もしくは
64-
- 型`S`が[`index-pair-like`](../../index-pair-like.md)`<index_type>`のモデル、もしくは
65-
- [`is_convertible_v`](/reference/type_traits/is_convertible.md)`<S,` [`full_extent_t`](../../full_extent_t.md)`>`が`true`
51+
- `S`が[`strided_slice`](../../strided_slice.md)の特殊化であり、`S::stride_type`が[`constant_wrapper`](/reference/type_traits/constant_wrapper.md.nolink)の特殊化かつ`S::stride_type::value`が`1`、または
52+
- `S`が[`full_extent_t`](../../full_extent_t.md)
6653
6754
説明専用の`submdspan-mapping-impl`関数テンプレートは下記の値を返す。
6855
6956
- [`Extents::rank()`](../../extents/rank.md) `== 0`のとき、[`submdspan_mapping_result`](../../submdspan_mapping_result.md)`{*this, 0}`
7057
- `SubExtents::rank() == 0`のとき、[`submdspan_mapping_result`](../../submdspan_mapping_result.md)`{`[`layout_left::mapping`](../../layout_left.md)`(sub_ext), offset}`
7158
- 以下を満たすとき、[`submdspan_mapping_result`](../../submdspan_mapping_result.md)`{`[`layout_left::mapping`](../../layout_left.md)`(sub_ext), offset}`
72-
- 半開区間`[0, SubExtents::rank()-1)`の値`k`に対して、[`is_convertible_v`](/reference/type_traits/is_convertible.md)`<S_k,` [`full_extent_t`](../../full_extent_t.md)`>`が`true`、かつ
73-
- `SubExtents::rank()-1`に等しい値`k`に対して、型`S_k`が単位ストライド幅スライスである
59+
- 半開区間`[0, SubExtents::rank()-1)`の値`k`に対して、`SliceSpecifiers...[k]`が[`full_extent_t`](../../full_extent_t.md)を表し、かつ
60+
- `SubExtents::rank()-1`に等しい値`k`に対して、`SliceSpecifiers...[k]`が単位ストライド幅スライス型である
7461
- 以下を満たすとき、[`submdspan_mapping_result`](../../submdspan_mapping_result.md)`{`[`layout_left_padded<S_static>::mapping`](../../layout_left_padded/mapping.md)`(sub_ext, stride(u + 1)), offset}`
75-
- 型`S_p`が単位ストライド幅スライスを満たす`0`より大きい最小値`p`に対して、`u+1`が`p`となる値`u`を用いて
76-
- 型`S_0`が単位ストライド幅スライスであり、かつ
77-
- 半開区間`[u+1, u+SubExtents::rank()-1)`の値`k`に対して、[`is_convertible_v`](/reference/type_traits/is_convertible.md)`<S_k,` [`full_extent_t`](../../full_extent_t.md)`>`、かつ
78-
- `u+SubExtents::rank()-1`に等しい値`k`に対して、型`S_k`が単位ストライド幅スライスである
62+
- `SliceSpecifiers...[p]`が単位ストライド幅スライス型となる`0`より大きい最小値`p`に対して、`u+1`が`p`となる値`u`を用いて
63+
- 型`SliceSpecifiers...[0]`が単位ストライド幅スライス型であり、かつ
64+
- 半開区間`[u+1, u+SubExtents::rank()-1)`の値`k`に対して、`SliceSpecifiers...[k]`が[`full_extent_t`](../../full_extent_t.md)を表し、かつ
65+
- `u+SubExtents::rank()-1`に等しい値`k`に対して、`SliceSpecifiers...[k]`が単位ストライド幅スライス型である
7966
- ここで定数`S_static`は
8067
- 半開区間`[0, u+1)`のいずれかの値`k`に対して`static_extent(k)`が[`dynamic_extent`](/reference/span/dynamic_extent.md)のとき、`dynamic_extent`
8168
- そうでなければ、半開区間`[0, u+1)`の全ての値`k`に対して`static_extent(k)`を乗算した値
@@ -101,3 +88,4 @@ friend constexpr auto submdspan_mapping(
10188
- [P2630R4 Submdspan](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2630r4.html)
10289
- [P2642R6 Padded mdspan layouts](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2642r6.pdf)
10390
- [P3355R1 Fix submdspan for C++26](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3355r1.html)
91+
- [P3663R3 Future-proof `submdspan_mapping`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3663r3.html)

0 commit comments

Comments
 (0)