From Jason Turner

[range.take]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp3hwxctj2/{from.md → to.md} +87 -42
tmp/tmp3hwxctj2/{from.md → to.md} RENAMED
@@ -1,41 +1,56 @@
1
  ### Take view <a id="range.take">[[range.take]]</a>
2
 
3
  #### Overview <a id="range.take.overview">[[range.take.overview]]</a>
4
 
5
- `take_view` produces a `view` of the first N elements from another
6
- `view`, or all the elements if the adapted `view` contains fewer than N.
7
 
8
  The name `views::take` denotes a range adaptor object
9
  [[range.adaptor.object]]. Let `E` and `F` be expressions, let `T` be
10
  `remove_cvref_t<decltype((E))>`, and let `D` be
11
  `range_difference_t<decltype((E))>`. If `decltype((F))` does not model
12
  `convertible_to<D>`, `views::take(E, F)` is ill-formed. Otherwise, the
13
  expression `views::take(E, F)` is expression-equivalent to:
14
 
15
- - If `T` is a specialization of `ranges::empty_view`
16
- [[range.empty.view]], then `((void) F, decay-copy(E))`.
 
17
  - Otherwise, if `T` models `random_access_range` and `sized_range` and
18
- is
19
- - a specialization of `span` [[views.span]] where
20
- `T::extent == dynamic_extent`,
21
- - a specialization of `basic_string_view` [[string.view]],
22
- - a specialization of `ranges::iota_view` [[range.iota.view]], or
23
- - a specialization of `ranges::subrange` [[range.subrange]],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- then
26
- `T{ranges::begin(E), ranges::begin(E) + min<D>(ranges::size(E), F)}`,
27
- except that `E` is evaluated only once.
28
- - Otherwise, `ranges::take_view{E, F}`.
29
 
30
  [*Example 1*:
31
 
32
  ``` cpp
33
  vector<int> is{0,1,2,3,4,5,6,7,8,9};
34
- take_view few{is, 5};
35
- for (int i : few)
36
- cout << i << ' '; // prints: 0 1 2 3 4
37
  ```
38
 
39
  — *end example*]
40
 
41
  #### Class template `take_view` <a id="range.take.view">[[range.take.view]]</a>
@@ -45,62 +60,80 @@ namespace std::ranges {
45
  template<view V>
46
  class take_view : public view_interface<take_view<V>> {
47
  private:
48
  V base_ = V(); // exposition only
49
  range_difference_t<V> count_ = 0; // exposition only
 
50
  // [range.take.sentinel], class template take_view::sentinel
51
- template<bool> struct sentinel; // exposition only
 
52
  public:
53
- take_view() = default;
54
- constexpr take_view(V base, range_difference_t<V> count);
55
 
56
  constexpr V base() const & requires copy_constructible<V> { return base_; }
57
  constexpr V base() && { return std::move(base_); }
58
 
59
  constexpr auto begin() requires (!simple-view<V>) {
60
  if constexpr (sized_range<V>) {
61
- if constexpr (random_access_range<V>)
62
  return ranges::begin(base_);
63
- else {
64
- auto sz = size();
65
- return counted_iterator{ranges::begin(base_), sz};
 
 
 
 
 
 
 
66
  }
67
- } else
68
- return counted_iterator{ranges::begin(base_), count_};
69
  }
70
 
71
  constexpr auto begin() const requires range<const V> {
72
  if constexpr (sized_range<const V>) {
73
- if constexpr (random_access_range<const V>)
74
  return ranges::begin(base_);
75
- else {
76
- auto sz = size();
77
- return counted_iterator{ranges::begin(base_), sz};
 
 
 
 
 
 
 
78
  }
79
- } else
80
- return counted_iterator{ranges::begin(base_), count_};
81
  }
82
 
83
  constexpr auto end() requires (!simple-view<V>) {
84
  if constexpr (sized_range<V>) {
85
  if constexpr (random_access_range<V>)
86
- return ranges::begin(base_) + size();
87
  else
88
  return default_sentinel;
89
- } else
 
 
90
  return sentinel<false>{ranges::end(base_)};
91
  }
 
92
 
93
  constexpr auto end() const requires range<const V> {
94
  if constexpr (sized_range<const V>) {
95
  if constexpr (random_access_range<const V>)
96
- return ranges::begin(base_) + size();
97
  else
98
  return default_sentinel;
99
- } else
 
 
100
  return sentinel<true>{ranges::end(base_)};
101
  }
 
102
 
103
  constexpr auto size() requires sized_range<V> {
104
  auto n = ranges::size(base_);
105
  return ranges::min(n, static_cast<decltype(n)>(count_));
106
  }
@@ -109,20 +142,22 @@ namespace std::ranges {
109
  auto n = ranges::size(base_);
110
  return ranges::min(n, static_cast<decltype(n)>(count_));
111
  }
112
  };
113
 
114
- template<range R>
115
  take_view(R&&, range_difference_t<R>)
116
  -> take_view<views::all_t<R>>;
117
  }
118
  ```
119
 
120
  ``` cpp
121
- constexpr take_view(V base, range_difference_t<V> count);
122
  ```
123
 
 
 
124
  *Effects:* Initializes *base\_* with `std::move(base)` and *count\_*
125
  with `count`.
126
 
127
  #### Class template `take_view::sentinel` <a id="range.take.sentinel">[[range.take.sentinel]]</a>
128
 
@@ -130,22 +165,28 @@ with `count`.
130
  namespace std::ranges {
131
  template<view V>
132
  template<bool Const>
133
  class take_view<V>::sentinel {
134
  private:
135
- using Base = conditional_t<Const, const V, V>; // exposition only
136
- using CI = counted_iterator<iterator_t<Base>>; // exposition only
 
137
  sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
 
138
  public:
139
  sentinel() = default;
140
  constexpr explicit sentinel(sentinel_t<Base> end);
141
  constexpr sentinel(sentinel<!Const> s)
142
  requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
143
 
144
  constexpr sentinel_t<Base> base() const;
145
 
146
- friend constexpr bool operator==(const CI& y, const sentinel& x);
 
 
 
 
147
  };
148
  }
149
  ```
150
 
151
  ``` cpp
@@ -166,11 +207,15 @@ constexpr sentinel_t<Base> base() const;
166
  ```
167
 
168
  *Effects:* Equivalent to: `return `*`end_`*`;`
169
 
170
  ``` cpp
171
- friend constexpr bool operator==(const CI& y, const sentinel& x);
 
 
 
 
172
  ```
173
 
174
  *Effects:* Equivalent to:
175
  `return y.count() == 0 || y.base() == x.`*`end_`*`;`
176
 
 
1
  ### Take view <a id="range.take">[[range.take]]</a>
2
 
3
  #### Overview <a id="range.take.overview">[[range.take.overview]]</a>
4
 
5
+ `take_view` produces a view of the first N elements from another view,
6
+ or all the elements if the adapted view contains fewer than N.
7
 
8
  The name `views::take` denotes a range adaptor object
9
  [[range.adaptor.object]]. Let `E` and `F` be expressions, let `T` be
10
  `remove_cvref_t<decltype((E))>`, and let `D` be
11
  `range_difference_t<decltype((E))>`. If `decltype((F))` does not model
12
  `convertible_to<D>`, `views::take(E, F)` is ill-formed. Otherwise, the
13
  expression `views::take(E, F)` is expression-equivalent to:
14
 
15
+ - If `T` is a specialization of `empty_view` [[range.empty.view]], then
16
+ `((void)F, decay-copy(E))`, except that the evaluations of `E` and `F`
17
+ are indeterminately sequenced.
18
  - Otherwise, if `T` models `random_access_range` and `sized_range` and
19
+ is a specialization of `span` [[views.span]], `basic_string_view`
20
+ [[string.view]], or `subrange` [[range.subrange]], then
21
+ `U(ranges::begin(E),
22
+ ranges::begin(E) + std::min<D>(ranges::distance(E), F))`, except that
23
+ `E` is evaluated only once, where `U` is a type determined as follows:
24
+ - if `T` is a specialization of `span`, then `U` is
25
+ `span<typename T::element_type>`;
26
+ - otherwise, if `T` is a specialization of `basic_string_view`, then
27
+ `U` is `T`;
28
+ - otherwise, `T` is a specialization of `subrange`, and `U` is
29
+ `subrange<iterator_t<T>>`;
30
+ - otherwise, if `T` is a specialization of `iota_view`
31
+ [[range.iota.view]] that models `random_access_range` and
32
+ `sized_range`, then `iota_view(*ranges::begin(E),
33
+ *(ranges::begin(E) + std::{}min<D>(ranges::distance(E), F)))`, except
34
+ that `E` is evaluated only once.
35
+ - Otherwise, if `T` is a specialization of `repeat_view`
36
+ [[range.repeat.view]]:
37
+ - if `T` models `sized_range`, then
38
+ ``` cpp
39
+ views::repeat(*E.value_, std::min<D>(ranges::distance(E), F))
40
+ ```
41
 
42
+ except that `E` is evaluated only once;
43
+ - otherwise, `views::repeat(*E.value_, static_cast<D>(F))`.
44
+ - Otherwise, `take_view(E, F)`.
 
45
 
46
  [*Example 1*:
47
 
48
  ``` cpp
49
  vector<int> is{0,1,2,3,4,5,6,7,8,9};
50
+ for (int i : is | views::take(5))
51
+ cout << i << ' '; // prints 0 1 2 3 4
 
52
  ```
53
 
54
  — *end example*]
55
 
56
  #### Class template `take_view` <a id="range.take.view">[[range.take.view]]</a>
 
60
  template<view V>
61
  class take_view : public view_interface<take_view<V>> {
62
  private:
63
  V base_ = V(); // exposition only
64
  range_difference_t<V> count_ = 0; // exposition only
65
+
66
  // [range.take.sentinel], class template take_view::sentinel
67
+ template<bool> class sentinel; // exposition only
68
+
69
  public:
70
+ take_view() requires default_initializable<V> = default;
71
+ constexpr explicit take_view(V base, range_difference_t<V> count);
72
 
73
  constexpr V base() const & requires copy_constructible<V> { return base_; }
74
  constexpr V base() && { return std::move(base_); }
75
 
76
  constexpr auto begin() requires (!simple-view<V>) {
77
  if constexpr (sized_range<V>) {
78
+ if constexpr (random_access_range<V>) {
79
  return ranges::begin(base_);
80
+ } else {
81
+ auto sz = range_difference_t<V>(size());
82
+ return counted_iterator(ranges::begin(base_), sz);
83
+ }
84
+ } else if constexpr (sized_sentinel_for<sentinel_t<V>, iterator_t<V>>) {
85
+ auto it = ranges::begin(base_);
86
+ auto sz = std::min(count_, ranges::end(base_) - it);
87
+ return counted_iterator(std::move(it), sz);
88
+ } else {
89
+ return counted_iterator(ranges::begin(base_), count_);
90
  }
 
 
91
  }
92
 
93
  constexpr auto begin() const requires range<const V> {
94
  if constexpr (sized_range<const V>) {
95
+ if constexpr (random_access_range<const V>) {
96
  return ranges::begin(base_);
97
+ } else {
98
+ auto sz = range_difference_t<const V>(size());
99
+ return counted_iterator(ranges::begin(base_), sz);
100
+ }
101
+ } else if constexpr (sized_sentinel_for<sentinel_t<const V>, iterator_t<const V>>) {
102
+ auto it = ranges::begin(base_);
103
+ auto sz = std::min(count_, ranges::end(base_) - it);
104
+ return counted_iterator(std::move(it), sz);
105
+ } else {
106
+ return counted_iterator(ranges::begin(base_), count_);
107
  }
 
 
108
  }
109
 
110
  constexpr auto end() requires (!simple-view<V>) {
111
  if constexpr (sized_range<V>) {
112
  if constexpr (random_access_range<V>)
113
+ return ranges::begin(base_) + range_difference_t<V>(size());
114
  else
115
  return default_sentinel;
116
+ } else if constexpr (sized_sentinel_for<sentinel_t<V>, iterator_t<V>>) {
117
+ return default_sentinel;
118
+ } else {
119
  return sentinel<false>{ranges::end(base_)};
120
  }
121
+ }
122
 
123
  constexpr auto end() const requires range<const V> {
124
  if constexpr (sized_range<const V>) {
125
  if constexpr (random_access_range<const V>)
126
+ return ranges::begin(base_) + range_difference_t<const V>(size());
127
  else
128
  return default_sentinel;
129
+ } else if constexpr (sized_sentinel_for<sentinel_t<const V>, iterator_t<const V>>) {
130
+ return default_sentinel;
131
+ } else {
132
  return sentinel<true>{ranges::end(base_)};
133
  }
134
+ }
135
 
136
  constexpr auto size() requires sized_range<V> {
137
  auto n = ranges::size(base_);
138
  return ranges::min(n, static_cast<decltype(n)>(count_));
139
  }
 
142
  auto n = ranges::size(base_);
143
  return ranges::min(n, static_cast<decltype(n)>(count_));
144
  }
145
  };
146
 
147
+ template<class R>
148
  take_view(R&&, range_difference_t<R>)
149
  -> take_view<views::all_t<R>>;
150
  }
151
  ```
152
 
153
  ``` cpp
154
+ constexpr explicit take_view(V base, range_difference_t<V> count);
155
  ```
156
 
157
+ *Preconditions:* `count >= 0` is `true`.
158
+
159
  *Effects:* Initializes *base\_* with `std::move(base)` and *count\_*
160
  with `count`.
161
 
162
  #### Class template `take_view::sentinel` <a id="range.take.sentinel">[[range.take.sentinel]]</a>
163
 
 
165
  namespace std::ranges {
166
  template<view V>
167
  template<bool Const>
168
  class take_view<V>::sentinel {
169
  private:
170
+ using Base = maybe-const<Const, V>; // exposition only
171
+ template<bool OtherConst>
172
+ using CI = counted_iterator<iterator_t<maybe-const<OtherConst, V>>>; // exposition only
173
  sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
174
+
175
  public:
176
  sentinel() = default;
177
  constexpr explicit sentinel(sentinel_t<Base> end);
178
  constexpr sentinel(sentinel<!Const> s)
179
  requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
180
 
181
  constexpr sentinel_t<Base> base() const;
182
 
183
+ friend constexpr bool operator==(const CI<Const>& y, const sentinel& x);
184
+
185
+ template<bool OtherConst = !Const>
186
+ requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
187
+ friend constexpr bool operator==(const CI<OtherConst>& y, const sentinel& x);
188
  };
189
  }
190
  ```
191
 
192
  ``` cpp
 
207
  ```
208
 
209
  *Effects:* Equivalent to: `return `*`end_`*`;`
210
 
211
  ``` cpp
212
+ friend constexpr bool operator==(const CI<Const>& y, const sentinel& x);
213
+
214
+ template<bool OtherConst = !Const>
215
+ requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
216
+ friend constexpr bool operator==(const CI<OtherConst>& y, const sentinel& x);
217
  ```
218
 
219
  *Effects:* Equivalent to:
220
  `return y.count() == 0 || y.base() == x.`*`end_`*`;`
221