From Jason Turner

[views.contiguous]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmphim1yn76/{from.md → to.md} +516 -0
tmp/tmphim1yn76/{from.md → to.md} RENAMED
@@ -0,0 +1,516 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Contiguous access <a id="views.contiguous">[[views.contiguous]]</a>
2
+
3
+ #### Header `<span>` synopsis <a id="span.syn">[[span.syn]]</a>
4
+
5
+ ``` cpp
6
+ namespace std {
7
+ // constants
8
+ inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
9
+
10
+ // [views.span], class template span
11
+ template<class ElementType, size_t Extent = dynamic_extent>
12
+ class span;
13
+
14
+ template<class ElementType, size_t Extent>
15
+ constexpr bool ranges::enable_view<span<ElementType, Extent>> = true;
16
+ template<class ElementType, size_t Extent>
17
+ constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
18
+
19
+ // [span.objectrep], views of object representation
20
+ template<class ElementType, size_t Extent>
21
+ span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
22
+ as_bytes(span<ElementType, Extent> s) noexcept;
23
+
24
+ template<class ElementType, size_t Extent>
25
+ span<byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
26
+ as_writable_bytes(span<ElementType, Extent> s) noexcept;
27
+ }
28
+ ```
29
+
30
+ #### Class template `span` <a id="views.span">[[views.span]]</a>
31
+
32
+ ##### Overview <a id="span.overview">[[span.overview]]</a>
33
+
34
+ A `span` is a view over a contiguous sequence of objects, the storage of
35
+ which is owned by some other object.
36
+
37
+ All member functions of `span` have constant time complexity.
38
+
39
+ ``` cpp
40
+ namespace std {
41
+ template<class ElementType, size_t Extent = dynamic_extent>
42
+ class span {
43
+ public:
44
+ // constants and types
45
+ using element_type = ElementType;
46
+ using value_type = remove_cv_t<ElementType>;
47
+ using size_type = size_t;
48
+ using difference_type = ptrdiff_t;
49
+ using pointer = element_type*;
50
+ using const_pointer = const element_type*;
51
+ using reference = element_type&;
52
+ using const_reference = const element_type&;
53
+ using iterator = implementation-defined // type of span::iterator; // see [span.iterators]
54
+ using const_iterator = std::const_iterator<iterator>;
55
+ using reverse_iterator = std::reverse_iterator<iterator>;
56
+ using const_reverse_iterator = std::const_iterator<reverse_iterator>;
57
+ static constexpr size_type extent = Extent;
58
+
59
+ // [span.cons], constructors, copy, and assignment
60
+ constexpr span() noexcept;
61
+ template<class It>
62
+ constexpr explicit(extent != dynamic_extent) span(It first, size_type count);
63
+ template<class It, class End>
64
+ constexpr explicit(extent != dynamic_extent) span(It first, End last);
65
+ template<size_t N>
66
+ constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
67
+ template<class T, size_t N>
68
+ constexpr span(array<T, N>& arr) noexcept;
69
+ template<class T, size_t N>
70
+ constexpr span(const array<T, N>& arr) noexcept;
71
+ template<class R>
72
+ constexpr explicit(extent != dynamic_extent) span(R&& r);
73
+ constexpr span(const span& other) noexcept = default;
74
+ template<class OtherElementType, size_t OtherExtent>
75
+ constexpr explicit(see below) span(const span<OtherElementType, OtherExtent>& s) noexcept;
76
+
77
+ ~span() noexcept = default;
78
+
79
+ constexpr span& operator=(const span& other) noexcept = default;
80
+
81
+ // [span.sub], subviews
82
+ template<size_t Count>
83
+ constexpr span<element_type, Count> first() const;
84
+ template<size_t Count>
85
+ constexpr span<element_type, Count> last() const;
86
+ template<size_t Offset, size_t Count = dynamic_extent>
87
+ constexpr span<element_type, see below> subspan() const;
88
+
89
+ constexpr span<element_type, dynamic_extent> first(size_type count) const;
90
+ constexpr span<element_type, dynamic_extent> last(size_type count) const;
91
+ constexpr span<element_type, dynamic_extent> subspan(
92
+ size_type offset, size_type count = dynamic_extent) const;
93
+
94
+ // [span.obs], observers
95
+ constexpr size_type size() const noexcept;
96
+ constexpr size_type size_bytes() const noexcept;
97
+ [[nodiscard]] constexpr bool empty() const noexcept;
98
+
99
+ // [span.elem], element access
100
+ constexpr reference operator[](size_type idx) const;
101
+ constexpr reference front() const;
102
+ constexpr reference back() const;
103
+ constexpr pointer data() const noexcept;
104
+
105
+ // [span.iterators], iterator support
106
+ constexpr iterator begin() const noexcept;
107
+ constexpr iterator end() const noexcept;
108
+ constexpr const_iterator cbegin() const noexcept { return begin(); }
109
+ constexpr const_iterator cend() const noexcept { return end(); }
110
+ constexpr reverse_iterator rbegin() const noexcept;
111
+ constexpr reverse_iterator rend() const noexcept;
112
+ constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
113
+ constexpr const_reverse_iterator crend() const noexcept { return rend(); }
114
+
115
+ private:
116
+ pointer data_; // exposition only
117
+ size_type size_; // exposition only
118
+ };
119
+
120
+ template<class It, class EndOrSize>
121
+ span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>>;
122
+ template<class T, size_t N>
123
+ span(T (&)[N]) -> span<T, N>;
124
+ template<class T, size_t N>
125
+ span(array<T, N>&) -> span<T, N>;
126
+ template<class T, size_t N>
127
+ span(const array<T, N>&) -> span<const T, N>;
128
+ template<class R>
129
+ span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
130
+ }
131
+ ```
132
+
133
+ `span<ElementType, Extent>` is a trivially copyable type
134
+ [[term.trivially.copyable.type]].
135
+
136
+ `ElementType` is required to be a complete object type that is not an
137
+ abstract class type.
138
+
139
+ ##### Constructors, copy, and assignment <a id="span.cons">[[span.cons]]</a>
140
+
141
+ ``` cpp
142
+ constexpr span() noexcept;
143
+ ```
144
+
145
+ *Constraints:* `Extent == dynamic_extent || Extent == 0` is `true`.
146
+
147
+ *Ensures:* `size() == 0 && data() == nullptr`.
148
+
149
+ ``` cpp
150
+ template<class It>
151
+ constexpr explicit(extent != dynamic_extent) span(It first, size_type count);
152
+ ```
153
+
154
+ *Constraints:* Let `U` be `remove_reference_t<iter_reference_t<It>>`.
155
+
156
+ - `It` satisfies `contiguous_iterator`.
157
+ - `is_convertible_v<U(*)[], element_type(*)[]>` is `true`.
158
+ \[*Note 1*: The intent is to allow only qualification conversions of
159
+ the iterator reference type to `element_type`. — *end note*]
160
+
161
+ *Preconditions:*
162
+
163
+ - \[`first`, `first + count`) is a valid range.
164
+ - `It` models `contiguous_iterator`.
165
+ - If `extent` is not equal to `dynamic_extent`, then `count` is equal to
166
+ `extent`.
167
+
168
+ *Effects:* Initializes *`data_`* with `to_address(first)` and *`size_`*
169
+ with `count`.
170
+
171
+ *Throws:* Nothing.
172
+
173
+ ``` cpp
174
+ template<class It, class End>
175
+ constexpr explicit(extent != dynamic_extent) span(It first, End last);
176
+ ```
177
+
178
+ *Constraints:* Let `U` be `remove_reference_t<iter_reference_t<It>>`.
179
+
180
+ - `is_convertible_v<U(*)[], element_type(*)[]>` is `true`.
181
+ \[*Note 2*: The intent is to allow only qualification conversions of
182
+ the iterator reference type to `element_type`. — *end note*]
183
+ - `It` satisfies `contiguous_iterator`.
184
+ - `End` satisfies `sized_sentinel_for<It>`.
185
+ - `is_convertible_v<End, size_t>` is `false`.
186
+
187
+ *Preconditions:*
188
+
189
+ - If `extent` is not equal to `dynamic_extent`, then `last - first` is
190
+ equal to `extent`.
191
+ - \[`first`, `last`) is a valid range.
192
+ - `It` models `contiguous_iterator`.
193
+ - `End` models `sized_sentinel_for<It>`.
194
+
195
+ *Effects:* Initializes *`data_`* with `to_address(first)` and *`size_`*
196
+ with `last - first`.
197
+
198
+ *Throws:* When and what `last - first` throws.
199
+
200
+ ``` cpp
201
+ template<size_t N> constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
202
+ template<class T, size_t N> constexpr span(array<T, N>& arr) noexcept;
203
+ template<class T, size_t N> constexpr span(const array<T, N>& arr) noexcept;
204
+ ```
205
+
206
+ *Constraints:* Let `U` be `remove_pointer_t<decltype(data(arr))>`.
207
+
208
+ - `extent == dynamic_extent || N == extent` is `true`, and
209
+ - `is_convertible_v<U(*)[], element_type(*)[]>` is `true`.
210
+ \[*Note 3*: The intent is to allow only qualification conversions of
211
+ the array element type to `element_type`. — *end note*]
212
+
213
+ *Effects:* Constructs a `span` that is a view over the supplied array.
214
+
215
+ [*Note 1*: `type_identity_t` affects class template argument
216
+ deduction. — *end note*]
217
+
218
+ *Ensures:* `size() == N && data() == data(arr)` is `true`.
219
+
220
+ ``` cpp
221
+ template<class R> constexpr explicit(extent != dynamic_extent) span(R&& r);
222
+ ```
223
+
224
+ *Constraints:* Let `U` be
225
+ `remove_reference_t<ranges::range_reference_t<R>>`.
226
+
227
+ - `R` satisfies `ranges::contiguous_range` and `ranges::sized_range`.
228
+ - Either `R` satisfies `ranges::borrowed_range` or
229
+ `is_const_v<element_type>` is `true`.
230
+ - `remove_cvref_t<R>` is not a specialization of `span`.
231
+ - `remove_cvref_t<R>` is not a specialization of `array`.
232
+ - `is_array_v<remove_cvref_t<R>>` is `false`.
233
+ - `is_convertible_v<U(*)[], element_type(*)[]>` is `true`.
234
+ \[*Note 4*: The intent is to allow only qualification conversions of
235
+ the range reference type to `element_type`. — *end note*]
236
+
237
+ *Preconditions:*
238
+
239
+ - If `extent` is not equal to `dynamic_extent`, then `ranges::size(r)`
240
+ is equal to `extent`.
241
+ - `R` models `ranges::contiguous_range` and `ranges::sized_range`.
242
+ - If `is_const_v<element_type>` is `false`, `R` models
243
+ `ranges::borrowed_range`.
244
+
245
+ *Effects:* Initializes *`data_`* with `ranges::data(r)` and *`size_`*
246
+ with `ranges::size(r)`.
247
+
248
+ *Throws:* What and when `ranges::data(r)` and `ranges::size(r)` throw.
249
+
250
+ ``` cpp
251
+ constexpr span(const span& other) noexcept = default;
252
+ ```
253
+
254
+ *Ensures:* `other.size() == size() && other.data() == data()`.
255
+
256
+ ``` cpp
257
+ template<class OtherElementType, size_t OtherExtent>
258
+ constexpr explicit(see below) span(const span<OtherElementType, OtherExtent>& s) noexcept;
259
+ ```
260
+
261
+ *Constraints:*
262
+
263
+ - `extent == dynamic_extent` `||` `OtherExtent == dynamic_extent` `||`
264
+ `extent == OtherExtent` is `true`, and
265
+ - `is_convertible_v<OtherElementType(*)[], element_type(*)[]>` is
266
+ `true`. \[*Note 5*: The intent is to allow only qualification
267
+ conversions of the `OtherElementType` to
268
+ `element_type`. — *end note*]
269
+
270
+ *Preconditions:* If `extent` is not equal to `dynamic_extent`, then
271
+ `s.size()` is equal to `extent`.
272
+
273
+ *Effects:* Constructs a `span` that is a view over the range
274
+ \[`s.data()`, `s.data() + s.size()`).
275
+
276
+ *Ensures:* `size() == s.size() && data() == s.data()`.
277
+
278
+ *Remarks:* The expression inside `explicit` is equivalent to:
279
+
280
+ ``` cpp
281
+ extent != dynamic_extent && OtherExtent == dynamic_extent
282
+ ```
283
+
284
+ ``` cpp
285
+ constexpr span& operator=(const span& other) noexcept = default;
286
+ ```
287
+
288
+ *Ensures:* `size() == other.size() && data() == other.data()`.
289
+
290
+ ##### Deduction guides <a id="span.deduct">[[span.deduct]]</a>
291
+
292
+ ``` cpp
293
+ template<class It, class EndOrSize>
294
+ span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>>;
295
+ ```
296
+
297
+ *Constraints:* `It` satisfies `contiguous_iterator`.
298
+
299
+ ``` cpp
300
+ template<class R>
301
+ span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
302
+ ```
303
+
304
+ *Constraints:* `R` satisfies `ranges::contiguous_range`.
305
+
306
+ ##### Subviews <a id="span.sub">[[span.sub]]</a>
307
+
308
+ ``` cpp
309
+ template<size_t Count> constexpr span<element_type, Count> first() const;
310
+ ```
311
+
312
+ *Mandates:* `Count <= Extent` is `true`.
313
+
314
+ *Preconditions:* `Count <= size()` is `true`.
315
+
316
+ *Effects:* Equivalent to: `return R{data(), Count};` where `R` is the
317
+ return type.
318
+
319
+ ``` cpp
320
+ template<size_t Count> constexpr span<element_type, Count> last() const;
321
+ ```
322
+
323
+ *Mandates:* `Count <= Extent` is `true`.
324
+
325
+ *Preconditions:* `Count <= size()` is `true`.
326
+
327
+ *Effects:* Equivalent to: `return R{data() + (size() - Count), Count};`
328
+ where `R` is the return type.
329
+
330
+ ``` cpp
331
+ template<size_t Offset, size_t Count = dynamic_extent>
332
+ constexpr span<element_type, see below> subspan() const;
333
+ ```
334
+
335
+ *Mandates:*
336
+
337
+ ``` cpp
338
+ Offset <= Extent && (Count == dynamic_extent || Count <= Extent - Offset)
339
+ ```
340
+
341
+ is `true`.
342
+
343
+ *Preconditions:*
344
+
345
+ ``` cpp
346
+ Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset)
347
+ ```
348
+
349
+ is `true`.
350
+
351
+ *Effects:* Equivalent to:
352
+
353
+ ``` cpp
354
+ return span<ElementType, see below>(
355
+ data() + Offset, Count != dynamic_extent ? Count : size() - Offset);
356
+ ```
357
+
358
+ *Remarks:* The second template argument of the returned `span` type is:
359
+
360
+ ``` cpp
361
+ Count != dynamic_extent ? Count
362
+ : (Extent != dynamic_extent ? Extent - Offset
363
+ : dynamic_extent)
364
+ ```
365
+
366
+ ``` cpp
367
+ constexpr span<element_type, dynamic_extent> first(size_type count) const;
368
+ ```
369
+
370
+ *Preconditions:* `count <= size()` is `true`.
371
+
372
+ *Effects:* Equivalent to: `return {data(), count};`
373
+
374
+ ``` cpp
375
+ constexpr span<element_type, dynamic_extent> last(size_type count) const;
376
+ ```
377
+
378
+ *Preconditions:* `count <= size()` is `true`.
379
+
380
+ *Effects:* Equivalent to: `return {data() + (size() - count), count};`
381
+
382
+ ``` cpp
383
+ constexpr span<element_type, dynamic_extent> subspan(
384
+ size_type offset, size_type count = dynamic_extent) const;
385
+ ```
386
+
387
+ *Preconditions:*
388
+
389
+ ``` cpp
390
+ offset <= size() && (count == dynamic_extent || count <= size() - offset)
391
+ ```
392
+
393
+ is `true`.
394
+
395
+ *Effects:* Equivalent to:
396
+
397
+ ``` cpp
398
+ return {data() + offset, count == dynamic_extent ? size() - offset : count};
399
+ ```
400
+
401
+ ##### Observers <a id="span.obs">[[span.obs]]</a>
402
+
403
+ ``` cpp
404
+ constexpr size_type size() const noexcept;
405
+ ```
406
+
407
+ *Effects:* Equivalent to: `return `*`size_`*`;`
408
+
409
+ ``` cpp
410
+ constexpr size_type size_bytes() const noexcept;
411
+ ```
412
+
413
+ *Effects:* Equivalent to: `return size() * sizeof(element_type);`
414
+
415
+ ``` cpp
416
+ [[nodiscard]] constexpr bool empty() const noexcept;
417
+ ```
418
+
419
+ *Effects:* Equivalent to: `return size() == 0;`
420
+
421
+ ##### Element access <a id="span.elem">[[span.elem]]</a>
422
+
423
+ ``` cpp
424
+ constexpr reference operator[](size_type idx) const;
425
+ ```
426
+
427
+ *Preconditions:* `idx < size()` is `true`.
428
+
429
+ *Effects:* Equivalent to: `return *(data() + idx);`
430
+
431
+ ``` cpp
432
+ constexpr reference front() const;
433
+ ```
434
+
435
+ *Preconditions:* `empty()` is `false`.
436
+
437
+ *Effects:* Equivalent to: `return *data();`
438
+
439
+ ``` cpp
440
+ constexpr reference back() const;
441
+ ```
442
+
443
+ *Preconditions:* `empty()` is `false`.
444
+
445
+ *Effects:* Equivalent to: `return *(data() + (size() - 1));`
446
+
447
+ ``` cpp
448
+ constexpr pointer data() const noexcept;
449
+ ```
450
+
451
+ *Effects:* Equivalent to: `return `*`data_`*`;`
452
+
453
+ ##### Iterator support <a id="span.iterators">[[span.iterators]]</a>
454
+
455
+ ``` cpp
456
+ using iterator = implementation-defined // type of span::iterator;
457
+ ```
458
+
459
+ The type models `contiguous_iterator` [[iterator.concept.contiguous]],
460
+ meets the *Cpp17RandomAccessIterator*
461
+ requirements [[random.access.iterators]], and meets the requirements for
462
+ constexpr iterators [[iterator.requirements.general]], whose value type
463
+ is `value_type` and whose reference type is `reference`.
464
+
465
+ All requirements on container iterators [[container.reqmts]] apply to
466
+ `span::iterator` as well.
467
+
468
+ ``` cpp
469
+ constexpr iterator begin() const noexcept;
470
+ ```
471
+
472
+ *Returns:* An iterator referring to the first element in the span. If
473
+ `empty()` is `true`, then it returns the same value as `end()`.
474
+
475
+ ``` cpp
476
+ constexpr iterator end() const noexcept;
477
+ ```
478
+
479
+ *Returns:* An iterator which is the past-the-end value.
480
+
481
+ ``` cpp
482
+ constexpr reverse_iterator rbegin() const noexcept;
483
+ ```
484
+
485
+ *Effects:* Equivalent to: `return reverse_iterator(end());`
486
+
487
+ ``` cpp
488
+ constexpr reverse_iterator rend() const noexcept;
489
+ ```
490
+
491
+ *Effects:* Equivalent to: `return reverse_iterator(begin());`
492
+
493
+ #### Views of object representation <a id="span.objectrep">[[span.objectrep]]</a>
494
+
495
+ ``` cpp
496
+ template<class ElementType, size_t Extent>
497
+ span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
498
+ as_bytes(span<ElementType, Extent> s) noexcept;
499
+ ```
500
+
501
+ *Effects:* Equivalent to:
502
+ `return R{reinterpret_cast<const byte*>(s.data()), s.size_bytes()};`
503
+ where `R` is the return type.
504
+
505
+ ``` cpp
506
+ template<class ElementType, size_t Extent>
507
+ span<byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
508
+ as_writable_bytes(span<ElementType, Extent> s) noexcept;
509
+ ```
510
+
511
+ *Constraints:* `is_const_v<ElementType>` is `false`.
512
+
513
+ *Effects:* Equivalent to:
514
+ `return R{reinterpret_cast<byte*>(s.data()), s.size_bytes()};` where `R`
515
+ is the return type.
516
+