Skip to content

Commit 5a1743d

Browse files
committed
certesian_product_view #1089
1 parent 7110998 commit 5a1743d

File tree

3 files changed

+162
-3
lines changed

3 files changed

+162
-3
lines changed

lang/cpp23.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ C++23とは、2023年中に改訂される予定の、C++バージョンの通
133133
- [`std::map::erase()`](/reference/map/map/erase.md)
134134
- [`std::map::extract()`](/reference/map/map/extract.md)
135135
- [`<ranges>`](/reference/ranges.md)に、複数の範囲を綴じ合わせる[`std::views::zip`](/reference/ranges/zip_view.md)を追加
136-
- [`<ranges>`](/reference/ranges.md)に、複数の範囲の直積をとる[`std::views::cartesian_product`](/reference/ranges/cartesian_product_view.md.nolink)を追加
136+
- [`<ranges>`](/reference/ranges.md)に、複数の範囲の直積をとる[`std::views::cartesian_product`](/reference/ranges/cartesian_product_view.md)を追加
137137
- Rangeから任意のコンテナに変換するRangeアダプタ[`std::ranges::to()`](/reference/ranges/to.md)を追加
138138
- Rangeから任意のコンテナに変換するために、可変長のコンテナ ([`std::array`](/reference/array/array.md)以外) に、以下の機能を追加:
139139
- Rangeから変換するコンストラクタ

reference/ranges.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,8 @@ range | adaptor(args...)
395395
396396
| 名前 | 説明 | 対応バージョン |
397397
|---------------------------------------------------------------|------------------------------------------------------------------|----------------|
398-
| [`cartesian_product_view`](ranges/cartesian_product_view.md.nolink) | シーケンスの直積集合のビュー (class template) | C++23 |
399-
| [`views::cartesian_product`](ranges/cartesian_product.md.nolink) | `cartesian_product_view`を生成する (customization point object) | C++23 |
398+
| [`cartesian_product_view`](ranges/cartesian_product_view.md) | シーケンスの直積集合のビュー (class template) | C++23 |
399+
| [`views::cartesian_product`](ranges/cartesian_product.md) | `cartesian_product_view`を生成する (customization point object) | C++23 |
400400
401401
402402
## Range変換
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# cartesian_product_view
2+
* ranges[meta header]
3+
* std::ranges[meta namespace]
4+
* class template[meta id-type]
5+
* cpp23[meta cpp]
6+
7+
```cpp
8+
namespace std::ranges {
9+
template<input_range First, forward_range... Vs>
10+
requires (view<First> && ... && view<Vs>)
11+
class cartesian_product_view : public view_interface<cartesian_product_view<First, Vs...>> {…… }; // (1)
12+
13+
namespace views {
14+
inline constexpr /*unspecified*/ cartesian_product = /*unspecified*/; // (2)
15+
}
16+
}
17+
```
18+
19+
## 概要
20+
21+
`cartesian_product_view`は複数のRangeの直積をとり、その要素を[`tuple`](/reference/tuple/tuple.md)として見せる[`view`](view.md)。
22+
23+
この[`view`](view.md)の要素数は、すべての指定したRangeの要素数の積である。
24+
25+
- (1): `cartesian_product_view`のクラス定義
26+
- (2): `cartesian_product_view`を生成するカスタマイゼーションポイントオブジェクト(Rangeアダプタオブジェクトではない)
27+
28+
### Rangeコンセプト
29+
30+
| borrowed | sized | output | input | forward | bidirectional | random_access | contiguous | common | viewable | view |
31+
|----------|-------|--------|-------|---------|---------------|---------------|------------|--------|----------|------|
32+
| | (1) | 〇 | 〇 | 〇 | (2) | (3) | | (4) | ○ | ○ |
33+
34+
- (1): すべてのRangeが[`sized_range`](sized_range.md)のとき
35+
- (2): すべてのRangeが[`bidirectional_range`](bidirectional_range.md)かつ、先頭以外のRangeが*cartesian-product-common-arg*のとき
36+
- (3): すべてのRangeが[`random_access_range`](random_access_range.md)かつ、先頭のRamgeが[`sized_range`](sized_range.md)のとき
37+
- (4): 先頭のRangeが*cartesian-product-common-arg*のとき
38+
39+
## 効果
40+
41+
- (2): 式`views::cartesian_product(Es...)`の効果は次の通り
42+
- `Es`が空でないとき、`cartesian_product_view<`[`views::all_t`](all.md)`<decltype((Es))>...>(Es...)` と等しい
43+
- `Es`が空のとき、[`views::single`](single_view.md)`(`[`tuple`](/reference/tuple/tuple.md)`())` と等しい
44+
45+
46+
## 備考
47+
48+
本説明に用いる説明専用要素を以下のように定義する。
49+
50+
```cpp
51+
namespace std::ranges {
52+
template<bool Const, class First, class... Vs>
53+
concept cartesian-product-is-random-access = // exposition only
54+
(random_access_range<maybe-const<Const, First>> && ... &&
55+
(random_access_range<maybe-const<Const, Vs>>
56+
&& sized_range<maybe-const<Const, Vs>>));
57+
58+
template<class R>
59+
concept cartesian-product-common-arg = // exposition only
60+
common_range<R> || (sized_range<R> && random_access_range<R>);
61+
62+
template<bool Const, class First, class... Vs>
63+
concept cartesian-product-is-bidirectional = // exposition only
64+
(bidirectional_range<maybe-const<Const, First>> && ... &&
65+
(bidirectional_range<maybe-const<Const, Vs>>
66+
&& cartesian-product-common-arg<maybe-const<Const, Vs>>));
67+
68+
template<class First, class... Vs>
69+
concept cartesian-product-is-common = // exposition only
70+
cartesian-product-common-arg<First>;
71+
72+
template<class... Vs>
73+
concept cartesian-product-is-sized = // exposition only
74+
(sized_range<Vs> && ...);
75+
76+
template<bool Const, template<class> class FirstSent, class First, class... Vs>
77+
concept cartesian-is-sized-sentinel = // exposition only
78+
(sized_sentinel_for<FirstSent<maybe-const<Const, First>>,
79+
iterator_t<maybe-const<Const, First>>> && ...
80+
&& (sized_range<maybe-const<Const, Vs>>
81+
&& sized_sentinel_for<iterator_t<maybe-const<Const, Vs>>,
82+
iterator_t<maybe-const<Const, Vs>>>));
83+
84+
template<cartesian-product-common-arg R>
85+
constexpr auto cartesian-common-arg-end(R& r) { // exposition only
86+
if constexpr (common_range<R>) {
87+
return ranges::end(r);
88+
} else {
89+
return ranges::begin(r) + ranges::distance(r);
90+
}
91+
}
92+
}
93+
```
94+
95+
## メンバ関数
96+
97+
| 名前 | 説明 | 対応バージョン |
98+
|--------------------------------------------------|----------------------------------|----------------|
99+
| [`(constructor)`](cartesian_product_view/op_constructor.md.nolink) | コンストラクタ | C++23 |
100+
| [`begin`](cartesian_product_view/begin.md.nolink) | 先頭を指すイテレータを取得する | C++23 |
101+
| [`end`](cartesian_product_view/end.md.nolink) | 番兵を取得する | C++23 |
102+
| [`size`](cartesian_product_view/size.md.nolink) | 要素数を取得する | C++23 |
103+
104+
## 継承しているメンバ関数
105+
106+
| 名前 | 説明 | 対応バージョン |
107+
|----------------------------------------------|-----------------------------------|----------------|
108+
| [`empty`](view_interface/empty.md) | Rangeが空かどうかを判定する | C++20 |
109+
| [`operator bool`](view_interface/op_bool.md) | Rangeが空でないかどうかを判定する | C++20 |
110+
| [`front`](view_interface/front.md) | 先頭要素への参照を取得する | C++20 |
111+
| [`back`](view_interface/back.md) | 末尾要素への参照を取得する | C++20 |
112+
| [`cbegin`](view_interface/cbegin.md) | 定数イテレータを取得する | C++23 |
113+
| [`cend`](view_interface/cend.md) | 定数イテレータ(番兵)を取得する | C++23 |
114+
| [`operator[]`](view_interface/op_at.md) | 要素へアクセスする | C++20 |
115+
116+
## 推論補助
117+
118+
| 名前 | 説明 | 対応バージョン |
119+
|-------------------------------------------------------|------------------------------|----------------|
120+
| [`(deduction_guide)`](cartesian_product_view/op_deduction_guide.md.nolink) | クラステンプレートの推論補助 | C++23 |
121+
122+
##
123+
```cpp example
124+
#include <ranges>
125+
#include <vector>
126+
#include <list>
127+
#include <print>
128+
129+
int main() {
130+
std::vector v = {1, 2};
131+
const std::list l = {'a', 'b', 'c'};
132+
133+
std::println("{}", std::views::cartesian_product(v, l));
134+
135+
// 空になる場合
136+
std::println("{}", std::views::cartesian_product());
137+
}
138+
```
139+
* std::views::cartesian_product[color ff0000]
140+
* std::ranges::to[link to.md]
141+
142+
### 出力
143+
```
144+
[(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c')]
145+
[]
146+
```
147+
148+
## バージョン
149+
### 言語
150+
- C++23
151+
152+
### 処理系
153+
- [Clang](/implementation.md#clang): 16.0
154+
- [GCC](/implementation.md#gcc): 13.2
155+
- [ICC](/implementation.md#icc): ??
156+
- [Visual C++](/implementation.md#visual_cpp): ??
157+
158+
## 参照
159+
- [N4950 26 Ranges library](https://timsong-cpp.github.io/cppwp/n4950/ranges)

0 commit comments

Comments
 (0)