From Jason Turner

[views]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpwh75wt21/{from.md → to.md} +1895 -45
tmp/tmpwh75wt21/{from.md → to.md} RENAMED
@@ -1,12 +1,16 @@
1
  ## Views <a id="views">[[views]]</a>
2
 
3
  ### General <a id="views.general">[[views.general]]</a>
4
 
5
- The header `<span>` defines the view `span`.
 
 
6
 
7
- ### Header `<span>` synopsis <a id="span.syn">[[span.syn]]</a>
 
 
8
 
9
  ``` cpp
10
  namespace std {
11
  // constants
12
  inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
@@ -14,14 +18,13 @@ namespace std {
14
  // [views.span], class template span
15
  template<class ElementType, size_t Extent = dynamic_extent>
16
  class span;
17
 
18
  template<class ElementType, size_t Extent>
19
- inline constexpr bool ranges::enable_view<span<ElementType, Extent>> =
20
- Extent == 0 || Extent == dynamic_extent;
21
  template<class ElementType, size_t Extent>
22
- inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
23
 
24
  // [span.objectrep], views of object representation
25
  template<class ElementType, size_t Extent>
26
  span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
27
  as_bytes(span<ElementType, Extent> s) noexcept;
@@ -30,13 +33,13 @@ namespace std {
30
  span<byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
31
  as_writable_bytes(span<ElementType, Extent> s) noexcept;
32
  }
33
  ```
34
 
35
- ### Class template `span` <a id="views.span">[[views.span]]</a>
36
 
37
- #### Overview <a id="span.overview">[[span.overview]]</a>
38
 
39
  A `span` is a view over a contiguous sequence of objects, the storage of
40
  which is owned by some other object.
41
 
42
  All member functions of `span` have constant time complexity.
@@ -54,11 +57,13 @@ namespace std {
54
  using pointer = element_type*;
55
  using const_pointer = const element_type*;
56
  using reference = element_type&;
57
  using const_reference = const element_type&;
58
  using iterator = implementation-defined // type of span::iterator; // see [span.iterators]
 
59
  using reverse_iterator = std::reverse_iterator<iterator>;
 
60
  static constexpr size_type extent = Extent;
61
 
62
  // [span.cons], constructors, copy, and assignment
63
  constexpr span() noexcept;
64
  template<class It>
@@ -106,12 +111,16 @@ namespace std {
106
  constexpr pointer data() const noexcept;
107
 
108
  // [span.iterators], iterator support
109
  constexpr iterator begin() const noexcept;
110
  constexpr iterator end() const noexcept;
 
 
111
  constexpr reverse_iterator rbegin() const noexcept;
112
  constexpr reverse_iterator rend() const noexcept;
 
 
113
 
114
  private:
115
  pointer data_; // exposition only
116
  size_type size_; // exposition only
117
  };
@@ -127,14 +136,17 @@ namespace std {
127
  template<class R>
128
  span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
129
  }
130
  ```
131
 
 
 
 
132
  `ElementType` is required to be a complete object type that is not an
133
  abstract class type.
134
 
135
- #### Constructors, copy, and assignment <a id="span.cons">[[span.cons]]</a>
136
 
137
  ``` cpp
138
  constexpr span() noexcept;
139
  ```
140
 
@@ -159,12 +171,12 @@ template<class It>
159
  - \[`first`, `first + count`) is a valid range.
160
  - `It` models `contiguous_iterator`.
161
  - If `extent` is not equal to `dynamic_extent`, then `count` is equal to
162
  `extent`.
163
 
164
- *Effects:* Initializes `data_` with `to_address(first)` and `size_` with
165
- `count`.
166
 
167
  *Throws:* Nothing.
168
 
169
  ``` cpp
170
  template<class It, class End>
@@ -186,12 +198,12 @@ template<class It, class End>
186
  equal to `extent`.
187
  - \[`first`, `last`) is a valid range.
188
  - `It` models `contiguous_iterator`.
189
  - `End` models `sized_sentinel_for<It>`.
190
 
191
- *Effects:* Initializes `data_` with `to_address(first)` and `size_` with
192
- `last - first`.
193
 
194
  *Throws:* When and what `last - first` throws.
195
 
196
  ``` cpp
197
  template<size_t N> constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
@@ -236,12 +248,12 @@ template<class R> constexpr explicit(extent != dynamic_extent) span(R&& r);
236
  is equal to `extent`.
237
  - `R` models `ranges::contiguous_range` and `ranges::sized_range`.
238
  - If `is_const_v<element_type>` is `false`, `R` models
239
  `ranges::borrowed_range`.
240
 
241
- *Effects:* Initializes `data_` with `ranges::data(r)` and `size_` with
242
- `ranges::size(r)`.
243
 
244
  *Throws:* What and when `ranges::data(r)` and `ranges::size(r)` throw.
245
 
246
  ``` cpp
247
  constexpr span(const span& other) noexcept = default;
@@ -281,11 +293,11 @@ extent != dynamic_extent && OtherExtent == dynamic_extent
281
  constexpr span& operator=(const span& other) noexcept = default;
282
  ```
283
 
284
  *Ensures:* `size() == other.size() && data() == other.data()`.
285
 
286
- #### Deduction guides <a id="span.deduct">[[span.deduct]]</a>
287
 
288
  ``` cpp
289
  template<class It, class EndOrSize>
290
  span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>>;
291
  ```
@@ -297,11 +309,11 @@ template<class R>
297
  span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
298
  ```
299
 
300
  *Constraints:* `R` satisfies `ranges::contiguous_range`.
301
 
302
- #### Subviews <a id="span.sub">[[span.sub]]</a>
303
 
304
  ``` cpp
305
  template<size_t Count> constexpr span<element_type, Count> first() const;
306
  ```
307
 
@@ -392,17 +404,17 @@ is `true`.
392
 
393
  ``` cpp
394
  return {data() + offset, count == dynamic_extent ? size() - offset : count};
395
  ```
396
 
397
- #### Observers <a id="span.obs">[[span.obs]]</a>
398
 
399
  ``` cpp
400
  constexpr size_type size() const noexcept;
401
  ```
402
 
403
- *Effects:* Equivalent to: `return size_;`
404
 
405
  ``` cpp
406
  constexpr size_type size_bytes() const noexcept;
407
  ```
408
 
@@ -412,11 +424,11 @@ constexpr size_type size_bytes() const noexcept;
412
  [[nodiscard]] constexpr bool empty() const noexcept;
413
  ```
414
 
415
  *Effects:* Equivalent to: `return size() == 0;`
416
 
417
- #### Element access <a id="span.elem">[[span.elem]]</a>
418
 
419
  ``` cpp
420
  constexpr reference operator[](size_type idx) const;
421
  ```
422
 
@@ -442,23 +454,25 @@ constexpr reference back() const;
442
 
443
  ``` cpp
444
  constexpr pointer data() const noexcept;
445
  ```
446
 
447
- *Effects:* Equivalent to: `return data_;`
448
 
449
- #### Iterator support <a id="span.iterators">[[span.iterators]]</a>
450
 
451
  ``` cpp
452
  using iterator = implementation-defined // type of span::iterator;
453
  ```
454
 
455
  The type models `contiguous_iterator` [[iterator.concept.contiguous]],
456
  meets the *Cpp17RandomAccessIterator*
457
  requirements [[random.access.iterators]], and meets the requirements for
458
- constexpr iterators [[iterator.requirements.general]]. All requirements
459
- on container iterators [[container.requirements]] apply to
 
 
460
  `span::iterator` as well.
461
 
462
  ``` cpp
463
  constexpr iterator begin() const noexcept;
464
  ```
@@ -506,18 +520,1781 @@ template<class ElementType, size_t Extent>
506
 
507
  *Effects:* Equivalent to:
508
  `return R{reinterpret_cast<byte*>(s.data()), s.size_bytes()};` where `R`
509
  is the return type.
510
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
511
  <!-- Link reference definitions -->
 
512
  [alg.sorting]: algorithms.md#alg.sorting
513
  [algorithm.stable]: library.md#algorithm.stable
514
  [algorithms]: algorithms.md#algorithms
515
  [algorithms.requirements]: algorithms.md#algorithms.requirements
516
  [allocator.requirements]: library.md#allocator.requirements
517
  [allocator.requirements.completeness]: library.md#allocator.requirements.completeness
518
- [allocator.traits.members]: utilities.md#allocator.traits.members
 
519
  [array]: #array
520
  [array.cons]: #array.cons
521
  [array.creation]: #array.creation
522
  [array.members]: #array.members
523
  [array.overview]: #array.overview
@@ -528,58 +2305,90 @@ is the return type.
528
  [associative]: #associative
529
  [associative.general]: #associative.general
530
  [associative.map.syn]: #associative.map.syn
531
  [associative.reqmts]: #associative.reqmts
532
  [associative.reqmts.except]: #associative.reqmts.except
 
533
  [associative.set.syn]: #associative.set.syn
 
534
  [basic.string]: strings.md#basic.string
535
  [class.copy.ctor]: class.md#class.copy.ctor
536
  [class.default.ctor]: class.md#class.default.ctor
537
  [class.dtor]: class.md#class.dtor
538
  [container.adaptors]: #container.adaptors
 
539
  [container.adaptors.general]: #container.adaptors.general
540
- [container.alloc.req]: #container.alloc.req
541
- [container.assoc.req]: #container.assoc.req
542
- [container.hash.req]: #container.hash.req
543
  [container.insert.return]: #container.insert.return
544
  [container.node]: #container.node
545
  [container.node.compat]: #container.node.compat
546
  [container.node.cons]: #container.node.cons
547
  [container.node.dtor]: #container.node.dtor
548
  [container.node.modifiers]: #container.node.modifiers
549
  [container.node.observers]: #container.node.observers
550
  [container.node.overview]: #container.node.overview
551
- [container.opt]: #container.opt
552
- [container.req]: #container.req
553
  [container.requirements]: #container.requirements
554
  [container.requirements.dataraces]: #container.requirements.dataraces
555
  [container.requirements.general]: #container.requirements.general
556
- [container.rev.req]: #container.rev.req
557
- [container.seq.opt]: #container.seq.opt
558
- [container.seq.req]: #container.seq.req
559
  [containers]: #containers
560
  [containers.general]: #containers.general
561
  [containers.summary]: #containers.summary
562
  [dcl.init.aggr]: dcl.md#dcl.init.aggr
 
563
  [deque]: #deque
564
  [deque.capacity]: #deque.capacity
565
  [deque.cons]: #deque.cons
566
  [deque.erasure]: #deque.erasure
567
  [deque.modifiers]: #deque.modifiers
568
  [deque.overview]: #deque.overview
569
  [deque.syn]: #deque.syn
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
570
  [forward.list.erasure]: #forward.list.erasure
 
 
 
 
571
  [forward.list.syn]: #forward.list.syn
572
- [forwardlist]: #forwardlist
573
- [forwardlist.access]: #forwardlist.access
574
- [forwardlist.cons]: #forwardlist.cons
575
- [forwardlist.iter]: #forwardlist.iter
576
- [forwardlist.modifiers]: #forwardlist.modifiers
577
- [forwardlist.ops]: #forwardlist.ops
578
- [forwardlist.overview]: #forwardlist.overview
579
  [hash.requirements]: library.md#hash.requirements
580
  [iterator.concept.contiguous]: iterators.md#iterator.concept.contiguous
 
581
  [iterator.requirements]: iterators.md#iterator.requirements
582
  [iterator.requirements.general]: iterators.md#iterator.requirements.general
583
  [list]: #list
584
  [list.capacity]: #list.capacity
585
  [list.cons]: #list.cons
@@ -592,10 +2401,47 @@ is the return type.
592
  [map.access]: #map.access
593
  [map.cons]: #map.cons
594
  [map.erasure]: #map.erasure
595
  [map.modifiers]: #map.modifiers
596
  [map.overview]: #map.overview
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
597
  [multimap]: #multimap
598
  [multimap.cons]: #multimap.cons
599
  [multimap.erasure]: #multimap.erasure
600
  [multimap.modifiers]: #multimap.modifiers
601
  [multimap.overview]: #multimap.overview
@@ -611,10 +2457,11 @@ is the return type.
611
  [priqueue.special]: #priqueue.special
612
  [queue]: #queue
613
  [queue.cons]: #queue.cons
614
  [queue.cons.alloc]: #queue.cons.alloc
615
  [queue.defn]: #queue.defn
 
616
  [queue.ops]: #queue.ops
617
  [queue.special]: #queue.special
618
  [queue.syn]: #queue.syn
619
  [random.access.iterators]: iterators.md#random.access.iterators
620
  [res.on.data.races]: library.md#res.on.data.races
@@ -636,23 +2483,21 @@ is the return type.
636
  [span.syn]: #span.syn
637
  [stack]: #stack
638
  [stack.cons]: #stack.cons
639
  [stack.cons.alloc]: #stack.cons.alloc
640
  [stack.defn]: #stack.defn
 
 
641
  [stack.ops]: #stack.ops
642
  [stack.special]: #stack.special
643
  [stack.syn]: #stack.syn
644
  [strings]: strings.md#strings
645
  [swappable.requirements]: library.md#swappable.requirements
646
- [tab:container.opt]: #tab:container.opt
647
- [tab:container.req]: #tab:container.req
648
- [tab:container.rev.req]: #tab:container.rev.req
649
- [tab:container.seq.opt]: #tab:container.seq.opt
650
- [tab:container.seq.req]: #tab:container.seq.req
651
  [temp.deduct]: temp.md#temp.deduct
652
  [temp.param]: temp.md#temp.param
653
  [temp.type]: temp.md#temp.type
 
654
  [unord]: #unord
655
  [unord.general]: #unord.general
656
  [unord.hash]: utilities.md#unord.hash
657
  [unord.map]: #unord.map
658
  [unord.map.cnstr]: #unord.map.cnstr
@@ -670,26 +2515,31 @@ is the return type.
670
  [unord.multiset.cnstr]: #unord.multiset.cnstr
671
  [unord.multiset.erasure]: #unord.multiset.erasure
672
  [unord.multiset.overview]: #unord.multiset.overview
673
  [unord.req]: #unord.req
674
  [unord.req.except]: #unord.req.except
 
675
  [unord.set]: #unord.set
676
  [unord.set.cnstr]: #unord.set.cnstr
677
  [unord.set.erasure]: #unord.set.erasure
678
  [unord.set.overview]: #unord.set.overview
679
  [unord.set.syn]: #unord.set.syn
680
  [vector]: #vector
681
  [vector.bool]: #vector.bool
 
 
682
  [vector.capacity]: #vector.capacity
683
  [vector.cons]: #vector.cons
684
  [vector.data]: #vector.data
685
  [vector.erasure]: #vector.erasure
686
  [vector.modifiers]: #vector.modifiers
687
  [vector.overview]: #vector.overview
688
  [vector.syn]: #vector.syn
689
  [views]: #views
 
690
  [views.general]: #views.general
 
691
  [views.span]: #views.span
692
 
693
  [^1]: Equality comparison is a refinement of partitioning if no two
694
  objects that compare equal fall into different partitions.
695
 
@@ -697,7 +2547,7 @@ is the return type.
697
  iterators are random access iterators.
698
 
699
  [^3]: As specified in  [[allocator.requirements]], the requirements in
700
  this Clause apply only to lists whose allocators compare equal.
701
 
702
- [^4]: `reserve()` uses `Allocator::allocate()` which may throw an
703
  appropriate exception.
 
1
  ## Views <a id="views">[[views]]</a>
2
 
3
  ### General <a id="views.general">[[views.general]]</a>
4
 
5
+ The header `<span>` defines the view `span`. The header `<mdspan>`
6
+ defines the class template `mdspan` and other facilities for interacting
7
+ with these multidimensional views.
8
 
9
+ ### Contiguous access <a id="views.contiguous">[[views.contiguous]]</a>
10
+
11
+ #### Header `<span>` synopsis <a id="span.syn">[[span.syn]]</a>
12
 
13
  ``` cpp
14
  namespace std {
15
  // constants
16
  inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
 
18
  // [views.span], class template span
19
  template<class ElementType, size_t Extent = dynamic_extent>
20
  class span;
21
 
22
  template<class ElementType, size_t Extent>
23
+ constexpr bool ranges::enable_view<span<ElementType, Extent>> = true;
 
24
  template<class ElementType, size_t Extent>
25
+ constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
26
 
27
  // [span.objectrep], views of object representation
28
  template<class ElementType, size_t Extent>
29
  span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
30
  as_bytes(span<ElementType, Extent> s) noexcept;
 
33
  span<byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
34
  as_writable_bytes(span<ElementType, Extent> s) noexcept;
35
  }
36
  ```
37
 
38
+ #### Class template `span` <a id="views.span">[[views.span]]</a>
39
 
40
+ ##### Overview <a id="span.overview">[[span.overview]]</a>
41
 
42
  A `span` is a view over a contiguous sequence of objects, the storage of
43
  which is owned by some other object.
44
 
45
  All member functions of `span` have constant time complexity.
 
57
  using pointer = element_type*;
58
  using const_pointer = const element_type*;
59
  using reference = element_type&;
60
  using const_reference = const element_type&;
61
  using iterator = implementation-defined // type of span::iterator; // see [span.iterators]
62
+ using const_iterator = std::const_iterator<iterator>;
63
  using reverse_iterator = std::reverse_iterator<iterator>;
64
+ using const_reverse_iterator = std::const_iterator<reverse_iterator>;
65
  static constexpr size_type extent = Extent;
66
 
67
  // [span.cons], constructors, copy, and assignment
68
  constexpr span() noexcept;
69
  template<class It>
 
111
  constexpr pointer data() const noexcept;
112
 
113
  // [span.iterators], iterator support
114
  constexpr iterator begin() const noexcept;
115
  constexpr iterator end() const noexcept;
116
+ constexpr const_iterator cbegin() const noexcept { return begin(); }
117
+ constexpr const_iterator cend() const noexcept { return end(); }
118
  constexpr reverse_iterator rbegin() const noexcept;
119
  constexpr reverse_iterator rend() const noexcept;
120
+ constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
121
+ constexpr const_reverse_iterator crend() const noexcept { return rend(); }
122
 
123
  private:
124
  pointer data_; // exposition only
125
  size_type size_; // exposition only
126
  };
 
136
  template<class R>
137
  span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
138
  }
139
  ```
140
 
141
+ `span<ElementType, Extent>` is a trivially copyable type
142
+ [[term.trivially.copyable.type]].
143
+
144
  `ElementType` is required to be a complete object type that is not an
145
  abstract class type.
146
 
147
+ ##### Constructors, copy, and assignment <a id="span.cons">[[span.cons]]</a>
148
 
149
  ``` cpp
150
  constexpr span() noexcept;
151
  ```
152
 
 
171
  - \[`first`, `first + count`) is a valid range.
172
  - `It` models `contiguous_iterator`.
173
  - If `extent` is not equal to `dynamic_extent`, then `count` is equal to
174
  `extent`.
175
 
176
+ *Effects:* Initializes *`data_`* with `to_address(first)` and *`size_`*
177
+ with `count`.
178
 
179
  *Throws:* Nothing.
180
 
181
  ``` cpp
182
  template<class It, class End>
 
198
  equal to `extent`.
199
  - \[`first`, `last`) is a valid range.
200
  - `It` models `contiguous_iterator`.
201
  - `End` models `sized_sentinel_for<It>`.
202
 
203
+ *Effects:* Initializes *`data_`* with `to_address(first)` and *`size_`*
204
+ with `last - first`.
205
 
206
  *Throws:* When and what `last - first` throws.
207
 
208
  ``` cpp
209
  template<size_t N> constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
 
248
  is equal to `extent`.
249
  - `R` models `ranges::contiguous_range` and `ranges::sized_range`.
250
  - If `is_const_v<element_type>` is `false`, `R` models
251
  `ranges::borrowed_range`.
252
 
253
+ *Effects:* Initializes *`data_`* with `ranges::data(r)` and *`size_`*
254
+ with `ranges::size(r)`.
255
 
256
  *Throws:* What and when `ranges::data(r)` and `ranges::size(r)` throw.
257
 
258
  ``` cpp
259
  constexpr span(const span& other) noexcept = default;
 
293
  constexpr span& operator=(const span& other) noexcept = default;
294
  ```
295
 
296
  *Ensures:* `size() == other.size() && data() == other.data()`.
297
 
298
+ ##### Deduction guides <a id="span.deduct">[[span.deduct]]</a>
299
 
300
  ``` cpp
301
  template<class It, class EndOrSize>
302
  span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>>;
303
  ```
 
309
  span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
310
  ```
311
 
312
  *Constraints:* `R` satisfies `ranges::contiguous_range`.
313
 
314
+ ##### Subviews <a id="span.sub">[[span.sub]]</a>
315
 
316
  ``` cpp
317
  template<size_t Count> constexpr span<element_type, Count> first() const;
318
  ```
319
 
 
404
 
405
  ``` cpp
406
  return {data() + offset, count == dynamic_extent ? size() - offset : count};
407
  ```
408
 
409
+ ##### Observers <a id="span.obs">[[span.obs]]</a>
410
 
411
  ``` cpp
412
  constexpr size_type size() const noexcept;
413
  ```
414
 
415
+ *Effects:* Equivalent to: `return `*`size_`*`;`
416
 
417
  ``` cpp
418
  constexpr size_type size_bytes() const noexcept;
419
  ```
420
 
 
424
  [[nodiscard]] constexpr bool empty() const noexcept;
425
  ```
426
 
427
  *Effects:* Equivalent to: `return size() == 0;`
428
 
429
+ ##### Element access <a id="span.elem">[[span.elem]]</a>
430
 
431
  ``` cpp
432
  constexpr reference operator[](size_type idx) const;
433
  ```
434
 
 
454
 
455
  ``` cpp
456
  constexpr pointer data() const noexcept;
457
  ```
458
 
459
+ *Effects:* Equivalent to: `return `*`data_`*`;`
460
 
461
+ ##### Iterator support <a id="span.iterators">[[span.iterators]]</a>
462
 
463
  ``` cpp
464
  using iterator = implementation-defined // type of span::iterator;
465
  ```
466
 
467
  The type models `contiguous_iterator` [[iterator.concept.contiguous]],
468
  meets the *Cpp17RandomAccessIterator*
469
  requirements [[random.access.iterators]], and meets the requirements for
470
+ constexpr iterators [[iterator.requirements.general]], whose value type
471
+ is `value_type` and whose reference type is `reference`.
472
+
473
+ All requirements on container iterators [[container.reqmts]] apply to
474
  `span::iterator` as well.
475
 
476
  ``` cpp
477
  constexpr iterator begin() const noexcept;
478
  ```
 
520
 
521
  *Effects:* Equivalent to:
522
  `return R{reinterpret_cast<byte*>(s.data()), s.size_bytes()};` where `R`
523
  is the return type.
524
 
525
+ ### Multidimensional access <a id="views.multidim">[[views.multidim]]</a>
526
+
527
+ #### Overview <a id="mdspan.overview">[[mdspan.overview]]</a>
528
+
529
+ A *multidimensional index space* is a Cartesian product of integer
530
+ intervals. Each interval can be represented by a half-open range
531
+ [Lᵢ, Uᵢ), where Lᵢ and Uᵢ are the lower and upper bounds of the iᵗʰ
532
+ dimension. The *rank* of a multidimensional index space is the number of
533
+ intervals it represents. The *size of a multidimensional index space* is
534
+ the product of Uᵢ - Lᵢ for each dimension i if its rank is greater than
535
+ 0, and 1 otherwise.
536
+
537
+ An integer r is a *rank index* of an index space S if r is in the range
538
+ [0, rank of $S$).
539
+
540
+ A pack of integers `idx` is a *multidimensional index* in a
541
+ multidimensional index space S (or representation thereof) if both of
542
+ the following are true:
543
+
544
+ - `sizeof...(idx)` is equal to the rank of S, and
545
+ - for every rank index i of S, the iᵗʰ value of `idx` is an integer in
546
+ the interval [Lᵢ, Uᵢ) of S.
547
+
548
+ #### Header `<mdspan>` synopsis <a id="mdspan.syn">[[mdspan.syn]]</a>
549
+
550
+ ``` cpp
551
+ namespace std {
552
+ // [mdspan.extents], class template extents
553
+ template<class IndexType, size_t... Extents>
554
+ class extents;
555
+
556
+ // [mdspan.extents.dextents], alias template dextents
557
+ template<class IndexType, size_t Rank>
558
+ using dextents = see below;
559
+
560
+ // [mdspan.layout], layout mapping
561
+ struct layout_left;
562
+ struct layout_right;
563
+ struct layout_stride;
564
+
565
+ // [mdspan.accessor.default], class template default_accessor
566
+ template<class ElementType>
567
+ class default_accessor;
568
+
569
+ // [mdspan.mdspan], class template mdspan
570
+ template<class ElementType, class Extents, class LayoutPolicy = layout_right,
571
+ class AccessorPolicy = default_accessor<ElementType>>
572
+ class mdspan;
573
+ }
574
+ ```
575
+
576
+ #### Class template `extents` <a id="mdspan.extents">[[mdspan.extents]]</a>
577
+
578
+ ##### Overview <a id="mdspan.extents.overview">[[mdspan.extents.overview]]</a>
579
+
580
+ The class template `extents` represents a multidimensional index space
581
+ of rank equal to `sizeof...(Extents)`. In subclause [[views]], `extents`
582
+ is used synonymously with multidimensional index space.
583
+
584
+ ``` cpp
585
+ namespace std {
586
+ template<class IndexType, size_t... Extents>
587
+ class extents {
588
+ public:
589
+ using index_type = IndexType;
590
+ using size_type = make_unsigned_t<index_type>;
591
+ using rank_type = size_t;
592
+
593
+ // [mdspan.extents.obs], observers of the multidimensional index space
594
+ static constexpr rank_type rank() noexcept { return sizeof...(Extents); }
595
+ static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }
596
+ static constexpr size_t static_extent(rank_type) noexcept;
597
+ constexpr index_type extent(rank_type) const noexcept;
598
+
599
+ // [mdspan.extents.cons], constructors
600
+ constexpr extents() noexcept = default;
601
+
602
+ template<class OtherIndexType, size_t... OtherExtents>
603
+ constexpr explicit(see below)
604
+ extents(const extents<OtherIndexType, OtherExtents...>&) noexcept;
605
+ template<class... OtherIndexTypes>
606
+ constexpr explicit extents(OtherIndexTypes...) noexcept;
607
+ template<class OtherIndexType, size_t N>
608
+ constexpr explicit(N != rank_dynamic())
609
+ extents(span<OtherIndexType, N>) noexcept;
610
+ template<class OtherIndexType, size_t N>
611
+ constexpr explicit(N != rank_dynamic())
612
+ extents(const array<OtherIndexType, N>&) noexcept;
613
+
614
+ // [mdspan.extents.cmp], comparison operators
615
+ template<class OtherIndexType, size_t... OtherExtents>
616
+ friend constexpr bool operator==(const extents&,
617
+ const extents<OtherIndexType, OtherExtents...>&) noexcept;
618
+
619
+ // [mdspan.extents.expo], exposition-only helpers
620
+ constexpr size_t fwd-prod-of-extents(rank_type) const noexcept; // exposition only
621
+ constexpr size_t rev-prod-of-extents(rank_type) const noexcept; // exposition only
622
+ template<class OtherIndexType>
623
+ static constexpr auto index-cast(OtherIndexType&&) noexcept; // exposition only
624
+
625
+ private:
626
+ static constexpr rank_type dynamic-index(rank_type) noexcept; // exposition only
627
+ static constexpr rank_type dynamic-index-inv(rank_type) noexcept; // exposition only
628
+ array<index_type, rank_dynamic()> dynamic-extents{}; // exposition only
629
+ };
630
+
631
+ template<class... Integrals>
632
+ explicit extents(Integrals...)
633
+ -> see below;
634
+ }
635
+ ```
636
+
637
+ *Mandates:*
638
+
639
+ - `IndexType` is a signed or unsigned integer type, and
640
+ - each element of `Extents` is either equal to `dynamic_extent`, or is
641
+ representable as a value of type `IndexType`.
642
+
643
+ Each specialization of `extents` models `regular` and is trivially
644
+ copyable.
645
+
646
+ Let Eᵣ be the rᵗʰ element of `Extents`. Eᵣ is a *dynamic extent* if it
647
+ is equal to `dynamic_extent`, otherwise Eᵣ is a *static extent*. Let Dᵣ
648
+ be the value of `dynamic-extents[dynamic-index(r)]` if Eᵣ is a dynamic
649
+ extent, otherwise Eᵣ.
650
+
651
+ The rᵗʰ interval of the multidimensional index space represented by an
652
+ `extents` object is [0, Dᵣ).
653
+
654
+ ##### Exposition-only helpers <a id="mdspan.extents.expo">[[mdspan.extents.expo]]</a>
655
+
656
+ ``` cpp
657
+ static constexpr rank_type dynamic-index(rank_type i) noexcept;
658
+ ```
659
+
660
+ *Preconditions:* `i <= rank()` is `true`.
661
+
662
+ *Returns:* The number of Eᵣ with r < `i` for which Eᵣ is a dynamic
663
+ extent.
664
+
665
+ ``` cpp
666
+ static constexpr rank_type dynamic-index-inv(rank_type i) noexcept;
667
+ ```
668
+
669
+ *Preconditions:* `i < rank_dynamic()` is `true`.
670
+
671
+ *Returns:* The minimum value of r such that
672
+ *`dynamic-index`*`(`r` + 1) == i + 1` is `true`.
673
+
674
+ ``` cpp
675
+ constexpr size_t fwd-prod-of-extents(rank_type i) const noexcept;
676
+ ```
677
+
678
+ *Preconditions:* `i <= rank()` is `true`.
679
+
680
+ *Returns:* If `i > 0` is `true`, the product of `extent(`k`)` for all k
681
+ in the range [0, `i`), otherwise `1`.
682
+
683
+ ``` cpp
684
+ constexpr size_t rev-prod-of-extents(rank_type i) const noexcept;
685
+ ```
686
+
687
+ *Preconditions:* `i < rank()` is `true`.
688
+
689
+ *Returns:* If `i + 1 < rank()` is `true`, the product of `extent(`k`)`
690
+ for all k in the range [`i + 1`, `rank()`), otherwise `1`.
691
+
692
+ ``` cpp
693
+ template<class OtherIndexType>
694
+ static constexpr auto index-cast(OtherIndexType&& i) noexcept;
695
+ ```
696
+
697
+ *Effects:*
698
+
699
+ - If `OtherIndexType` is an integral type other than `bool`, then
700
+ equivalent to `return i;`,
701
+ - otherwise, equivalent to `return static_cast<index_type>(i);`.
702
+
703
+ [*Note 1*: This function will always return an integral type other than
704
+ `bool`. Since this function’s call sites are constrained on
705
+ convertibility of `OtherIndexType` to `index_type`, integer-class types
706
+ can use the `static_cast` branch without loss of
707
+ precision. — *end note*]
708
+
709
+ ##### Constructors <a id="mdspan.extents.cons">[[mdspan.extents.cons]]</a>
710
+
711
+ ``` cpp
712
+ template<class OtherIndexType, size_t... OtherExtents>
713
+ constexpr explicit(see below)
714
+ extents(const extents<OtherIndexType, OtherExtents...>& other) noexcept;
715
+ ```
716
+
717
+ *Constraints:*
718
+
719
+ - `sizeof...(OtherExtents) == rank()` is `true`.
720
+ - `((OtherExtents == dynamic_extent || Extents == dynamic_extent || OtherExtents == Extents) && ...)`
721
+ is `true`.
722
+
723
+ *Preconditions:*
724
+
725
+ - `other.extent(`r`)` equals Eᵣ for each r for which Eᵣ is a static
726
+ extent, and
727
+ - either
728
+ - `sizeof...(OtherExtents)` is zero, or
729
+ - `other.extent(`r`)` is representable as a value of type `index_type`
730
+ for every rank index r of `other`.
731
+
732
+ *Ensures:* `*this == other` is `true`.
733
+
734
+ *Remarks:* The expression inside `explicit` is equivalent to:
735
+
736
+ ``` cpp
737
+ (((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) ||
738
+ (numeric_limits<index_type>::max() < numeric_limits<OtherIndexType>::max())
739
+ ```
740
+
741
+ ``` cpp
742
+ template<class... OtherIndexTypes>
743
+ constexpr explicit extents(OtherIndexTypes... exts) noexcept;
744
+ ```
745
+
746
+ Let `N` be `sizeof...(OtherIndexTypes)`, and let `exts_arr` be
747
+ `array<index_type, N>{static_cast<`
748
+ `index_type>(std::move(exts))...}`.
749
+
750
+ *Constraints:*
751
+
752
+ - `(is_convertible_v<OtherIndexTypes, index_type> && ...)` is `true`,
753
+ - `(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...)` is
754
+ `true`, and
755
+ - `N == rank_dynamic() || N == rank()` is `true`. \[*Note 1*: One can
756
+ construct `extents` from just dynamic extents, which are all the
757
+ values getting stored, or from all the extents with a
758
+ precondition. — *end note*]
759
+
760
+ *Preconditions:*
761
+
762
+ - If `N != rank_dynamic()` is `true`, `exts_arr[`r`]` equals Eᵣ for each
763
+ r for which Eᵣ is a static extent, and
764
+ - either
765
+ - `sizeof...(exts) == 0` is `true`, or
766
+ - each element of `exts` is nonnegative and is representable as a
767
+ value of type `index_type`.
768
+
769
+ *Ensures:* `*this == extents(exts_arr)` is `true`.
770
+
771
+ ``` cpp
772
+ template<class OtherIndexType, size_t N>
773
+ constexpr explicit(N != rank_dynamic())
774
+ extents(span<OtherIndexType, N> exts) noexcept;
775
+ template<class OtherIndexType, size_t N>
776
+ constexpr explicit(N != rank_dynamic())
777
+ extents(const array<OtherIndexType, N>& exts) noexcept;
778
+ ```
779
+
780
+ *Constraints:*
781
+
782
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`,
783
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
784
+ `true`, and
785
+ - `N == rank_dynamic() || N == rank()` is `true`.
786
+
787
+ *Preconditions:*
788
+
789
+ - If `N != rank_dynamic()` is `true`, `exts[`r`]` equals Eᵣ for each r
790
+ for which Eᵣ is a static extent, and
791
+ - either
792
+ - `N` is zero, or
793
+ - `exts[`r`]` is nonnegative and is representable as a value of type
794
+ `index_type` for every rank index r.
795
+
796
+ *Effects:*
797
+
798
+ - If `N` equals `dynamic_rank()`, for all d in the range
799
+ [0, `rank_dynamic()`), direct-non-list-initializes
800
+ *`dynamic-extents`*`[`d`]` with `as_const(exts[`d`])`.
801
+ - Otherwise, for all d in the range [0, `rank_dynamic()`),
802
+ direct-non-list-initializes *`dynamic-extents`*`[`d`]` with
803
+ `as_const(exts[`*`dynamic-index-inv`*`(`d`)])`.
804
+
805
+ ``` cpp
806
+ template<class... Integrals>
807
+ explicit extents(Integrals...) -> see below;
808
+ ```
809
+
810
+ *Constraints:* `(is_convertible_v<Integrals, size_t> && ...)` is `true`.
811
+
812
+ *Remarks:* The deduced type is `dextents<size_t, sizeof...(Integrals)>`.
813
+
814
+ ##### Observers of the multidimensional index space <a id="mdspan.extents.obs">[[mdspan.extents.obs]]</a>
815
+
816
+ ``` cpp
817
+ static constexpr size_t static_extent(rank_type i) noexcept;
818
+ ```
819
+
820
+ *Preconditions:* `i < rank()` is `true`.
821
+
822
+ *Returns:* E_`i`.
823
+
824
+ ``` cpp
825
+ constexpr index_type extent(rank_type i) const noexcept;
826
+ ```
827
+
828
+ *Preconditions:* `i < rank()` is `true`.
829
+
830
+ *Returns:* D_`i`.
831
+
832
+ ##### Comparison operators <a id="mdspan.extents.cmp">[[mdspan.extents.cmp]]</a>
833
+
834
+ ``` cpp
835
+ template<class OtherIndexType, size_t... OtherExtents>
836
+ friend constexpr bool operator==(const extents& lhs,
837
+ const extents<OtherIndexType, OtherExtents...>& rhs) noexcept;
838
+ ```
839
+
840
+ *Returns:* `true` if `lhs.rank()` equals `rhs.rank()` and if
841
+ `lhs.extent(r)` equals `rhs.extent(r)` for every rank index `r` of
842
+ `rhs`, otherwise `false`.
843
+
844
+ ##### Alias template `dextents` <a id="mdspan.extents.dextents">[[mdspan.extents.dextents]]</a>
845
+
846
+ ``` cpp
847
+ template<class IndexType, size_t Rank>
848
+ using dextents = see below;
849
+ ```
850
+
851
+ *Result:* A type `E` that is a specialization of `extents` such that
852
+ `E::rank() == Rank && E::rank() == E::rank_dynamic()` is `true`, and
853
+ `E::index_type` denotes `IndexType`.
854
+
855
+ #### Layout mapping <a id="mdspan.layout">[[mdspan.layout]]</a>
856
+
857
+ ##### General <a id="mdspan.layout.general">[[mdspan.layout.general]]</a>
858
+
859
+ In subclauses [[mdspan.layout.reqmts]] and
860
+ [[mdspan.layout.policy.reqmts]]:
861
+
862
+ - `M` denotes a layout mapping class.
863
+ - `m` denotes a (possibly const) value of type `M`.
864
+ - `i` and `j` are packs of (possibly const) integers that are
865
+ multidimensional indices in `m.extents()` [[mdspan.overview]].
866
+ \[*Note 1*: The type of each element of the packs can be a different
867
+ integer type. — *end note*]
868
+ - `r` is a (possibly const) rank index of `typename M::extents_type`.
869
+ - `dᵣ` is a pack of (possibly const) integers for which
870
+ `sizeof...(dᵣ) == M::extents_type::rank()` is `true`, the rᵗʰ element
871
+ is equal to 1, and all other elements are equal to 0.
872
+
873
+ In subclauses [[mdspan.layout.reqmts]] through [[mdspan.layout.stride]],
874
+ let *`is-mapping-of`* be the exposition-only variable template defined
875
+ as follows:
876
+
877
+ ``` cpp
878
+ template<class Layout, class Mapping>
879
+ constexpr bool is-mapping-of = // exposition only
880
+ is_same_v<typename Layout::template mapping<typename Mapping::extents_type>, Mapping>;
881
+ ```
882
+
883
+ ##### Requirements <a id="mdspan.layout.reqmts">[[mdspan.layout.reqmts]]</a>
884
+
885
+ A type `M` meets the *layout mapping* requirements if
886
+
887
+ - `M` models `copyable` and `equality_comparable`,
888
+ - `is_nothrow_move_constructible_v<M>` is `true`,
889
+ - `is_nothrow_move_assignable_v<M>` is `true`,
890
+ - `is_nothrow_swappable_v<M>` is `true`, and
891
+ - the following types and expressions are well-formed and have the
892
+ specified semantics.
893
+
894
+ ``` cpp
895
+ typename M::extents_type
896
+ ```
897
+
898
+ *Result:* A type that is a specialization of `extents`.
899
+
900
+ ``` cpp
901
+ typename M::index_type
902
+ ```
903
+
904
+ *Result:* `typename M::extents_type::index_type`.
905
+
906
+ ``` cpp
907
+ typename M::rank_type
908
+ ```
909
+
910
+ *Result:* `typename M::extents_type::rank_type`.
911
+
912
+ ``` cpp
913
+ typename M::layout_type
914
+ ```
915
+
916
+ *Result:* A type `MP` that meets the layout mapping policy
917
+ requirements [[mdspan.layout.policy.reqmts]] and for which
918
+ *`is-mapping-of`*`<MP, M>` is `true`.
919
+
920
+ ``` cpp
921
+ m.extents()
922
+ ```
923
+
924
+ *Result:* `const typename M::extents_type&`
925
+
926
+ ``` cpp
927
+ m(i...)
928
+ ```
929
+
930
+ *Result:* `typename M::index_type`
931
+
932
+ *Returns:* A nonnegative integer less than
933
+ `numeric_limits<typename M::index_type>::max()` and less than or equal
934
+ to `numeric_limits<size_t>::max()`.
935
+
936
+ ``` cpp
937
+ m(i...) == m(static_cast<typename M::index_type>(i)...)
938
+ ```
939
+
940
+ *Result:* `bool`
941
+
942
+ *Returns:* `true`
943
+
944
+ ``` cpp
945
+ m.required_span_size()
946
+ ```
947
+
948
+ *Result:* `typename M::index_type`
949
+
950
+ *Returns:* If the size of the multidimensional index space `m.extents()`
951
+ is 0, then `0`, else `1` plus the maximum value of `m(i...)` for all
952
+ `i`.
953
+
954
+ ``` cpp
955
+ m.is_unique()
956
+ ```
957
+
958
+ *Result:* `bool`
959
+
960
+ *Returns:* `true` only if for every `i` and `j` where `(i != j || ...)`
961
+ is `true`, `m(i...) != m(j...)` is `true`.
962
+
963
+ [*Note 1*: A mapping can return `false` even if the condition is met.
964
+ For certain layouts, it is possibly not feasible to determine
965
+ efficiently whether the layout is unique. — *end note*]
966
+
967
+ ``` cpp
968
+ m.is_exhaustive()
969
+ ```
970
+
971
+ *Result:* `bool`
972
+
973
+ *Returns:* `true` only if for all k in the range
974
+ [0, `m.required_span_size()`) there exists an `i` such that `m(i...)`
975
+ equals k.
976
+
977
+ [*Note 2*: A mapping can return `false` even if the condition is met.
978
+ For certain layouts, it is possibly not feasible to determine
979
+ efficiently whether the layout is exhaustive. — *end note*]
980
+
981
+ ``` cpp
982
+ m.is_strided()
983
+ ```
984
+
985
+ *Result:* `bool`
986
+
987
+ *Returns:* `true` only if for every rank index r of `m.extents()` there
988
+ exists an integer sᵣ such that, for all `i` where (`i`+dᵣ) is a
989
+ multidimensional index in `m.extents()` [[mdspan.overview]],
990
+ `m((i + `dᵣ`)...) - m(i...)` equals sᵣ.
991
+
992
+ [*Note 3*: This implies that for a strided layout
993
+ m(i₀, …, iₖ) = m(0, …, 0) + i₀ × s₀ + … + iₖ × sₖ. — *end note*]
994
+
995
+ [*Note 4*: A mapping can return `false` even if the condition is met.
996
+ For certain layouts, it is possibly not feasible to determine
997
+ efficiently whether the layout is strided. — *end note*]
998
+
999
+ ``` cpp
1000
+ m.stride(r)
1001
+ ```
1002
+
1003
+ *Preconditions:* `m.is_strided()` is `true`.
1004
+
1005
+ *Result:* `typename M::index_type`
1006
+
1007
+ *Returns:* sᵣ as defined in `m.is_strided()` above.
1008
+
1009
+ ``` cpp
1010
+ M::is_always_unique()
1011
+ ```
1012
+
1013
+ *Result:* A constant expression [[expr.const]] of type `bool`.
1014
+
1015
+ *Returns:* `true` only if `m.is_unique()` is `true` for all possible
1016
+ objects `m` of type `M`.
1017
+
1018
+ [*Note 5*: A mapping can return `false` even if the above condition is
1019
+ met. For certain layout mappings, it is possibly not feasible to
1020
+ determine whether every instance is unique. — *end note*]
1021
+
1022
+ ``` cpp
1023
+ M::is_always_exhaustive()
1024
+ ```
1025
+
1026
+ *Result:* A constant expression [[expr.const]] of type `bool`.
1027
+
1028
+ *Returns:* `true` only if `m.is_exhaustive()` is `true` for all possible
1029
+ objects `m` of type `M`.
1030
+
1031
+ [*Note 6*: A mapping can return `false` even if the above condition is
1032
+ met. For certain layout mappings, it is possibly not feasible to
1033
+ determine whether every instance is exhaustive. — *end note*]
1034
+
1035
+ ``` cpp
1036
+ M::is_always_strided()
1037
+ ```
1038
+
1039
+ *Result:* A constant expression [[expr.const]] of type `bool`.
1040
+
1041
+ *Returns:* `true` only if `m.is_strided()` is `true` for all possible
1042
+ objects `m` of type `M`.
1043
+
1044
+ [*Note 7*: A mapping can return `false` even if the above condition is
1045
+ met. For certain layout mappings, it is possibly not feasible to
1046
+ determine whether every instance is strided. — *end note*]
1047
+
1048
+ ##### Layout mapping policy requirements <a id="mdspan.layout.policy.reqmts">[[mdspan.layout.policy.reqmts]]</a>
1049
+
1050
+ A type `MP` meets the *layout mapping policy* requirements if for a type
1051
+ `E` that is a specialization of `extents`, `MP::mapping<E>` is valid and
1052
+ denotes a type `X` that meets the layout mapping requirements
1053
+ [[mdspan.layout.reqmts]], and for which the *qualified-id*
1054
+ `X::layout_type` is valid and denotes the type `MP` and the
1055
+ *qualified-id* `X::extents_type` denotes `E`.
1056
+
1057
+ ##### Layout mapping policies <a id="mdspan.layout.policy.overview">[[mdspan.layout.policy.overview]]</a>
1058
+
1059
+ ``` cpp
1060
+ namespace std {
1061
+ struct layout_left {
1062
+ template<class Extents>
1063
+ class mapping;
1064
+ };
1065
+ struct layout_right {
1066
+ template<class Extents>
1067
+ class mapping;
1068
+ };
1069
+ struct layout_stride {
1070
+ template<class Extents>
1071
+ class mapping;
1072
+ };
1073
+ }
1074
+ ```
1075
+
1076
+ Each of `layout_left`, `layout_right`, and `layout_stride` meets the
1077
+ layout mapping policy requirements and is a trivial type.
1078
+
1079
+ ##### Class template `layout_left::mapping` <a id="mdspan.layout.left">[[mdspan.layout.left]]</a>
1080
+
1081
+ ###### Overview <a id="mdspan.layout.left.overview">[[mdspan.layout.left.overview]]</a>
1082
+
1083
+ `layout_left` provides a layout mapping where the leftmost extent has
1084
+ stride 1, and strides increase left-to-right as the product of extents.
1085
+
1086
+ ``` cpp
1087
+ namespace std {
1088
+ template<class Extents>
1089
+ class layout_left::mapping {
1090
+ public:
1091
+ using extents_type = Extents;
1092
+ using index_type = typename extents_type::index_type;
1093
+ using size_type = typename extents_type::size_type;
1094
+ using rank_type = typename extents_type::rank_type;
1095
+ using layout_type = layout_left;
1096
+
1097
+ // [mdspan.layout.left.cons], constructors
1098
+ constexpr mapping() noexcept = default;
1099
+ constexpr mapping(const mapping&) noexcept = default;
1100
+ constexpr mapping(const extents_type&) noexcept;
1101
+ template<class OtherExtents>
1102
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
1103
+ mapping(const mapping<OtherExtents>&) noexcept;
1104
+ template<class OtherExtents>
1105
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
1106
+ mapping(const layout_right::mapping<OtherExtents>&) noexcept;
1107
+ template<class OtherExtents>
1108
+ constexpr explicit(extents_type::rank() > 0)
1109
+ mapping(const layout_stride::mapping<OtherExtents>&);
1110
+
1111
+ constexpr mapping& operator=(const mapping&) noexcept = default;
1112
+
1113
+ // [mdspan.layout.left.obs], observers
1114
+ constexpr const extents_type& extents() const noexcept { return extents_; }
1115
+
1116
+ constexpr index_type required_span_size() const noexcept;
1117
+
1118
+ template<class... Indices>
1119
+ constexpr index_type operator()(Indices...) const noexcept;
1120
+
1121
+ static constexpr bool is_always_unique() noexcept { return true; }
1122
+ static constexpr bool is_always_exhaustive() noexcept { return true; }
1123
+ static constexpr bool is_always_strided() noexcept { return true; }
1124
+
1125
+ static constexpr bool is_unique() noexcept { return true; }
1126
+ static constexpr bool is_exhaustive() noexcept { return true; }
1127
+ static constexpr bool is_strided() noexcept { return true; }
1128
+
1129
+ constexpr index_type stride(rank_type) const noexcept;
1130
+
1131
+ template<class OtherExtents>
1132
+ friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
1133
+
1134
+ private:
1135
+ extents_type extents_{}; // exposition only
1136
+ };
1137
+ }
1138
+ ```
1139
+
1140
+ If `Extents` is not a specialization of `extents`, then the program is
1141
+ ill-formed.
1142
+
1143
+ `layout_left::mapping<E>` is a trivially copyable type that models
1144
+ `regular` for each `E`.
1145
+
1146
+ *Mandates:* If `Extents::rank_dynamic() == 0` is `true`, then the size
1147
+ of the multidimensional index space `Extents()` is representable as a
1148
+ value of type `typename Extents::index_type`.
1149
+
1150
+ ###### Constructors <a id="mdspan.layout.left.cons">[[mdspan.layout.left.cons]]</a>
1151
+
1152
+ ``` cpp
1153
+ constexpr mapping(const extents_type& e) noexcept;
1154
+ ```
1155
+
1156
+ *Preconditions:* The size of the multidimensional index space `e` is
1157
+ representable as a value of type `index_type` [[basic.fundamental]].
1158
+
1159
+ *Effects:* Direct-non-list-initializes *extents\_* with `e`.
1160
+
1161
+ ``` cpp
1162
+ template<class OtherExtents>
1163
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
1164
+ mapping(const mapping<OtherExtents>& other) noexcept;
1165
+ ```
1166
+
1167
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
1168
+ `true`.
1169
+
1170
+ *Preconditions:* `other.required_span_size()` is representable as a
1171
+ value of type `index_type` [[basic.fundamental]].
1172
+
1173
+ *Effects:* Direct-non-list-initializes *extents\_* with
1174
+ `other.extents()`.
1175
+
1176
+ ``` cpp
1177
+ template<class OtherExents>
1178
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
1179
+ mapping(const layout_right::mapping<OtherExtents>& other) noexcept;
1180
+ ```
1181
+
1182
+ *Constraints:*
1183
+
1184
+ - `extents_type::rank() <= 1` is `true`, and
1185
+ - `is_constructible_v<extents_type, OtherExtents>` is `true`.
1186
+
1187
+ *Preconditions:* `other.required_span_size()` is representable as a
1188
+ value of type `index_type` [[basic.fundamental]].
1189
+
1190
+ *Effects:* Direct-non-list-initializes *extents\_* with
1191
+ `other.extents()`.
1192
+
1193
+ ``` cpp
1194
+ template<class OtherExtents>
1195
+ constexpr explicit(extents_type::rank() > 0)
1196
+ mapping(const layout_stride::mapping<OtherExtents>& other);
1197
+ ```
1198
+
1199
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
1200
+ `true`.
1201
+
1202
+ *Preconditions:*
1203
+
1204
+ - If `extents_type::rank() > 0` is `true`, then for all r in the range
1205
+ [0, `extents_type::rank()`), `other.stride(`r`)` equals
1206
+ `other.extents().`*`fwd-prod-of-extents`*`(`r`)`, and
1207
+ - `other.required_span_size()` is representable as a value of type
1208
+ `index_type` [[basic.fundamental]].
1209
+
1210
+ *Effects:* Direct-non-list-initializes *extents\_* with
1211
+ `other.extents()`.
1212
+
1213
+ ###### Observers <a id="mdspan.layout.left.obs">[[mdspan.layout.left.obs]]</a>
1214
+
1215
+ ``` cpp
1216
+ constexpr index_type required_span_size() const noexcept;
1217
+ ```
1218
+
1219
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(extents_type::rank())`.
1220
+
1221
+ ``` cpp
1222
+ template<class... Indices>
1223
+ constexpr index_type operator()(Indices... i) const noexcept;
1224
+ ```
1225
+
1226
+ *Constraints:*
1227
+
1228
+ - `sizeof...(Indices) == extents_type::rank()` is `true`,
1229
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`, and
1230
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
1231
+
1232
+ *Preconditions:* `extents_type::`*`index-cast`*`(i)` is a
1233
+ multidimensional index in *extents\_*[[mdspan.overview]].
1234
+
1235
+ *Effects:* Let `P` be a parameter pack such that
1236
+
1237
+ ``` cpp
1238
+ is_same_v<index_sequence_for<Indices...>, index_sequence<P...>>
1239
+ ```
1240
+
1241
+ is `true`. Equivalent to:
1242
+
1243
+ ``` cpp
1244
+ return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
1245
+ ```
1246
+
1247
+ ``` cpp
1248
+ constexpr index_type stride(rank_type i) const;
1249
+ ```
1250
+
1251
+ *Constraints:* `extents_type::rank() > 0` is `true`.
1252
+
1253
+ *Preconditions:* `i < extents_type::rank()` is `true`.
1254
+
1255
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(i)`.
1256
+
1257
+ ``` cpp
1258
+ template<class OtherExtents>
1259
+ friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
1260
+ ```
1261
+
1262
+ *Constraints:* `extents_type::rank() == OtherExtents::rank()` is `true`.
1263
+
1264
+ *Effects:* Equivalent to: `return x.extents() == y.extents();`
1265
+
1266
+ ##### Class template `layout_right::mapping` <a id="mdspan.layout.right">[[mdspan.layout.right]]</a>
1267
+
1268
+ ###### Overview <a id="mdspan.layout.right.overview">[[mdspan.layout.right.overview]]</a>
1269
+
1270
+ `layout_right` provides a layout mapping where the rightmost extent is
1271
+ stride 1, and strides increase right-to-left as the product of extents.
1272
+
1273
+ ``` cpp
1274
+ namespace std {
1275
+ template<class Extents>
1276
+ class layout_right::mapping {
1277
+ public:
1278
+ using extents_type = Extents;
1279
+ using index_type = typename extents_type::index_type;
1280
+ using size_type = typename extents_type::size_type;
1281
+ using rank_type = typename extents_type::rank_type;
1282
+ using layout_type = layout_right;
1283
+
1284
+ // [mdspan.layout.right.cons], constructors
1285
+ constexpr mapping() noexcept = default;
1286
+ constexpr mapping(const mapping&) noexcept = default;
1287
+ constexpr mapping(const extents_type&) noexcept;
1288
+ template<class OtherExtents>
1289
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
1290
+ mapping(const mapping<OtherExtents>&) noexcept;
1291
+ template<class OtherExtents>
1292
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
1293
+ mapping(const layout_left::mapping<OtherExtents>&) noexcept;
1294
+ template<class OtherExtents>
1295
+ constexpr explicit(extents_type::rank() > 0)
1296
+ mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
1297
+
1298
+ constexpr mapping& operator=(const mapping&) noexcept = default;
1299
+
1300
+ // [mdspan.layout.right.obs], observers
1301
+ constexpr const extents_type& extents() const noexcept { return extents_; }
1302
+
1303
+ constexpr index_type required_span_size() const noexcept;
1304
+
1305
+ template<class... Indices>
1306
+ constexpr index_type operator()(Indices...) const noexcept;
1307
+
1308
+ static constexpr bool is_always_unique() noexcept { return true; }
1309
+ static constexpr bool is_always_exhaustive() noexcept { return true; }
1310
+ static constexpr bool is_always_strided() noexcept { return true; }
1311
+
1312
+ static constexpr bool is_unique() noexcept { return true; }
1313
+ static constexpr bool is_exhaustive() noexcept { return true; }
1314
+ static constexpr bool is_strided() noexcept { return true; }
1315
+
1316
+ constexpr index_type stride(rank_type) const noexcept;
1317
+
1318
+ template<class OtherExtents>
1319
+ friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
1320
+
1321
+ private:
1322
+ extents_type extents_{}; // exposition only
1323
+ };
1324
+ }
1325
+ ```
1326
+
1327
+ If `Extents` is not a specialization of `extents`, then the program is
1328
+ ill-formed.
1329
+
1330
+ `layout_right::mapping<E>` is a trivially copyable type that models
1331
+ `regular` for each `E`.
1332
+
1333
+ *Mandates:* If `Extents::rank_dynamic() == 0` is `true`, then the size
1334
+ of the multidimensional index space `Extents()` is representable as a
1335
+ value of type `typename Extents::index_type`.
1336
+
1337
+ ###### Constructors <a id="mdspan.layout.right.cons">[[mdspan.layout.right.cons]]</a>
1338
+
1339
+ ``` cpp
1340
+ constexpr mapping(const extents_type& e) noexcept;
1341
+ ```
1342
+
1343
+ *Preconditions:* The size of the multidimensional index space `e` is
1344
+ representable as a value of type `index_type` [[basic.fundamental]].
1345
+
1346
+ *Effects:* Direct-non-list-initializes *extents\_* with `e`.
1347
+
1348
+ ``` cpp
1349
+ template<class OtherExtents>
1350
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
1351
+ mapping(const mapping<OtherExtents>& other) noexcept;
1352
+ ```
1353
+
1354
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
1355
+ `true`.
1356
+
1357
+ *Preconditions:* `other.required_span_size()` is representable as a
1358
+ value of type `index_type` [[basic.fundamental]].
1359
+
1360
+ *Effects:* Direct-non-list-initializes *extents\_* with
1361
+ `other.extents()`.
1362
+
1363
+ ``` cpp
1364
+ template<class OtherExtents>
1365
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
1366
+ mapping(const layout_left::mapping<OtherExtents>& other) noexcept;
1367
+ ```
1368
+
1369
+ *Constraints:*
1370
+
1371
+ - `extents_type::rank() <= 1` is `true`, and
1372
+ - `is_constructible_v<extents_type, OtherExtents>` is `true`.
1373
+
1374
+ *Preconditions:* `other.required_span_size()` is representable as a
1375
+ value of type `index_type` [[basic.fundamental]].
1376
+
1377
+ *Effects:* Direct-non-list-initializes *extents\_* with
1378
+ `other.extents()`.
1379
+
1380
+ ``` cpp
1381
+ template<class OtherExtents>
1382
+ constexpr explicit(extents_type::rank() > 0)
1383
+ mapping(const layout_stride::mapping<OtherExtents>& other) noexcept;
1384
+ ```
1385
+
1386
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
1387
+ `true`.
1388
+
1389
+ *Preconditions:*
1390
+
1391
+ - If `extents_type::rank() > 0` is `true`, then for all r in the range
1392
+ [0, `extents_type::rank()`), `other.stride(`r`)` equals
1393
+ `other.extents().`*`rev-prod-of-extents`*`(`r`)`.
1394
+ - `other.required_span_size()` is representable as a value of type
1395
+ `index_type` [[basic.fundamental]].
1396
+
1397
+ *Effects:* Direct-non-list-initializes *extents\_* with
1398
+ `other.extents()`.
1399
+
1400
+ ###### Observers <a id="mdspan.layout.right.obs">[[mdspan.layout.right.obs]]</a>
1401
+
1402
+ ``` cpp
1403
+ index_type required_span_size() const noexcept;
1404
+ ```
1405
+
1406
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(extents_type::rank())`.
1407
+
1408
+ ``` cpp
1409
+ template<class... Indices>
1410
+ constexpr index_type operator()(Indices... i) const noexcept;
1411
+ ```
1412
+
1413
+ *Constraints:*
1414
+
1415
+ - `sizeof...(Indices) == extents_type::rank()` is `true`,
1416
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`, and
1417
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
1418
+
1419
+ *Preconditions:* `extents_type::`*`index-cast`*`(i)` is a
1420
+ multidimensional index in *extents\_*[[mdspan.overview]].
1421
+
1422
+ *Effects:* Let `P` be a parameter pack such that
1423
+
1424
+ ``` cpp
1425
+ is_same_v<index_sequence_for<Indices...>, index_sequence<P...>>
1426
+ ```
1427
+
1428
+ is `true`. Equivalent to:
1429
+
1430
+ ``` cpp
1431
+ return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
1432
+ ```
1433
+
1434
+ ``` cpp
1435
+ constexpr index_type stride(rank_type i) const noexcept;
1436
+ ```
1437
+
1438
+ *Constraints:* `extents_type::rank() > 0` is `true`.
1439
+
1440
+ *Preconditions:* `i < extents_type::rank()` is `true`.
1441
+
1442
+ *Returns:* `extents().`*`rev-prod-of-extents`*`(i)`.
1443
+
1444
+ ``` cpp
1445
+ template<class OtherExtents>
1446
+ friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
1447
+ ```
1448
+
1449
+ *Constraints:* `extents_type::rank() == OtherExtents::rank()` is `true`.
1450
+
1451
+ *Effects:* Equivalent to: `return x.extents() == y.extents();`
1452
+
1453
+ ##### Class template `layout_stride::mapping` <a id="mdspan.layout.stride">[[mdspan.layout.stride]]</a>
1454
+
1455
+ ###### Overview <a id="mdspan.layout.stride.overview">[[mdspan.layout.stride.overview]]</a>
1456
+
1457
+ `layout_stride` provides a layout mapping where the strides are
1458
+ user-defined.
1459
+
1460
+ ``` cpp
1461
+ namespace std {
1462
+ template<class Extents>
1463
+ class layout_stride::mapping {
1464
+ public:
1465
+ using extents_type = Extents;
1466
+ using index_type = typename extents_type::index_type;
1467
+ using size_type = typename extents_type::size_type;
1468
+ using rank_type = typename extents_type::rank_type;
1469
+ using layout_type = layout_stride;
1470
+
1471
+ private:
1472
+ static constexpr rank_type rank_ = extents_type::rank(); // exposition only
1473
+
1474
+ public:
1475
+ // [mdspan.layout.stride.cons], constructors
1476
+ constexpr mapping() noexcept;
1477
+ constexpr mapping(const mapping&) noexcept = default;
1478
+ template<class OtherIndexType>
1479
+ constexpr mapping(const extents_type&, span<OtherIndexType, rank_>) noexcept;
1480
+ template<class OtherIndexType>
1481
+ constexpr mapping(const extents_type&, const array<OtherIndexType, rank_>&) noexcept;
1482
+
1483
+ template<class StridedLayoutMapping>
1484
+ constexpr explicit(see below) mapping(const StridedLayoutMapping&) noexcept;
1485
+
1486
+ constexpr mapping& operator=(const mapping&) noexcept = default;
1487
+
1488
+ // [mdspan.layout.stride.obs], observers
1489
+ constexpr const extents_type& extents() const noexcept { return extents_; }
1490
+ constexpr array<index_type, rank_> strides() const noexcept { return strides_; }
1491
+
1492
+ constexpr index_type required_span_size() const noexcept;
1493
+
1494
+ template<class... Indices>
1495
+ constexpr index_type operator()(Indices...) const noexcept;
1496
+
1497
+ static constexpr bool is_always_unique() noexcept { return true; }
1498
+ static constexpr bool is_always_exhaustive() noexcept { return false; }
1499
+ static constexpr bool is_always_strided() noexcept { return true; }
1500
+
1501
+ static constexpr bool is_unique() noexcept { return true; }
1502
+ constexpr bool is_exhaustive() const noexcept;
1503
+ static constexpr bool is_strided() noexcept { return true; }
1504
+
1505
+ constexpr index_type stride(rank_type i) const noexcept { return strides_[i]; }
1506
+
1507
+ template<class OtherMapping>
1508
+ friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept;
1509
+
1510
+ private:
1511
+ extents_type extents_{}; // exposition only
1512
+ array<index_type, rank_> strides_{}; // exposition only
1513
+ };
1514
+ }
1515
+ ```
1516
+
1517
+ If `Extents` is not a specialization of `extents`, then the program is
1518
+ ill-formed.
1519
+
1520
+ `layout_stride::mapping<E>` is a trivially copyable type that models
1521
+ `regular` for each `E`.
1522
+
1523
+ *Mandates:* If `Extents::rank_dynamic() == 0` is `true`, then the size
1524
+ of the multidimensional index space `Extents()` is representable as a
1525
+ value of type `typename Extents::index_type`.
1526
+
1527
+ ###### Exposition-only helpers <a id="mdspan.layout.stride.expo">[[mdspan.layout.stride.expo]]</a>
1528
+
1529
+ Let `REQUIRED-SPAN-SIZE(e, strides)` be:
1530
+
1531
+ - `1`, if `e.rank() == 0` is `true`,
1532
+ - otherwise `0`, if the size of the multidimensional index space `e` is
1533
+ 0,
1534
+ - otherwise `1` plus the sum of products of `(e.extent(r) - 1)` and
1535
+ `strides[r]` for all r in the range [0, `e.rank()`).
1536
+
1537
+ Let `OFFSET(m)` be:
1538
+
1539
+ - `m()`, if `e.rank() == 0` is `true`,
1540
+ - otherwise `0`, if the size of the multidimensional index space `e` is
1541
+ 0,
1542
+ - otherwise `m(z...)` for a pack of integers `z` that is a
1543
+ multidimensional index in `m.extents()` and each element of `z` equals
1544
+ 0.
1545
+
1546
+ Let *`is-extents`* be the exposition-only variable template defined as
1547
+ follows:
1548
+
1549
+ ``` cpp
1550
+ template<class T>
1551
+ constexpr bool is-extents = false; // exposition only
1552
+ template<class IndexType, size_t... Args>
1553
+ constexpr bool is-extents<extents<IndexType, Args...>> = true; // exposition only
1554
+ ```
1555
+
1556
+ Let `layout-mapping-alike` be the exposition-only concept defined as
1557
+ follows:
1558
+
1559
+ ``` cpp
1560
+ template<class M>
1561
+ concept layout-mapping-alike = requires { // exposition only
1562
+ requires is-extents<typename M::extents_type>;
1563
+ { M::is_always_strided() } -> same_as<bool>;
1564
+ { M::is_always_exhaustive() } -> same_as<bool>;
1565
+ { M::is_always_unique() } -> same_as<bool>;
1566
+ bool_constant<M::is_always_strided()>::value;
1567
+ bool_constant<M::is_always_exhaustive()>::value;
1568
+ bool_constant<M::is_always_unique()>::value;
1569
+ };
1570
+ ```
1571
+
1572
+ [*Note 2*: This concept checks that the functions
1573
+ `M::is_always_strided()`, `M::is_always_exhaustive()`, and
1574
+ `M::is_always_unique()` exist, are constant expressions, and have a
1575
+ return type of `bool`. — *end note*]
1576
+
1577
+ ###### Constructors <a id="mdspan.layout.stride.cons">[[mdspan.layout.stride.cons]]</a>
1578
+
1579
+ ``` cpp
1580
+ constexpr mapping() noexcept;
1581
+ ```
1582
+
1583
+ *Preconditions:*
1584
+ `layout_right::mapping<extents_type>().required_span_size()` is
1585
+ representable as a value of type `index_type` [[basic.fundamental]].
1586
+
1587
+ *Effects:* Direct-non-list-initializes *extents\_* with
1588
+ `extents_type()`, and for all d in the range \[`0`, *`rank_`*),
1589
+ direct-non-list-initializes *`strides_`*`[`d`]` with
1590
+ `layout_right::mapping<extents_type>().stride(`d`)`.
1591
+
1592
+ ``` cpp
1593
+ template<class OtherIndexType>
1594
+ constexpr mapping(const extents_type& e, span<OtherIndexType, rank_> s) noexcept;
1595
+ template<class OtherIndexType>
1596
+ constexpr mapping(const extents_type& e, const array<OtherIndexType, rank_>& s) noexcept;
1597
+ ```
1598
+
1599
+ *Constraints:*
1600
+
1601
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`, and
1602
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
1603
+ `true`.
1604
+
1605
+ *Preconditions:*
1606
+
1607
+ - `s[`i`] > 0` is `true` for all i in the range [0, rank_).
1608
+ - *`REQUIRED-SPAN-SIZE`*`(e, s)` is representable as a value of type
1609
+ `index_type` [[basic.fundamental]].
1610
+ - If *rank\_* is greater than 0, then there exists a permutation P of
1611
+ the integers in the range [0, rank_), such that
1612
+ `s[`pᵢ`] >= s[`pᵢ₋₁`] * e.extent(p`ᵢ₋₁`)` is `true` for all i in the
1613
+ range [1, rank_), where pᵢ is the iᵗʰ element of P. \[*Note 3*: For
1614
+ `layout_stride`, this condition is necessary and sufficient for
1615
+ `is_unique()` to be `true`. — *end note*]
1616
+
1617
+ *Effects:* Direct-non-list-initializes *extents\_* with `e`, and for all
1618
+ d in the range [0, rank_), direct-non-list-initializes `strides_[`d`]`
1619
+ with `as_const(s[`d`])`.
1620
+
1621
+ ``` cpp
1622
+ template<class StridedLayoutMapping>
1623
+ constexpr explicit(see below)
1624
+ mapping(const StridedLayoutMapping& other) noexcept;
1625
+ ```
1626
+
1627
+ *Constraints:*
1628
+
1629
+ - `layout-mapping-alike<StridedLayoutMapping>` is satisfied.
1630
+ - `is_constructible_v<extents_type, typename StridedLayoutMapping::extents_type>`
1631
+ is
1632
+ `true`.
1633
+ - `StridedLayoutMapping::is_always_unique()` is `true`.
1634
+ - `StridedLayoutMapping::is_always_strided()` is `true`.
1635
+
1636
+ *Preconditions:*
1637
+
1638
+ - `StridedLayoutMapping` meets the layout mapping
1639
+ requirements [[mdspan.layout.policy.reqmts]],
1640
+ - `other.stride(`r`) > 0` is `true` for every rank index r of
1641
+ `extents()`,
1642
+ - `other.required_span_size()` is representable as a value of type
1643
+ `index_type` [[basic.fundamental]], and
1644
+ - *`OFFSET`*`(other) == 0` is `true`.
1645
+
1646
+ *Effects:* Direct-non-list-initializes *extents\_* with
1647
+ `other.extents()`, and for all d in the range [0, rank_),
1648
+ direct-non-list-initializes *`strides_`*`[`d`]` with
1649
+ `other.stride(`d`)`.
1650
+
1651
+ Remarks: The expression inside `explicit` is equivalent to:
1652
+
1653
+ ``` cpp
1654
+ !(is_convertible_v<typename StridedLayoutMapping::extents_type, extents_type> &&
1655
+ (is-mapping-of<layout_left, LayoutStrideMapping> ||
1656
+ is-mapping-of<layout_right, LayoutStrideMapping> ||
1657
+ is-mapping-of<layout_stride, LayoutStrideMapping>))
1658
+ ```
1659
+
1660
+ ###### Observers <a id="mdspan.layout.stride.obs">[[mdspan.layout.stride.obs]]</a>
1661
+
1662
+ ``` cpp
1663
+ constexpr index_type required_span_size() const noexcept;
1664
+ ```
1665
+
1666
+ *Returns:* *`REQUIRED-SPAN-SIZE`*`(extents(), `*`strides_`*`)`.
1667
+
1668
+ ``` cpp
1669
+ template<class... Indices>
1670
+ constexpr index_type operator()(Indices... i) const noexcept;
1671
+ ```
1672
+
1673
+ *Constraints:*
1674
+
1675
+ - `sizeof...(Indices) == `*`rank_`* is `true`,
1676
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`, and
1677
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
1678
+
1679
+ *Preconditions:* `extents_type::`*`index-cast`*`(i)` is a
1680
+ multidimensional index in *extents\_*[[mdspan.overview]].
1681
+
1682
+ *Effects:* Let `P` be a parameter pack such that
1683
+
1684
+ ``` cpp
1685
+ is_same_v<index_sequence_for<Indices...>, index_sequence<P...>>
1686
+ ```
1687
+
1688
+ is `true`. Equivalent to:
1689
+
1690
+ ``` cpp
1691
+ return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
1692
+ ```
1693
+
1694
+ ``` cpp
1695
+ constexpr bool is_exhaustive() const noexcept;
1696
+ ```
1697
+
1698
+ *Returns:*
1699
+
1700
+ - `true` if *rank\_* is 0.
1701
+ - Otherwise, `true` if there is a permutation P of the integers in the
1702
+ range [0, rank_) such that `stride(`p₀`)` equals 1, and `stride(`pᵢ`)`
1703
+ equals `stride(`pᵢ₋₁`) * extents().extent(`pᵢ₋₁`)` for i in the range
1704
+ [1, rank_), where pᵢ is the iᵗʰ element of P.
1705
+ - Otherwise, `false`.
1706
+
1707
+ ``` cpp
1708
+ template<class OtherMapping>
1709
+ friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept;
1710
+ ```
1711
+
1712
+ *Constraints:*
1713
+
1714
+ - `layout-mapping-alike<OtherMapping>` is satisfied.
1715
+ - *`rank_`*` == OtherMapping::extents_type::rank()` is `true`.
1716
+ - `OtherMapping::is_always_strided()` is `true`.
1717
+
1718
+ *Preconditions:* `OtherMapping` meets the layout mapping
1719
+ requirements [[mdspan.layout.policy.reqmts]].
1720
+
1721
+ *Returns:* `true` if `x.extents() == y.extents()` is `true`,
1722
+ *`OFFSET`*`(y) == 0` is `true`, and each of
1723
+ `x.stride(`r`) == y.stride(`r`)` is `true` for r in the range
1724
+ [0, `x.extents().rank()`). Otherwise, `false`.
1725
+
1726
+ #### Accessor policy <a id="mdspan.accessor">[[mdspan.accessor]]</a>
1727
+
1728
+ ##### General <a id="mdspan.accessor.general">[[mdspan.accessor.general]]</a>
1729
+
1730
+ An *accessor policy* defines types and operations by which a reference
1731
+ to a single object is created from an abstract data handle to a number
1732
+ of such objects and an index.
1733
+
1734
+ A range of indices [0, N) is an *accessible range* of a given data
1735
+ handle and an accessor if, for each i in the range, the accessor
1736
+ policy’s `access` function produces a valid reference to an object.
1737
+
1738
+ In subclause [[mdspan.accessor.reqmts]],
1739
+
1740
+ - `A` denotes an accessor policy.
1741
+ - `a` denotes a value of type `A` or `const A`.
1742
+ - `p` denotes a value of type `A::data_handle_type` or
1743
+ `const A::data_handle_type`. \[*Note 1*: The type
1744
+ `A::data_handle_type` need not be dereferenceable. — *end note*]
1745
+ - `n`, `i`, and `j` each denote values of type `size_t`.
1746
+
1747
+ ##### Requirements <a id="mdspan.accessor.reqmts">[[mdspan.accessor.reqmts]]</a>
1748
+
1749
+ A type `A` meets the accessor policy requirements if
1750
+
1751
+ - `A` models `copyable`,
1752
+ - `is_nothrow_move_constructible_v<A>` is `true`,
1753
+ - `is_nothrow_move_assignable_v<A>` is `true`,
1754
+ - `is_nothrow_swappable_v<A>` is `true`, and
1755
+ - the following types and expressions are well-formed and have the
1756
+ specified semantics.
1757
+
1758
+ ``` cpp
1759
+ typename A::element_type
1760
+ ```
1761
+
1762
+ *Result:* A complete object type that is not an abstract class type.
1763
+
1764
+ ``` cpp
1765
+ typename A::data_handle_type
1766
+ ```
1767
+
1768
+ *Result:* A type that models `copyable`, and for which
1769
+ `is_nothrow_move_constructible_v<A::data_handle_type>` is `true`,
1770
+ `is_nothrow_move_assignable_v<A::data_handle_type>` is `true`, and
1771
+ `is_nothrow_swappable_v<A::data_handle_type>` is `true`.
1772
+
1773
+ [*Note 1*: The type of `data_handle_type` need not be
1774
+ `element_type*`. — *end note*]
1775
+
1776
+ ``` cpp
1777
+ typename A::reference
1778
+ ```
1779
+
1780
+ *Result:* A type that models
1781
+ `common_reference_with<A::reference&&, A::element_type&>`.
1782
+
1783
+ [*Note 2*: The type of `reference` need not be
1784
+ `element_type&`. — *end note*]
1785
+
1786
+ ``` cpp
1787
+ typename A::offset_policy
1788
+ ```
1789
+
1790
+ *Result:* A type `OP` such that:
1791
+
1792
+ - `OP` meets the accessor policy requirements,
1793
+ - `constructible_from<OP, const A&>` is modeled, and
1794
+ - `is_same_v<typename OP::element_type, typename A::element_type>` is
1795
+ `true`.
1796
+
1797
+ ``` cpp
1798
+ a.access(p, i)
1799
+ ```
1800
+
1801
+ *Result:* `A::reference`
1802
+
1803
+ *Remarks:* The expression is equality preserving.
1804
+
1805
+ [*Note 3*: Concrete accessor policies can impose preconditions for
1806
+ their `access` function. However, they might not. For example, an
1807
+ accessor where `p` is `span<A::element_type, dynamic_extent>` and
1808
+ `access(p, i)` returns `p[i % p.size()]` does not need to impose a
1809
+ precondition on `i`. — *end note*]
1810
+
1811
+ ``` cpp
1812
+ a.offset(p, i)
1813
+ ```
1814
+
1815
+ *Result:* `A::offset_policy::data_handle_type`
1816
+
1817
+ *Returns:* `q` such that for `b` being `A::offset_policy(a)`, and any
1818
+ integer `n` for which [0, `n`) is an accessible range of `p` and `a`:
1819
+
1820
+ - [0, `n` - `i`) is an accessible range of `q` and `b`; and
1821
+ - `b.access(q, j)` provides access to the same element as
1822
+ `a.access(p, i + j)`, for every `j` in the range [0, `n` - `i`).
1823
+
1824
+ *Remarks:* The expression is equality-preserving.
1825
+
1826
+ ##### Class template `default_accessor` <a id="mdspan.accessor.default">[[mdspan.accessor.default]]</a>
1827
+
1828
+ ###### Overview <a id="mdspan.accessor.default.overview">[[mdspan.accessor.default.overview]]</a>
1829
+
1830
+ ``` cpp
1831
+ namespace std {
1832
+ template<class ElementType>
1833
+ struct default_accessor {
1834
+ using offset_policy = default_accessor;
1835
+ using element_type = ElementType;
1836
+ using reference = ElementType&;
1837
+ using data_handle_type = ElementType*;
1838
+
1839
+ constexpr default_accessor() noexcept = default;
1840
+ template<class OtherElementType>
1841
+ constexpr default_accessor(default_accessor<OtherElementType>) noexcept;
1842
+ constexpr reference access(data_handle_type p, size_t i) const noexcept;
1843
+ constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
1844
+ };
1845
+ }
1846
+ ```
1847
+
1848
+ `default_accessor` meets the accessor policy requirements.
1849
+
1850
+ `ElementType` is required to be a complete object type that is neither
1851
+ an abstract class type nor an array type.
1852
+
1853
+ Each specialization of `default_accessor` is a trivially copyable type
1854
+ that models `semiregular`.
1855
+
1856
+ [0, n) is an accessible range for an object `p` of type
1857
+ `data_handle_type` and an object of type `default_accessor` if and only
1858
+ if \[`p`, `p + `n) is a valid range.
1859
+
1860
+ ###### Members <a id="mdspan.accessor.default.members">[[mdspan.accessor.default.members]]</a>
1861
+
1862
+ ``` cpp
1863
+ template<class OtherElementType>
1864
+ constexpr default_accessor(default_accessor<OtherElementType>) noexcept {}
1865
+ ```
1866
+
1867
+ *Constraints:*
1868
+ `is_convertible_v<OtherElementType(*)[], element_type(*)[]>` is `true`.
1869
+
1870
+ ``` cpp
1871
+ constexpr reference access(data_handle_type p, size_t i) const noexcept;
1872
+ ```
1873
+
1874
+ *Effects:* Equivalent to: `return p[i];`
1875
+
1876
+ ``` cpp
1877
+ constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
1878
+ ```
1879
+
1880
+ *Effects:* Equivalent to: `return p + i;`
1881
+
1882
+ #### Class template `mdspan` <a id="mdspan.mdspan">[[mdspan.mdspan]]</a>
1883
+
1884
+ ##### Overview <a id="mdspan.mdspan.overview">[[mdspan.mdspan.overview]]</a>
1885
+
1886
+ `mdspan` is a view of a multidimensional array of elements.
1887
+
1888
+ ``` cpp
1889
+ namespace std {
1890
+ template<class ElementType, class Extents, class LayoutPolicy = layout_right,
1891
+ class AccessorPolicy = default_accessor<ElementType>>
1892
+ class mdspan {
1893
+ public:
1894
+ using extents_type = Extents;
1895
+ using layout_type = LayoutPolicy;
1896
+ using accessor_type = AccessorPolicy;
1897
+ using mapping_type = typename layout_type::template mapping<extents_type>;
1898
+ using element_type = ElementType;
1899
+ using value_type = remove_cv_t<element_type>;
1900
+ using index_type = typename extents_type::index_type;
1901
+ using size_type = typename extents_type::size_type;
1902
+ using rank_type = typename extents_type::rank_type;
1903
+ using data_handle_type = typename accessor_type::data_handle_type;
1904
+ using reference = typename accessor_type::reference;
1905
+
1906
+ static constexpr rank_type rank() noexcept { return extents_type::rank(); }
1907
+ static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
1908
+ static constexpr size_t static_extent(rank_type r) noexcept
1909
+ { return extents_type::static_extent(r); }
1910
+ constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); }
1911
+
1912
+ // [mdspan.mdspan.cons], constructors
1913
+ constexpr mdspan();
1914
+ constexpr mdspan(const mdspan& rhs) = default;
1915
+ constexpr mdspan(mdspan&& rhs) = default;
1916
+
1917
+ template<class... OtherIndexTypes>
1918
+ constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts);
1919
+ template<class OtherIndexType, size_t N>
1920
+ constexpr explicit(N != rank_dynamic())
1921
+ mdspan(data_handle_type p, span<OtherIndexType, N> exts);
1922
+ template<class OtherIndexType, size_t N>
1923
+ constexpr explicit(N != rank_dynamic())
1924
+ mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
1925
+ constexpr mdspan(data_handle_type p, const extents_type& ext);
1926
+ constexpr mdspan(data_handle_type p, const mapping_type& m);
1927
+ constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
1928
+
1929
+ template<class OtherElementType, class OtherExtents,
1930
+ class OtherLayoutPolicy, class OtherAccessorPolicy>
1931
+ constexpr explicit(see below)
1932
+ mdspan(const mdspan<OtherElementType, OtherExtents,
1933
+ OtherLayoutPolicy, OtherAccessorPolicy>& other);
1934
+
1935
+ constexpr mdspan& operator=(const mdspan& rhs) = default;
1936
+ constexpr mdspan& operator=(mdspan&& rhs) = default;
1937
+
1938
+ // [mdspan.mdspan.members], members
1939
+ template<class... OtherIndexTypes>
1940
+ constexpr reference operator[](OtherIndexTypes... indices) const;
1941
+ template<class OtherIndexType>
1942
+ constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
1943
+ template<class OtherIndexType>
1944
+ constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
1945
+
1946
+ constexpr size_type size() const noexcept;
1947
+ [[nodiscard]] constexpr bool empty() const noexcept;
1948
+
1949
+ friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
1950
+
1951
+ constexpr const extents_type& extents() const noexcept { return map_.extents(); }
1952
+ constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
1953
+ constexpr const mapping_type& mapping() const noexcept { return map_; }
1954
+ constexpr const accessor_type& accessor() const noexcept { return acc_; }
1955
+
1956
+ static constexpr bool is_always_unique()
1957
+ { return mapping_type::is_always_unique(); }
1958
+ static constexpr bool is_always_exhaustive()
1959
+ { return mapping_type::is_always_exhaustive(); }
1960
+ static constexpr bool is_always_strided()
1961
+ { return mapping_type::is_always_strided(); }
1962
+
1963
+ constexpr bool is_unique() const
1964
+ { return map_.is_unique(); }
1965
+ constexpr bool is_exhaustive() const
1966
+ { return map_.is_exhaustive(); }
1967
+ constexpr bool is_strided() const
1968
+ { return map_.is_strided(); }
1969
+ constexpr index_type stride(rank_type r) const
1970
+ { return map_.stride(r); }
1971
+
1972
+ private:
1973
+ accessor_type acc_; // exposition only
1974
+ mapping_type map_; // exposition only
1975
+ data_handle_type ptr_; // exposition only
1976
+ };
1977
+
1978
+ template<class CArray>
1979
+ requires(is_array_v<CArray> && rank_v<CArray> == 1)
1980
+ mdspan(CArray&)
1981
+ -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>;
1982
+
1983
+ template<class Pointer>
1984
+ requires(is_pointer_v<remove_reference_t<Pointer>>)
1985
+ mdspan(Pointer&&)
1986
+ -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
1987
+
1988
+ template<class ElementType, class... Integrals>
1989
+ requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)
1990
+ explicit mdspan(ElementType*, Integrals...)
1991
+ -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>;
1992
+
1993
+ template<class ElementType, class OtherIndexType, size_t N>
1994
+ mdspan(ElementType*, span<OtherIndexType, N>)
1995
+ -> mdspan<ElementType, dextents<size_t, N>>;
1996
+
1997
+ template<class ElementType, class OtherIndexType, size_t N>
1998
+ mdspan(ElementType*, const array<OtherIndexType, N>&)
1999
+ -> mdspan<ElementType, dextents<size_t, N>>;
2000
+
2001
+ template<class ElementType, class IndexType, size_t... ExtentsPack>
2002
+ mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&)
2003
+ -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>;
2004
+
2005
+ template<class ElementType, class MappingType>
2006
+ mdspan(ElementType*, const MappingType&)
2007
+ -> mdspan<ElementType, typename MappingType::extents_type,
2008
+ typename MappingType::layout_type>;
2009
+
2010
+ template<class MappingType, class AccessorType>
2011
+ mdspan(const typename AccessorType::data_handle_type&, const MappingType&,
2012
+ const AccessorType&)
2013
+ -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type,
2014
+ typename MappingType::layout_type, AccessorType>;
2015
+ }
2016
+ ```
2017
+
2018
+ *Mandates:*
2019
+
2020
+ - `ElementType` is a complete object type that is neither an abstract
2021
+ class type nor an array type,
2022
+ - `Extents` is a specialization of `extents`, and
2023
+ - `is_same_v<ElementType, typename AccessorPolicy::element_type>` is
2024
+ `true`.
2025
+
2026
+ `LayoutPolicy` shall meet the layout mapping policy requirements
2027
+ [[mdspan.layout.policy.reqmts]], and `AccessorPolicy` shall meet the
2028
+ accessor policy requirements [[mdspan.accessor.reqmts]].
2029
+
2030
+ Each specialization `MDS` of `mdspan` models `copyable` and
2031
+
2032
+ - `is_nothrow_move_constructible_v<MDS>` is `true`,
2033
+ - `is_nothrow_move_assignable_v<MDS>` is `true`, and
2034
+ - `is_nothrow_swappable_v<MDS>` is `true`.
2035
+
2036
+ A specialization of `mdspan` is a trivially copyable type if its
2037
+ `accessor_type`, `mapping_type`, and `data_handle_type` are trivially
2038
+ copyable types.
2039
+
2040
+ ##### Constructors <a id="mdspan.mdspan.cons">[[mdspan.mdspan.cons]]</a>
2041
+
2042
+ ``` cpp
2043
+ constexpr mdspan();
2044
+ ```
2045
+
2046
+ *Constraints:*
2047
+
2048
+ - `rank_dynamic() > 0` is `true`.
2049
+ - `is_default_constructible_v<data_handle_type>` is `true`.
2050
+ - `is_default_constructible_v<mapping_type>` is `true`.
2051
+ - `is_default_constructible_v<accessor_type>` is `true`.
2052
+
2053
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
2054
+ an accessible range of *ptr\_* and *acc\_* for the values of *map\_* and
2055
+ *acc\_* after the invocation of this constructor.
2056
+
2057
+ *Effects:* Value-initializes *ptr\_*, *map\_*, and *acc\_*.
2058
+
2059
+ ``` cpp
2060
+ template<class... OtherIndexTypes>
2061
+ constexpr explicit mdspan(data_handle_type p, OtherIndexTypes... exts);
2062
+ ```
2063
+
2064
+ Let `N` be `sizeof...(OtherIndexTypes)`.
2065
+
2066
+ *Constraints:*
2067
+
2068
+ - `(is_convertible_v<OtherIndexTypes, index_type> && ...)` is `true`,
2069
+ - `(is_nothrow_constructible<index_type, OtherIndexTypes> && ...)` is
2070
+ `true`,
2071
+ - `N == rank() || N == rank_dynamic()` is `true`,
2072
+ - `is_constructible_v<mapping_type, extents_type>` is `true`, and
2073
+ - `is_default_constructible_v<accessor_type>` is `true`.
2074
+
2075
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
2076
+ an accessible range of `p` and *acc\_* for the values of *map\_* and
2077
+ *acc\_* after the invocation of this constructor.
2078
+
2079
+ *Effects:*
2080
+
2081
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
2082
+ - direct-non-list-initializes *map\_* with
2083
+ `extents_type(static_cast<index_type>(std::move(exts))...)`, and
2084
+ - value-initializes *acc\_*.
2085
+
2086
+ ``` cpp
2087
+ template<class OtherIndexType, size_t N>
2088
+ constexpr explicit(N != rank_dynamic())
2089
+ mdspan(data_handle_type p, span<OtherIndexType, N> exts);
2090
+ template<class OtherIndexType, size_t N>
2091
+ constexpr explicit(N != rank_dynamic())
2092
+ mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
2093
+ ```
2094
+
2095
+ *Constraints:*
2096
+
2097
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`,
2098
+ - `(is_nothrow_constructible<index_type, const OtherIndexType&> && ...)`
2099
+ is `true`,
2100
+ - `N == rank() || N == rank_dynamic()` is `true`,
2101
+ - `is_constructible_v<mapping_type, extents_type>` is `true`, and
2102
+ - `is_default_constructible_v<accessor_type>` is `true`.
2103
+
2104
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
2105
+ an accessible range of `p` and *acc\_* for the values of *map\_* and
2106
+ *acc\_* after the invocation of this constructor.
2107
+
2108
+ *Effects:*
2109
+
2110
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
2111
+ - direct-non-list-initializes *map\_* with `extents_type(exts)`, and
2112
+ - value-initializes *acc\_*.
2113
+
2114
+ ``` cpp
2115
+ constexpr mdspan(data_handle_type p, const extents_type& ext);
2116
+ ```
2117
+
2118
+ *Constraints:*
2119
+
2120
+ - `is_constructible_v<mapping_type, const extents_type&>` is `true`, and
2121
+ - `is_default_constructible_v<accessor_type>` is `true`.
2122
+
2123
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
2124
+ an accessible range of `p` and *acc\_* for the values of *map\_* and
2125
+ *acc\_* after the invocation of this constructor.
2126
+
2127
+ *Effects:*
2128
+
2129
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
2130
+ - direct-non-list-initializes *map\_* with `ext`, and
2131
+ - value-initializes *acc\_*.
2132
+
2133
+ ``` cpp
2134
+ constexpr mdspan(data_handle_type p, const mapping_type& m);
2135
+ ```
2136
+
2137
+ *Constraints:* `is_default_constructible_v<accessor_type>` is `true`.
2138
+
2139
+ *Preconditions:* [0, `m.required_span_size()`) is an accessible range of
2140
+ `p` and *acc\_* for the value of *acc\_* after the invocation of this
2141
+ constructor.
2142
+
2143
+ *Effects:*
2144
+
2145
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
2146
+ - direct-non-list-initializes *map\_* with `m`, and
2147
+ - value-initializes *acc\_*.
2148
+
2149
+ ``` cpp
2150
+ constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
2151
+ ```
2152
+
2153
+ *Preconditions:* [0, `m.required_span_size()`) is an accessible range of
2154
+ `p` and `a`.
2155
+
2156
+ *Effects:*
2157
+
2158
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
2159
+ - direct-non-list-initializes *map\_* with `m`, and
2160
+ - direct-non-list-initializes *acc\_* with `a`.
2161
+
2162
+ ``` cpp
2163
+ template<class OtherElementType, class OtherExtents,
2164
+ class OtherLayoutPolicy, class OtherAccessor>
2165
+ constexpr explicit(see below)
2166
+ mdspan(const mdspan<OtherElementType, OtherExtents,
2167
+ OtherLayoutPolicy, OtherAccessor>& other);
2168
+ ```
2169
+
2170
+ *Constraints:*
2171
+
2172
+ - `is_constructible_v<mapping_type, const OtherLayoutPolicy::template mapping<Oth- erExtents>&>`
2173
+ is `true`, and
2174
+ - `is_constructible_v<accessor_type, const OtherAccessor&>` is `true`.
2175
+
2176
+ *Mandates:*
2177
+
2178
+ - `is_constructible_v<data_handle_type, const OtherAccessor::data_handle_type&>`
2179
+ is `true`, and
2180
+ - `is_constructible_v<extents_type, OtherExtents>` is `true`.
2181
+
2182
+ *Preconditions:*
2183
+
2184
+ - For each rank index `r` of `extents_type`,
2185
+ `static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r)`
2186
+ is `true`.
2187
+ - $[0, \texttt{\textit{map_}.required_span_size()})$ is an accessible
2188
+ range of *ptr\_* and *acc\_* for values of *ptr\_*, *map\_*, and
2189
+ *acc\_* after the invocation of this constructor.
2190
+
2191
+ *Effects:*
2192
+
2193
+ - Direct-non-list-initializes *ptr\_* with `other.`*`ptr_`*,
2194
+ - direct-non-list-initializes *map\_* with `other.`*`map_`*, and
2195
+ - direct-non-list-initializes *acc\_* with `other.`*`acc_`*.
2196
+
2197
+ *Remarks:* The expression inside `explicit` is equivalent to:
2198
+
2199
+ ``` cpp
2200
+ !is_convertible_v<const OtherLayoutPolicy::template mapping<OtherExtents>&, mapping_type>
2201
+ || !is_convertible_v<const OtherAccessor&, accessor_type>
2202
+ ```
2203
+
2204
+ ##### Members <a id="mdspan.mdspan.members">[[mdspan.mdspan.members]]</a>
2205
+
2206
+ ``` cpp
2207
+ template<class... OtherIndexTypes>
2208
+ constexpr reference operator[](OtherIndexTypes... indices) const;
2209
+ ```
2210
+
2211
+ *Constraints:*
2212
+
2213
+ - `(is_convertible_v<OtherIndexTypes, index_type> && ...)` is `true`,
2214
+ - `(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...)` is
2215
+ `true`, and
2216
+ - `sizeof...(OtherIndexTypes) == rank()` is `true`.
2217
+
2218
+ Let `I` be `extents_type::`*`index-cast`*`(std::move(indices))`.
2219
+
2220
+ *Preconditions:* `I` is a multidimensional index in `extents()`.
2221
+
2222
+ [*Note 1*: This implies that
2223
+ *`map_`*`(I) < `*`map_`*`.required_span_size()` is
2224
+ `true`. — *end note*]
2225
+
2226
+ *Effects:* Equivalent to:
2227
+
2228
+ ``` cpp
2229
+ return acc_.access(ptr_, map_(static_cast<index_type>(std::move(indices))...));
2230
+ ```
2231
+
2232
+ ``` cpp
2233
+ template<class OtherIndexType>
2234
+ constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
2235
+ template<class OtherIndexType>
2236
+ constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
2237
+ ```
2238
+
2239
+ *Constraints:*
2240
+
2241
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`, and
2242
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
2243
+ `true`.
2244
+
2245
+ *Effects:* Let `P` be a parameter pack such that
2246
+
2247
+ ``` cpp
2248
+ is_same_v<make_index_sequence<rank()>, index_sequence<P...>>
2249
+ ```
2250
+
2251
+ is `true`. Equivalent to:
2252
+
2253
+ ``` cpp
2254
+ return operator[](as_const(indices[P])...);
2255
+ ```
2256
+
2257
+ ``` cpp
2258
+ constexpr size_type size() const noexcept;
2259
+ ```
2260
+
2261
+ *Preconditions:* The size of the multidimensional index space
2262
+ `extents()` is representable as a value of type `size_type`
2263
+ [[basic.fundamental]].
2264
+
2265
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(rank())`.
2266
+
2267
+ ``` cpp
2268
+ [[nodiscard]] constexpr bool empty() const noexcept;
2269
+ ```
2270
+
2271
+ *Returns:* `true` if the size of the multidimensional index space
2272
+ `extents()` is 0, otherwise `false`.
2273
+
2274
+ ``` cpp
2275
+ friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
2276
+ ```
2277
+
2278
+ *Effects:* Equivalent to:
2279
+
2280
+ ``` cpp
2281
+ swap(x.ptr_, y.ptr_);
2282
+ swap(x.map_, y.map_);
2283
+ swap(x.acc_, y.acc_);
2284
+ ```
2285
+
2286
  <!-- Link reference definitions -->
2287
+ [alg.equal]: algorithms.md#alg.equal
2288
  [alg.sorting]: algorithms.md#alg.sorting
2289
  [algorithm.stable]: library.md#algorithm.stable
2290
  [algorithms]: algorithms.md#algorithms
2291
  [algorithms.requirements]: algorithms.md#algorithms.requirements
2292
  [allocator.requirements]: library.md#allocator.requirements
2293
  [allocator.requirements.completeness]: library.md#allocator.requirements.completeness
2294
+ [allocator.traits.members]: mem.md#allocator.traits.members
2295
+ [allocator.uses.construction]: mem.md#allocator.uses.construction
2296
  [array]: #array
2297
  [array.cons]: #array.cons
2298
  [array.creation]: #array.creation
2299
  [array.members]: #array.members
2300
  [array.overview]: #array.overview
 
2305
  [associative]: #associative
2306
  [associative.general]: #associative.general
2307
  [associative.map.syn]: #associative.map.syn
2308
  [associative.reqmts]: #associative.reqmts
2309
  [associative.reqmts.except]: #associative.reqmts.except
2310
+ [associative.reqmts.general]: #associative.reqmts.general
2311
  [associative.set.syn]: #associative.set.syn
2312
+ [basic.fundamental]: basic.md#basic.fundamental
2313
  [basic.string]: strings.md#basic.string
2314
  [class.copy.ctor]: class.md#class.copy.ctor
2315
  [class.default.ctor]: class.md#class.default.ctor
2316
  [class.dtor]: class.md#class.dtor
2317
  [container.adaptors]: #container.adaptors
2318
+ [container.adaptors.format]: #container.adaptors.format
2319
  [container.adaptors.general]: #container.adaptors.general
2320
+ [container.alloc.reqmts]: #container.alloc.reqmts
2321
+ [container.gen.reqmts]: #container.gen.reqmts
 
2322
  [container.insert.return]: #container.insert.return
2323
  [container.node]: #container.node
2324
  [container.node.compat]: #container.node.compat
2325
  [container.node.cons]: #container.node.cons
2326
  [container.node.dtor]: #container.node.dtor
2327
  [container.node.modifiers]: #container.node.modifiers
2328
  [container.node.observers]: #container.node.observers
2329
  [container.node.overview]: #container.node.overview
2330
+ [container.opt.reqmts]: #container.opt.reqmts
2331
+ [container.reqmts]: #container.reqmts
2332
  [container.requirements]: #container.requirements
2333
  [container.requirements.dataraces]: #container.requirements.dataraces
2334
  [container.requirements.general]: #container.requirements.general
2335
+ [container.requirements.pre]: #container.requirements.pre
2336
+ [container.rev.reqmts]: #container.rev.reqmts
 
2337
  [containers]: #containers
2338
  [containers.general]: #containers.general
2339
  [containers.summary]: #containers.summary
2340
  [dcl.init.aggr]: dcl.md#dcl.init.aggr
2341
+ [defns.valid]: intro.md#defns.valid
2342
  [deque]: #deque
2343
  [deque.capacity]: #deque.capacity
2344
  [deque.cons]: #deque.cons
2345
  [deque.erasure]: #deque.erasure
2346
  [deque.modifiers]: #deque.modifiers
2347
  [deque.overview]: #deque.overview
2348
  [deque.syn]: #deque.syn
2349
+ [expr.const]: expr.md#expr.const
2350
+ [flat.map]: #flat.map
2351
+ [flat.map.access]: #flat.map.access
2352
+ [flat.map.capacity]: #flat.map.capacity
2353
+ [flat.map.cons]: #flat.map.cons
2354
+ [flat.map.defn]: #flat.map.defn
2355
+ [flat.map.erasure]: #flat.map.erasure
2356
+ [flat.map.modifiers]: #flat.map.modifiers
2357
+ [flat.map.overview]: #flat.map.overview
2358
+ [flat.map.syn]: #flat.map.syn
2359
+ [flat.multimap]: #flat.multimap
2360
+ [flat.multimap.cons]: #flat.multimap.cons
2361
+ [flat.multimap.defn]: #flat.multimap.defn
2362
+ [flat.multimap.erasure]: #flat.multimap.erasure
2363
+ [flat.multimap.overview]: #flat.multimap.overview
2364
+ [flat.multiset]: #flat.multiset
2365
+ [flat.multiset.cons]: #flat.multiset.cons
2366
+ [flat.multiset.defn]: #flat.multiset.defn
2367
+ [flat.multiset.erasure]: #flat.multiset.erasure
2368
+ [flat.multiset.modifiers]: #flat.multiset.modifiers
2369
+ [flat.multiset.overview]: #flat.multiset.overview
2370
+ [flat.set]: #flat.set
2371
+ [flat.set.cons]: #flat.set.cons
2372
+ [flat.set.defn]: #flat.set.defn
2373
+ [flat.set.erasure]: #flat.set.erasure
2374
+ [flat.set.modifiers]: #flat.set.modifiers
2375
+ [flat.set.overview]: #flat.set.overview
2376
+ [flat.set.syn]: #flat.set.syn
2377
+ [forward.iterators]: iterators.md#forward.iterators
2378
+ [forward.list]: #forward.list
2379
+ [forward.list.access]: #forward.list.access
2380
+ [forward.list.cons]: #forward.list.cons
2381
  [forward.list.erasure]: #forward.list.erasure
2382
+ [forward.list.iter]: #forward.list.iter
2383
+ [forward.list.modifiers]: #forward.list.modifiers
2384
+ [forward.list.ops]: #forward.list.ops
2385
+ [forward.list.overview]: #forward.list.overview
2386
  [forward.list.syn]: #forward.list.syn
 
 
 
 
 
 
 
2387
  [hash.requirements]: library.md#hash.requirements
2388
  [iterator.concept.contiguous]: iterators.md#iterator.concept.contiguous
2389
+ [iterator.concept.random.access]: iterators.md#iterator.concept.random.access
2390
  [iterator.requirements]: iterators.md#iterator.requirements
2391
  [iterator.requirements.general]: iterators.md#iterator.requirements.general
2392
  [list]: #list
2393
  [list.capacity]: #list.capacity
2394
  [list.cons]: #list.cons
 
2401
  [map.access]: #map.access
2402
  [map.cons]: #map.cons
2403
  [map.erasure]: #map.erasure
2404
  [map.modifiers]: #map.modifiers
2405
  [map.overview]: #map.overview
2406
+ [mdspan.accessor]: #mdspan.accessor
2407
+ [mdspan.accessor.default]: #mdspan.accessor.default
2408
+ [mdspan.accessor.default.members]: #mdspan.accessor.default.members
2409
+ [mdspan.accessor.default.overview]: #mdspan.accessor.default.overview
2410
+ [mdspan.accessor.general]: #mdspan.accessor.general
2411
+ [mdspan.accessor.reqmts]: #mdspan.accessor.reqmts
2412
+ [mdspan.extents]: #mdspan.extents
2413
+ [mdspan.extents.cmp]: #mdspan.extents.cmp
2414
+ [mdspan.extents.cons]: #mdspan.extents.cons
2415
+ [mdspan.extents.dextents]: #mdspan.extents.dextents
2416
+ [mdspan.extents.expo]: #mdspan.extents.expo
2417
+ [mdspan.extents.obs]: #mdspan.extents.obs
2418
+ [mdspan.extents.overview]: #mdspan.extents.overview
2419
+ [mdspan.layout]: #mdspan.layout
2420
+ [mdspan.layout.general]: #mdspan.layout.general
2421
+ [mdspan.layout.left]: #mdspan.layout.left
2422
+ [mdspan.layout.left.cons]: #mdspan.layout.left.cons
2423
+ [mdspan.layout.left.obs]: #mdspan.layout.left.obs
2424
+ [mdspan.layout.left.overview]: #mdspan.layout.left.overview
2425
+ [mdspan.layout.policy.overview]: #mdspan.layout.policy.overview
2426
+ [mdspan.layout.policy.reqmts]: #mdspan.layout.policy.reqmts
2427
+ [mdspan.layout.reqmts]: #mdspan.layout.reqmts
2428
+ [mdspan.layout.right]: #mdspan.layout.right
2429
+ [mdspan.layout.right.cons]: #mdspan.layout.right.cons
2430
+ [mdspan.layout.right.obs]: #mdspan.layout.right.obs
2431
+ [mdspan.layout.right.overview]: #mdspan.layout.right.overview
2432
+ [mdspan.layout.stride]: #mdspan.layout.stride
2433
+ [mdspan.layout.stride.cons]: #mdspan.layout.stride.cons
2434
+ [mdspan.layout.stride.expo]: #mdspan.layout.stride.expo
2435
+ [mdspan.layout.stride.obs]: #mdspan.layout.stride.obs
2436
+ [mdspan.layout.stride.overview]: #mdspan.layout.stride.overview
2437
+ [mdspan.mdspan]: #mdspan.mdspan
2438
+ [mdspan.mdspan.cons]: #mdspan.mdspan.cons
2439
+ [mdspan.mdspan.members]: #mdspan.mdspan.members
2440
+ [mdspan.mdspan.overview]: #mdspan.mdspan.overview
2441
+ [mdspan.overview]: #mdspan.overview
2442
+ [mdspan.syn]: #mdspan.syn
2443
  [multimap]: #multimap
2444
  [multimap.cons]: #multimap.cons
2445
  [multimap.erasure]: #multimap.erasure
2446
  [multimap.modifiers]: #multimap.modifiers
2447
  [multimap.overview]: #multimap.overview
 
2457
  [priqueue.special]: #priqueue.special
2458
  [queue]: #queue
2459
  [queue.cons]: #queue.cons
2460
  [queue.cons.alloc]: #queue.cons.alloc
2461
  [queue.defn]: #queue.defn
2462
+ [queue.mod]: #queue.mod
2463
  [queue.ops]: #queue.ops
2464
  [queue.special]: #queue.special
2465
  [queue.syn]: #queue.syn
2466
  [random.access.iterators]: iterators.md#random.access.iterators
2467
  [res.on.data.races]: library.md#res.on.data.races
 
2483
  [span.syn]: #span.syn
2484
  [stack]: #stack
2485
  [stack.cons]: #stack.cons
2486
  [stack.cons.alloc]: #stack.cons.alloc
2487
  [stack.defn]: #stack.defn
2488
+ [stack.general]: #stack.general
2489
+ [stack.mod]: #stack.mod
2490
  [stack.ops]: #stack.ops
2491
  [stack.special]: #stack.special
2492
  [stack.syn]: #stack.syn
2493
  [strings]: strings.md#strings
2494
  [swappable.requirements]: library.md#swappable.requirements
 
 
 
 
 
2495
  [temp.deduct]: temp.md#temp.deduct
2496
  [temp.param]: temp.md#temp.param
2497
  [temp.type]: temp.md#temp.type
2498
+ [term.trivially.copyable.type]: basic.md#term.trivially.copyable.type
2499
  [unord]: #unord
2500
  [unord.general]: #unord.general
2501
  [unord.hash]: utilities.md#unord.hash
2502
  [unord.map]: #unord.map
2503
  [unord.map.cnstr]: #unord.map.cnstr
 
2515
  [unord.multiset.cnstr]: #unord.multiset.cnstr
2516
  [unord.multiset.erasure]: #unord.multiset.erasure
2517
  [unord.multiset.overview]: #unord.multiset.overview
2518
  [unord.req]: #unord.req
2519
  [unord.req.except]: #unord.req.except
2520
+ [unord.req.general]: #unord.req.general
2521
  [unord.set]: #unord.set
2522
  [unord.set.cnstr]: #unord.set.cnstr
2523
  [unord.set.erasure]: #unord.set.erasure
2524
  [unord.set.overview]: #unord.set.overview
2525
  [unord.set.syn]: #unord.set.syn
2526
  [vector]: #vector
2527
  [vector.bool]: #vector.bool
2528
+ [vector.bool.fmt]: #vector.bool.fmt
2529
+ [vector.bool.pspc]: #vector.bool.pspc
2530
  [vector.capacity]: #vector.capacity
2531
  [vector.cons]: #vector.cons
2532
  [vector.data]: #vector.data
2533
  [vector.erasure]: #vector.erasure
2534
  [vector.modifiers]: #vector.modifiers
2535
  [vector.overview]: #vector.overview
2536
  [vector.syn]: #vector.syn
2537
  [views]: #views
2538
+ [views.contiguous]: #views.contiguous
2539
  [views.general]: #views.general
2540
+ [views.multidim]: #views.multidim
2541
  [views.span]: #views.span
2542
 
2543
  [^1]: Equality comparison is a refinement of partitioning if no two
2544
  objects that compare equal fall into different partitions.
2545
 
 
2547
  iterators are random access iterators.
2548
 
2549
  [^3]: As specified in  [[allocator.requirements]], the requirements in
2550
  this Clause apply only to lists whose allocators compare equal.
2551
 
2552
+ [^4]: `reserve()` uses `Allocator::allocate()` which can throw an
2553
  appropriate exception.