From Jason Turner

[range.zip.view]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpv1wg7avt/{from.md → to.md} +90 -0
tmp/tmpv1wg7avt/{from.md → to.md} RENAMED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### Class template `zip_view` <a id="range.zip.view">[[range.zip.view]]</a>
2
+
3
+ ``` cpp
4
+ namespace std::ranges {
5
+ template<class... Rs>
6
+ concept zip-is-common = // exposition only
7
+ (sizeof...(Rs) == 1 && (common_range<Rs> && ...)) ||
8
+ (!(bidirectional_range<Rs> && ...) && (common_range<Rs> && ...)) ||
9
+ ((random_access_range<Rs> && ...) && (sized_range<Rs> && ...));
10
+
11
+ template<input_range... Views>
12
+ requires (view<Views> && ...) && (sizeof...(Views) > 0)
13
+ class zip_view : public view_interface<zip_view<Views...>> {
14
+ tuple<Views...> views_; // exposition only
15
+
16
+ // [range.zip.iterator], class template zip_view::iterator
17
+ template<bool> class iterator; // exposition only
18
+
19
+ // [range.zip.sentinel], class template zip_view::sentinel
20
+ template<bool> class sentinel; // exposition only
21
+
22
+ public:
23
+ zip_view() = default;
24
+ constexpr explicit zip_view(Views... views);
25
+
26
+ constexpr auto begin() requires (!(simple-view<Views> && ...)) {
27
+ return iterator<false>(tuple-transform(ranges::begin, views_));
28
+ }
29
+ constexpr auto begin() const requires (range<const Views> && ...) {
30
+ return iterator<true>(tuple-transform(ranges::begin, views_));
31
+ }
32
+
33
+ constexpr auto end() requires (!(simple-view<Views> && ...)) {
34
+ if constexpr (!zip-is-common<Views...>) {
35
+ return sentinel<false>(tuple-transform(ranges::end, views_));
36
+ } else if constexpr ((random_access_range<Views> && ...)) {
37
+ return begin() + iter_difference_t<iterator<false>>(size());
38
+ } else {
39
+ return iterator<false>(tuple-transform(ranges::end, views_));
40
+ }
41
+ }
42
+
43
+ constexpr auto end() const requires (range<const Views> && ...) {
44
+ if constexpr (!zip-is-common<const Views...>) {
45
+ return sentinel<true>(tuple-transform(ranges::end, views_));
46
+ } else if constexpr ((random_access_range<const Views> && ...)) {
47
+ return begin() + iter_difference_t<iterator<true>>(size());
48
+ } else {
49
+ return iterator<true>(tuple-transform(ranges::end, views_));
50
+ }
51
+ }
52
+
53
+ constexpr auto size() requires (sized_range<Views> && ...);
54
+ constexpr auto size() const requires (sized_range<const Views> && ...);
55
+ };
56
+
57
+ template<class... Rs>
58
+ zip_view(Rs&&...) -> zip_view<views::all_t<Rs>...>;
59
+ }
60
+ ```
61
+
62
+ Two `zip_view` objects have the same underlying sequence if and only if
63
+ the corresponding elements of *`views_`* are equal [[concepts.equality]]
64
+ and have the same underlying sequence.
65
+
66
+ [*Note 1*: In particular, comparison of iterators obtained from
67
+ `zip_view` objects that do not have the same underlying sequence is not
68
+ required to produce meaningful results
69
+ [[iterator.concept.forward]]. — *end note*]
70
+
71
+ ``` cpp
72
+ constexpr explicit zip_view(Views... views);
73
+ ```
74
+
75
+ *Effects:* Initializes *views\_* with `std::move(views)...`.
76
+
77
+ ``` cpp
78
+ constexpr auto size() requires (sized_range<Views> && ...);
79
+ constexpr auto size() const requires (sized_range<const Views> && ...);
80
+ ```
81
+
82
+ *Effects:* Equivalent to:
83
+
84
+ ``` cpp
85
+ return apply([](auto... sizes) {
86
+ using CT = make-unsigned-like-t<common_type_t<decltype(sizes)...>>;
87
+ return ranges::min({CT(sizes)...});
88
+ }, tuple-transform(ranges::size, views_));
89
+ ```
90
+