From Jason Turner

[range.subrange]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpdagwwuav/{from.md → to.md} +31 -60
tmp/tmpdagwwuav/{from.md → to.md} RENAMED
@@ -1,79 +1,67 @@
1
  ### Sub-ranges <a id="range.subrange">[[range.subrange]]</a>
2
 
 
 
3
  The `subrange` class template combines together an iterator and a
4
  sentinel into a single object that models the `view` concept.
5
  Additionally, it models the `sized_range` concept when the final
6
  template parameter is `subrange_kind::sized`.
7
 
8
  ``` cpp
9
  namespace std::ranges {
 
 
 
 
 
10
  template<class From, class To>
11
  concept convertible-to-non-slicing = // exposition only
12
  convertible_to<From, To> &&
13
- !(is_pointer_v<decay_t<From>> &&
14
- is_pointer_v<decay_t<To>> &&
15
- not-same-as<remove_pointer_t<decay_t<From>>, remove_pointer_t<decay_t<To>>>);
16
-
17
- template<class T>
18
- concept pair-like = // exposition only
19
- !is_reference_v<T> && requires(T t) {
20
- typename tuple_size<T>::type; // ensures tuple_size<T> is complete
21
- requires derived_from<tuple_size<T>, integral_constant<size_t, 2>>;
22
- typename tuple_element_t<0, remove_const_t<T>>;
23
- typename tuple_element_t<1, remove_const_t<T>>;
24
- { get<0>(t) } -> convertible_to<const tuple_element_t<0, T>&>;
25
- { get<1>(t) } -> convertible_to<const tuple_element_t<1, T>&>;
26
- };
27
 
28
  template<class T, class U, class V>
29
  concept pair-like-convertible-from = // exposition only
30
- !range<T> && pair-like<T> &&
31
  constructible_from<T, U, V> &&
32
  convertible-to-non-slicing<U, tuple_element_t<0, T>> &&
33
  convertible_to<V, tuple_element_t<1, T>>;
34
 
35
- template<class T>
36
- concept iterator-sentinel-pair = // exposition only
37
- !range<T> && pair-like<T> &&
38
- sentinel_for<tuple_element_t<1, T>, tuple_element_t<0, T>>;
39
-
40
  template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K =
41
  sized_sentinel_for<S, I> ? subrange_kind::sized : subrange_kind::unsized>
42
  requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
43
  class subrange : public view_interface<subrange<I, S, K>> {
44
  private:
45
  static constexpr bool StoreSize = // exposition only
46
  K == subrange_kind::sized && !sized_sentinel_for<S, I>;
47
  I begin_ = I(); // exposition only
48
  S end_ = S(); // exposition only
49
  make-unsigned-like-t<iter_difference_t<I>> size_ = 0; // exposition only; present only
50
- // when StoreSize is true
51
  public:
52
- subrange() = default;
53
 
54
  constexpr subrange(convertible-to-non-slicing<I> auto i, S s) requires (!StoreSize);
55
 
56
  constexpr subrange(convertible-to-non-slicing<I> auto i, S s,
57
  make-unsigned-like-t<iter_difference_t<I>> n)
58
  requires (K == subrange_kind::sized);
59
 
60
- template<not-same-as<subrange> R>
61
  requires borrowed_range<R> &&
62
  convertible-to-non-slicing<iterator_t<R>, I> &&
63
  convertible_to<sentinel_t<R>, S>
64
  constexpr subrange(R&& r) requires (!StoreSize || sized_range<R>);
65
 
66
  template<borrowed_range R>
67
  requires convertible-to-non-slicing<iterator_t<R>, I> &&
68
  convertible_to<sentinel_t<R>, S>
69
  constexpr subrange(R&& r, make-unsigned-like-t<iter_difference_t<I>> n)
70
  requires (K == subrange_kind::sized)
71
- : subrange{ranges::begin(r), ranges::end(r), n}
72
- {}
73
 
74
- template<not-same-as<subrange> PairLike>
75
  requires pair-like-convertible-from<PairLike, const I&, const S&>
76
  constexpr operator PairLike() const;
77
 
78
  constexpr I begin() const requires copyable<I>;
79
  [[nodiscard]] constexpr I begin() requires (!copyable<I>);
@@ -96,38 +84,19 @@ namespace std::ranges {
96
 
97
  template<input_or_output_iterator I, sentinel_for<I> S>
98
  subrange(I, S, make-unsigned-like-t<iter_difference_t<I>>) ->
99
  subrange<I, S, subrange_kind::sized>;
100
 
101
- template<iterator-sentinel-pair P>
102
- subrange(P) -> subrange<tuple_element_t<0, P>, tuple_element_t<1, P>>;
103
-
104
- template<iterator-sentinel-pair P>
105
- subrange(P, make-unsigned-like-t<iter_difference_t<tuple_element_t<0, P>>>) ->
106
- subrange<tuple_element_t<0, P>, tuple_element_t<1, P>, subrange_kind::sized>;
107
-
108
  template<borrowed_range R>
109
  subrange(R&&) ->
110
  subrange<iterator_t<R>, sentinel_t<R>,
111
  (sized_range<R> || sized_sentinel_for<sentinel_t<R>, iterator_t<R>>)
112
  ? subrange_kind::sized : subrange_kind::unsized>;
113
 
114
  template<borrowed_range R>
115
  subrange(R&&, make-unsigned-like-t<range_difference_t<R>>) ->
116
  subrange<iterator_t<R>, sentinel_t<R>, subrange_kind::sized>;
117
-
118
- template<size_t N, class I, class S, subrange_kind K>
119
- requires (N < 2)
120
- constexpr auto get(const subrange<I, S, K>& r);
121
-
122
- template<size_t N, class I, class S, subrange_kind K>
123
- requires (N < 2)
124
- constexpr auto get(subrange<I, S, K>&& r);
125
- }
126
-
127
- namespace std {
128
- using ranges::get;
129
  }
130
  ```
131
 
132
  #### Constructors and conversions <a id="range.subrange.ctor">[[range.subrange.ctor]]</a>
133
 
@@ -145,35 +114,36 @@ constexpr subrange(convertible-to-non-slicing<I> auto i, S s,
145
  make-unsigned-like-t<iter_difference_t<I>> n)
146
  requires (K == subrange_kind::sized);
147
  ```
148
 
149
  *Preconditions:* \[`i`, `s`) is a valid range, and
150
- `n == `*`to-unsigned-like`*`(ranges::distance(i, s))`.
151
 
152
  *Effects:* Initializes *begin\_* with `std::move(i)` and *end\_* with
153
  `s`. If *StoreSize* is `true`, initializes *size\_* with `n`.
154
 
155
  [*Note 1*: Accepting the length of the range and storing it to later
156
  return from `size()` enables `subrange` to model `sized_range` even when
157
  it stores an iterator and sentinel that do not model
158
  `sized_sentinel_for`. — *end note*]
159
 
160
  ``` cpp
161
- template<not-same-as<subrange> R>
162
  requires borrowed_range<R> &&
163
  convertible-to-non-slicing<iterator_t<R>, I> &&
164
  convertible_to<sentinel_t<R>, S>
165
  constexpr subrange(R&& r) requires (!StoreSize || sized_range<R>);
166
  ```
167
 
168
  *Effects:* Equivalent to:
169
 
170
- - If *StoreSize* is `true`, `subrange{r, ranges::size(r)}`.
171
- - Otherwise, `subrange{ranges::begin(r), ranges::end(r)}`.
 
172
 
173
  ``` cpp
174
- template<not-same-as<subrange> PairLike>
175
  requires pair-like-convertible-from<PairLike, const I&, const S&>
176
  constexpr operator PairLike() const;
177
  ```
178
 
179
  *Effects:* Equivalent to: `return PairLike(`*`begin_`*`, `*`end_`*`);`
@@ -256,28 +226,29 @@ return tmp;
256
  constexpr subrange& advance(iter_difference_t<I> n);
257
  ```
258
 
259
  *Effects:* Equivalent to:
260
 
261
- - If *StoreSize* is `true`,
262
  ``` cpp
 
 
 
 
 
 
 
 
 
263
  auto d = n - ranges::advance(begin_, n, end_);
264
- if (d >= 0)
265
  size_ -= to-unsigned-like(d);
266
- else
267
- size_ += to-unsigned-like(-d);
268
- return *this;
269
- ```
270
- - Otherwise,
271
- ``` cpp
272
- ranges::advance(begin_, n, end_);
273
  return *this;
274
  ```
275
 
276
  ``` cpp
277
  template<size_t N, class I, class S, subrange_kind K>
278
- requires (N < 2)
279
  constexpr auto get(const subrange<I, S, K>& r);
280
  template<size_t N, class I, class S, subrange_kind K>
281
  requires (N < 2)
282
  constexpr auto get(subrange<I, S, K>&& r);
283
  ```
 
1
  ### Sub-ranges <a id="range.subrange">[[range.subrange]]</a>
2
 
3
+ #### General <a id="range.subrange.general">[[range.subrange.general]]</a>
4
+
5
  The `subrange` class template combines together an iterator and a
6
  sentinel into a single object that models the `view` concept.
7
  Additionally, it models the `sized_range` concept when the final
8
  template parameter is `subrange_kind::sized`.
9
 
10
  ``` cpp
11
  namespace std::ranges {
12
+ template<class From, class To>
13
+ concept uses-nonqualification-pointer-conversion = // exposition only
14
+ is_pointer_v<From> && is_pointer_v<To> &&
15
+ !convertible_to<remove_pointer_t<From>(*)[], remove_pointer_t<To>(*)[]>;
16
+
17
  template<class From, class To>
18
  concept convertible-to-non-slicing = // exposition only
19
  convertible_to<From, To> &&
20
+ !uses-nonqualification-pointer-conversion<decay_t<From>, decay_t<To>>;
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  template<class T, class U, class V>
23
  concept pair-like-convertible-from = // exposition only
24
+ !range<T> && !is_reference_v<T> && pair-like<T> &&
25
  constructible_from<T, U, V> &&
26
  convertible-to-non-slicing<U, tuple_element_t<0, T>> &&
27
  convertible_to<V, tuple_element_t<1, T>>;
28
 
 
 
 
 
 
29
  template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K =
30
  sized_sentinel_for<S, I> ? subrange_kind::sized : subrange_kind::unsized>
31
  requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
32
  class subrange : public view_interface<subrange<I, S, K>> {
33
  private:
34
  static constexpr bool StoreSize = // exposition only
35
  K == subrange_kind::sized && !sized_sentinel_for<S, I>;
36
  I begin_ = I(); // exposition only
37
  S end_ = S(); // exposition only
38
  make-unsigned-like-t<iter_difference_t<I>> size_ = 0; // exposition only; present only
39
+ // if StoreSize is true
40
  public:
41
+ subrange() requires default_initializable<I> = default;
42
 
43
  constexpr subrange(convertible-to-non-slicing<I> auto i, S s) requires (!StoreSize);
44
 
45
  constexpr subrange(convertible-to-non-slicing<I> auto i, S s,
46
  make-unsigned-like-t<iter_difference_t<I>> n)
47
  requires (K == subrange_kind::sized);
48
 
49
+ template<different-from<subrange> R>
50
  requires borrowed_range<R> &&
51
  convertible-to-non-slicing<iterator_t<R>, I> &&
52
  convertible_to<sentinel_t<R>, S>
53
  constexpr subrange(R&& r) requires (!StoreSize || sized_range<R>);
54
 
55
  template<borrowed_range R>
56
  requires convertible-to-non-slicing<iterator_t<R>, I> &&
57
  convertible_to<sentinel_t<R>, S>
58
  constexpr subrange(R&& r, make-unsigned-like-t<iter_difference_t<I>> n)
59
  requires (K == subrange_kind::sized)
60
+ : subrange{ranges::begin(r), ranges::end(r), n} {}
 
61
 
62
+ template<different-from<subrange> PairLike>
63
  requires pair-like-convertible-from<PairLike, const I&, const S&>
64
  constexpr operator PairLike() const;
65
 
66
  constexpr I begin() const requires copyable<I>;
67
  [[nodiscard]] constexpr I begin() requires (!copyable<I>);
 
84
 
85
  template<input_or_output_iterator I, sentinel_for<I> S>
86
  subrange(I, S, make-unsigned-like-t<iter_difference_t<I>>) ->
87
  subrange<I, S, subrange_kind::sized>;
88
 
 
 
 
 
 
 
 
89
  template<borrowed_range R>
90
  subrange(R&&) ->
91
  subrange<iterator_t<R>, sentinel_t<R>,
92
  (sized_range<R> || sized_sentinel_for<sentinel_t<R>, iterator_t<R>>)
93
  ? subrange_kind::sized : subrange_kind::unsized>;
94
 
95
  template<borrowed_range R>
96
  subrange(R&&, make-unsigned-like-t<range_difference_t<R>>) ->
97
  subrange<iterator_t<R>, sentinel_t<R>, subrange_kind::sized>;
 
 
 
 
 
 
 
 
 
 
 
 
98
  }
99
  ```
100
 
101
  #### Constructors and conversions <a id="range.subrange.ctor">[[range.subrange.ctor]]</a>
102
 
 
114
  make-unsigned-like-t<iter_difference_t<I>> n)
115
  requires (K == subrange_kind::sized);
116
  ```
117
 
118
  *Preconditions:* \[`i`, `s`) is a valid range, and
119
+ `n == `*`to-unsigned-like`*`(ranges::distance(i, s))` is `true`.
120
 
121
  *Effects:* Initializes *begin\_* with `std::move(i)` and *end\_* with
122
  `s`. If *StoreSize* is `true`, initializes *size\_* with `n`.
123
 
124
  [*Note 1*: Accepting the length of the range and storing it to later
125
  return from `size()` enables `subrange` to model `sized_range` even when
126
  it stores an iterator and sentinel that do not model
127
  `sized_sentinel_for`. — *end note*]
128
 
129
  ``` cpp
130
+ template<different-from<subrange> R>
131
  requires borrowed_range<R> &&
132
  convertible-to-non-slicing<iterator_t<R>, I> &&
133
  convertible_to<sentinel_t<R>, S>
134
  constexpr subrange(R&& r) requires (!StoreSize || sized_range<R>);
135
  ```
136
 
137
  *Effects:* Equivalent to:
138
 
139
+ - If *StoreSize* is `true`,
140
+ `subrange(r, static_cast<decltype(`*`size_`*`)>(ranges::size(r)))`.
141
+ - Otherwise, `subrange(ranges::begin(r), ranges::end(r))`.
142
 
143
  ``` cpp
144
+ template<different-from<subrange> PairLike>
145
  requires pair-like-convertible-from<PairLike, const I&, const S&>
146
  constexpr operator PairLike() const;
147
  ```
148
 
149
  *Effects:* Equivalent to: `return PairLike(`*`begin_`*`, `*`end_`*`);`
 
226
  constexpr subrange& advance(iter_difference_t<I> n);
227
  ```
228
 
229
  *Effects:* Equivalent to:
230
 
 
231
  ``` cpp
232
+ if constexpr (bidirectional_iterator<I>) {
233
+ if (n < 0) {
234
+ ranges::advance(begin_, n);
235
+ if constexpr (StoreSize)
236
+ size_ += to-unsigned-like(-n);
237
+ return *this;
238
+ }
239
+ }
240
+
241
  auto d = n - ranges::advance(begin_, n, end_);
242
+ if constexpr (StoreSize)
243
  size_ -= to-unsigned-like(d);
 
 
 
 
 
 
 
244
  return *this;
245
  ```
246
 
247
  ``` cpp
248
  template<size_t N, class I, class S, subrange_kind K>
249
+ requires ((N == 0 && copyable<I>) || N == 1)
250
  constexpr auto get(const subrange<I, S, K>& r);
251
  template<size_t N, class I, class S, subrange_kind K>
252
  requires (N < 2)
253
  constexpr auto get(subrange<I, S, K>&& r);
254
  ```