From Jason Turner

[predef.iterators]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpg5nowt6v/{from.md → to.md} +581 -98
tmp/tmpg5nowt6v/{from.md → to.md} RENAMED
@@ -1,9 +1,11 @@
1
  ## Iterator adaptors <a id="predef.iterators">[[predef.iterators]]</a>
2
 
3
  ### Reverse iterators <a id="reverse.iterators">[[reverse.iterators]]</a>
4
 
 
 
5
  Class template `reverse_iterator` is an iterator adaptor that iterates
6
  from the end of the sequence defined by its underlying iterator to the
7
  beginning of that sequence.
8
 
9
  #### Class template `reverse_iterator` <a id="reverse.iterator">[[reverse.iterator]]</a>
@@ -108,26 +110,33 @@ constexpr explicit reverse_iterator(Iterator x);
108
 
109
  ``` cpp
110
  template<class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
111
  ```
112
 
 
 
 
113
  *Effects:* Initializes `current` with `u.current`.
114
 
115
  ``` cpp
116
  template<class U>
117
  constexpr reverse_iterator&
118
  operator=(const reverse_iterator<U>& u);
119
  ```
120
 
121
- *Effects:* Assigns `u.base()` to `current`.
 
 
 
 
122
 
123
  *Returns:* `*this`.
124
 
125
  #### Conversion <a id="reverse.iter.conv">[[reverse.iter.conv]]</a>
126
 
127
  ``` cpp
128
- constexpr Iterator base() const; // explicit
129
  ```
130
 
131
  *Returns:* `current`.
132
 
133
  #### Element access <a id="reverse.iter.elem">[[reverse.iter.elem]]</a>
@@ -177,11 +186,11 @@ constexpr reverse_iterator operator-(difference_type n) const;
177
 
178
  ``` cpp
179
  constexpr reverse_iterator& operator++();
180
  ```
181
 
182
- *Effects:* As if by: `current;`
183
 
184
  *Returns:* `*this`.
185
 
186
  ``` cpp
187
  constexpr reverse_iterator operator++(int);
@@ -329,11 +338,11 @@ template<class Iterator1, class Iterator2>
329
  *Returns:* `y.base() - x.base()`.
330
 
331
  ``` cpp
332
  template<class Iterator>
333
  constexpr reverse_iterator<Iterator> operator+(
334
- typename reverse_iterator<Iterator>::difference_type n,
335
  const reverse_iterator<Iterator>& x);
336
  ```
337
 
338
  *Returns:* `reverse_iterator<Iterator>(x.base() - n)`.
339
 
@@ -347,11 +356,11 @@ friend constexpr iter_rvalue_reference_t<Iterator>
347
  ``` cpp
348
  auto tmp = i.base();
349
  return ranges::iter_move(--tmp);
350
  ```
351
 
352
- *Remarks:* The expression in `noexcept` is equivalent to:
353
 
354
  ``` cpp
355
  is_nothrow_copy_constructible_v<Iterator> &&
356
  noexcept(ranges::iter_move(--declval<Iterator&>()))
357
  ```
@@ -369,11 +378,11 @@ template<indirectly_swappable<Iterator> Iterator2>
369
  auto xtmp = x.base();
370
  auto ytmp = y.base();
371
  ranges::iter_swap(--xtmp, --ytmp);
372
  ```
373
 
374
- *Remarks:* The expression in `noexcept` is equivalent to:
375
 
376
  ``` cpp
377
  is_nothrow_copy_constructible_v<Iterator> &&
378
  is_nothrow_copy_constructible_v<Iterator2> &&
379
  noexcept(ranges::iter_swap(--declval<Iterator&>(), --declval<Iterator2&>()))
@@ -386,10 +395,12 @@ template<class Iterator>
386
 
387
  *Returns:* `reverse_iterator<Iterator>(i)`.
388
 
389
  ### Insert iterators <a id="insert.iterators">[[insert.iterators]]</a>
390
 
 
 
391
  To make it possible to deal with insertion in the same way as writing
392
  into an array, a special kind of iterator adaptors, called *insert
393
  iterators*, are provided in the library. With regular iterator classes,
394
 
395
  ``` cpp
@@ -422,21 +433,20 @@ iterators out of a container.
422
  ``` cpp
423
  namespace std {
424
  template<class Container>
425
  class back_insert_iterator {
426
  protected:
427
- Container* container = nullptr;
428
 
429
  public:
430
  using iterator_category = output_iterator_tag;
431
  using value_type = void;
432
  using difference_type = ptrdiff_t;
433
  using pointer = void;
434
  using reference = void;
435
  using container_type = Container;
436
 
437
- constexpr back_insert_iterator() noexcept = default;
438
  constexpr explicit back_insert_iterator(Container& x);
439
  constexpr back_insert_iterator& operator=(const typename Container::value_type& value);
440
  constexpr back_insert_iterator& operator=(typename Container::value_type&& value);
441
 
442
  constexpr back_insert_iterator& operator*();
@@ -497,21 +507,20 @@ template<class Container>
497
  ``` cpp
498
  namespace std {
499
  template<class Container>
500
  class front_insert_iterator {
501
  protected:
502
- Container* container = nullptr;
503
 
504
  public:
505
  using iterator_category = output_iterator_tag;
506
  using value_type = void;
507
  using difference_type = ptrdiff_t;
508
  using pointer = void;
509
  using reference = void;
510
  using container_type = Container;
511
 
512
- constexpr front_insert_iterator() noexcept = default;
513
  constexpr explicit front_insert_iterator(Container& x);
514
  constexpr front_insert_iterator& operator=(const typename Container::value_type& value);
515
  constexpr front_insert_iterator& operator=(typename Container::value_type&& value);
516
 
517
  constexpr front_insert_iterator& operator*();
@@ -572,22 +581,21 @@ template<class Container>
572
  ``` cpp
573
  namespace std {
574
  template<class Container>
575
  class insert_iterator {
576
  protected:
577
- Container* container = nullptr;
578
- ranges::iterator_t<Container> iter = ranges::iterator_t<Container>();
579
 
580
  public:
581
  using iterator_category = output_iterator_tag;
582
  using value_type = void;
583
  using difference_type = ptrdiff_t;
584
  using pointer = void;
585
  using reference = void;
586
  using container_type = Container;
587
 
588
- insert_iterator() = default;
589
  constexpr insert_iterator(Container& x, ranges::iterator_t<Container> i);
590
  constexpr insert_iterator& operator=(const typename Container::value_type& value);
591
  constexpr insert_iterator& operator=(typename Container::value_type&& value);
592
 
593
  constexpr insert_iterator& operator*();
@@ -653,12 +661,425 @@ template<class Container>
653
  inserter(Container& x, ranges::iterator_t<Container> i);
654
  ```
655
 
656
  *Returns:* `insert_iterator<Container>(x, i)`.
657
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
658
  ### Move iterators and sentinels <a id="move.iterators">[[move.iterators]]</a>
659
 
 
 
660
  Class template `move_iterator` is an iterator adaptor with the same
661
  behavior as the underlying iterator except that its indirection operator
662
  implicitly converts the value returned by the underlying iterator’s
663
  indirection operator to an rvalue. Some generic algorithms can be called
664
  with move iterators to replace copying with moving.
@@ -681,24 +1102,24 @@ vector<string> v2(make_move_iterator(s.begin()),
681
  namespace std {
682
  template<class Iterator>
683
  class move_iterator {
684
  public:
685
  using iterator_type = Iterator;
686
- using iterator_concept = input_iterator_tag;
687
- using iterator_category = see below;
688
  using value_type = iter_value_t<Iterator>;
689
  using difference_type = iter_difference_t<Iterator>;
690
  using pointer = Iterator;
691
  using reference = iter_rvalue_reference_t<Iterator>;
692
 
693
  constexpr move_iterator();
694
  constexpr explicit move_iterator(Iterator i);
695
  template<class U> constexpr move_iterator(const move_iterator<U>& u);
696
  template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
697
 
698
- constexpr iterator_type base() const &;
699
- constexpr iterator_type base() &&;
700
  constexpr reference operator*() const;
701
 
702
  constexpr move_iterator& operator++();
703
  constexpr auto operator++(int);
704
  constexpr move_iterator& operator--();
@@ -731,11 +1152,23 @@ namespace std {
731
  Iterator current; // exposition only
732
  };
733
  }
734
  ```
735
 
736
- The member *typedef-name* `iterator_category` denotes
 
 
 
 
 
 
 
 
 
 
 
 
737
 
738
  - `random_access_iterator_tag` if the type
739
  `iterator_traits<{}Iterator>::iterator_category` models
740
  `derived_from<random_access_iterator_tag>`, and
741
  - `iterator_traits<{}Iterator>::iterator_category` otherwise.
@@ -758,49 +1191,45 @@ parameter shall either meet the *Cpp17RandomAccessIterator* requirements
758
 
759
  ``` cpp
760
  constexpr move_iterator();
761
  ```
762
 
763
- *Effects:* Constructs a `move_iterator`, value-initializing `current`.
764
- Iterator operations applied to the resulting iterator have defined
765
- behavior if and only if the corresponding operations are defined on a
766
- value-initialized iterator of type `Iterator`.
767
 
768
  ``` cpp
769
  constexpr explicit move_iterator(Iterator i);
770
  ```
771
 
772
- *Effects:* Constructs a `move_iterator`, initializing `current` with
773
- `std::move(i)`.
774
 
775
  ``` cpp
776
  template<class U> constexpr move_iterator(const move_iterator<U>& u);
777
  ```
778
 
779
- *Mandates:* `U` is convertible to `Iterator`.
 
780
 
781
- *Effects:* Constructs a `move_iterator`, initializing `current` with
782
- `u.base()`.
783
 
784
  ``` cpp
785
  template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
786
  ```
787
 
788
- *Mandates:* `U` is convertible to `Iterator`.
 
 
789
 
790
- *Effects:* Assigns `u.base()` to `current`.
 
 
791
 
792
  #### Conversion <a id="move.iter.op.conv">[[move.iter.op.conv]]</a>
793
 
794
  ``` cpp
795
- constexpr Iterator base() const &;
796
  ```
797
 
798
- *Constraints:* `Iterator` satisfies `copy_constructible`.
799
-
800
- *Preconditions:* `Iterator` models `copy_constructible`.
801
-
802
  *Returns:* `current`.
803
 
804
  ``` cpp
805
  constexpr Iterator base() &&;
806
  ```
@@ -817,11 +1246,11 @@ constexpr reference operator*() const;
817
 
818
  ``` cpp
819
  constexpr reference operator[](difference_type n) const;
820
  ```
821
 
822
- *Effects:* Equivalent to: `ranges::iter_move(current + n);`
823
 
824
  #### Navigation <a id="move.iter.nav">[[move.iter.nav]]</a>
825
 
826
  ``` cpp
827
  constexpr move_iterator& operator++();
@@ -847,11 +1276,11 @@ Otherwise, equivalent to `++current`.
847
 
848
  ``` cpp
849
  constexpr move_iterator& operator--();
850
  ```
851
 
852
- *Effects:* As if by `current`.
853
 
854
  *Returns:* `*this`.
855
 
856
  ``` cpp
857
  constexpr move_iterator operator--(int);
@@ -960,12 +1389,12 @@ template<class Iterator1, three_way_comparable_with<Iterator1> Iterator2>
960
 
961
  #### Non-member functions <a id="move.iter.nonmember">[[move.iter.nonmember]]</a>
962
 
963
  ``` cpp
964
  template<class Iterator1, class Iterator2>
965
- constexpr auto operator-(const move_iterator<Iterator1>& x,
966
- const move_iterator<Iterator2>& y)
967
  -> decltype(x.base() - y.base());
968
  template<sized_sentinel_for<Iterator> S>
969
  friend constexpr iter_difference_t<Iterator>
970
  operator-(const move_sentinel<S>& x, const move_iterator& y);
971
  template<sized_sentinel_for<Iterator> S>
@@ -979,11 +1408,11 @@ template<sized_sentinel_for<Iterator> S>
979
  template<class Iterator>
980
  constexpr move_iterator<Iterator>
981
  operator+(iter_difference_t<Iterator> n, const move_iterator<Iterator>& x);
982
  ```
983
 
984
- *Constraints:* `x + n` is well-formed and has type `Iterator`.
985
 
986
  *Returns:* `x + n`.
987
 
988
  ``` cpp
989
  friend constexpr iter_rvalue_reference_t<Iterator>
@@ -1013,11 +1442,11 @@ constexpr move_iterator<Iterator> make_move_iterator(Iterator i);
1013
 
1014
  Class template `move_sentinel` is a sentinel adaptor useful for denoting
1015
  ranges together with `move_iterator`. When an input iterator type `I`
1016
  and sentinel type `S` model `sentinel_for<S, I>`, `move_sentinel<S>` and
1017
  `move_iterator<I>` model
1018
- `sentinel_for<move_sentinel<S>, move_iterator<I>{>}` as well.
1019
 
1020
  [*Example 1*:
1021
 
1022
  A `move_if` algorithm is easily implemented with `copy_if` using
1023
  `move_iterator` and `move_sentinel`:
@@ -1025,11 +1454,12 @@ A `move_if` algorithm is easily implemented with `copy_if` using
1025
  ``` cpp
1026
  template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
1027
  indirect_unary_predicate<I> Pred>
1028
  requires indirectly_movable<I, O>
1029
  void move_if(I first, S last, O out, Pred pred) {
1030
- std::ranges::copy_if(move_iterator<I>{first}, move_sentinel<S>{last}, out, pred);
 
1031
  }
1032
  ```
1033
 
1034
  — *end example*]
1035
 
@@ -1046,10 +1476,11 @@ namespace std {
1046
  template<class S2>
1047
  requires assignable_from<S&, const S2&>
1048
  constexpr move_sentinel& operator=(const move_sentinel<S2>& s);
1049
 
1050
  constexpr S base() const;
 
1051
  private:
1052
  S last; // exposition only
1053
  };
1054
  }
1055
  ```
@@ -1125,50 +1556,50 @@ fun(CI(counted_iterator(s.begin(), 10)), CI(default_sentinel));
1125
  namespace std {
1126
  template<input_or_output_iterator I, sentinel_for<I> S>
1127
  requires (!same_as<I, S> && copyable<I>)
1128
  class common_iterator {
1129
  public:
1130
- constexpr common_iterator() = default;
1131
  constexpr common_iterator(I i);
1132
  constexpr common_iterator(S s);
1133
  template<class I2, class S2>
1134
  requires convertible_to<const I2&, I> && convertible_to<const S2&, S>
1135
  constexpr common_iterator(const common_iterator<I2, S2>& x);
1136
 
1137
  template<class I2, class S2>
1138
  requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
1139
  assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
1140
- common_iterator& operator=(const common_iterator<I2, S2>& x);
1141
 
1142
- decltype(auto) operator*();
1143
- decltype(auto) operator*() const
1144
  requires dereferenceable<const I>;
1145
- decltype(auto) operator->() const
1146
  requires see below;
1147
 
1148
- common_iterator& operator++();
1149
- decltype(auto) operator++(int);
1150
 
1151
  template<class I2, sentinel_for<I> S2>
1152
  requires sentinel_for<S, I2>
1153
- friend bool operator==(
1154
  const common_iterator& x, const common_iterator<I2, S2>& y);
1155
  template<class I2, sentinel_for<I> S2>
1156
  requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
1157
- friend bool operator==(
1158
  const common_iterator& x, const common_iterator<I2, S2>& y);
1159
 
1160
  template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
1161
  requires sized_sentinel_for<S, I2>
1162
- friend iter_difference_t<I2> operator-(
1163
  const common_iterator& x, const common_iterator<I2, S2>& y);
1164
 
1165
- friend iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
1166
  noexcept(noexcept(ranges::iter_move(declval<const I&>())))
1167
  requires input_iterator<I>;
1168
  template<indirectly_swappable<I> I2, class S2>
1169
- friend void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
1170
  noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
1171
 
1172
  private:
1173
  variant<I, S> v_; // exposition only
1174
  };
@@ -1195,17 +1626,17 @@ namespace std {
1195
  The nested *typedef-name*s of the specialization of `iterator_traits`
1196
  for `common_iterator<I, S>` are defined as follows.
1197
 
1198
  - `iterator_concept` denotes `forward_iterator_tag` if `I` models
1199
  `forward_iterator`; otherwise it denotes `input_iterator_tag`.
1200
- - `iterator_category` denotes `forward_iterator_tag` if
1201
- `iterator_traits<I>::iterator_category` models
1202
- `derived_from<forward_iterator_tag>`; otherwise it denotes
1203
- `input_iterator_tag`.
1204
- - If the expression `a.operator->()` is well-formed, where `a` is an
1205
- lvalue of type `const common_iterator<I, S>`, then `pointer` denotes
1206
- the type of that expression. Otherwise, `pointer` denotes `void`.
1207
 
1208
  #### Constructors and conversions <a id="common.iter.const">[[common.iter.const]]</a>
1209
 
1210
  ``` cpp
1211
  constexpr common_iterator(I i);
@@ -1234,11 +1665,11 @@ template<class I2, class S2>
1234
 
1235
  ``` cpp
1236
  template<class I2, class S2>
1237
  requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
1238
  assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
1239
- common_iterator& operator=(const common_iterator<I2, S2>& x);
1240
  ```
1241
 
1242
  *Preconditions:* `x.v_.valueless_by_exception()` is `false`.
1243
 
1244
  *Effects:* Equivalent to:
@@ -1251,34 +1682,34 @@ where i is `x.v_.index()`.
1251
  *Returns:* `*this`
1252
 
1253
  #### Accessors <a id="common.iter.access">[[common.iter.access]]</a>
1254
 
1255
  ``` cpp
1256
- decltype(auto) operator*();
1257
- decltype(auto) operator*() const
1258
  requires dereferenceable<const I>;
1259
  ```
1260
 
1261
- *Preconditions:* `holds_alternative<I>(v_)`.
1262
 
1263
  *Effects:* Equivalent to: `return *get<I>(v_);`
1264
 
1265
  ``` cpp
1266
- decltype(auto) operator->() const
1267
  requires see below;
1268
  ```
1269
 
1270
- The expression in the requires clause is equivalent to:
1271
 
1272
  ``` cpp
1273
  indirectly_readable<const I> &&
1274
  (requires(const I& i) { i.operator->(); } ||
1275
  is_reference_v<iter_reference_t<I>> ||
1276
  constructible_from<iter_value_t<I>, iter_reference_t<I>>)
1277
  ```
1278
 
1279
- *Preconditions:* `holds_alternative<I>(v_)`.
1280
 
1281
  *Effects:*
1282
 
1283
  - If `I` is a pointer type or if the expression
1284
  `get<I>(v_).operator->()` is well-formed, equivalent to:
@@ -1292,53 +1723,87 @@ indirectly_readable<const I> &&
1292
  - Otherwise, equivalent to: `return `*`proxy`*`(*get<I>(v_));` where
1293
  *proxy* is the exposition-only class:
1294
  ``` cpp
1295
  class proxy {
1296
  iter_value_t<I> keep_;
1297
- proxy(iter_reference_t<I>&& x)
1298
  : keep_(std::move(x)) {}
1299
  public:
1300
- const iter_value_t<I>* operator->() const {
1301
  return addressof(keep_);
1302
  }
1303
  };
1304
  ```
1305
 
1306
  #### Navigation <a id="common.iter.nav">[[common.iter.nav]]</a>
1307
 
1308
  ``` cpp
1309
- common_iterator& operator++();
1310
  ```
1311
 
1312
- *Preconditions:* `holds_alternative<I>(v_)`.
1313
 
1314
  *Effects:* Equivalent to `++get<I>(v_)`.
1315
 
1316
  *Returns:* `*this`.
1317
 
1318
  ``` cpp
1319
- decltype(auto) operator++(int);
1320
  ```
1321
 
1322
- *Preconditions:* `holds_alternative<I>(v_)`.
1323
 
1324
  *Effects:* If `I` models `forward_iterator`, equivalent to:
1325
 
1326
  ``` cpp
1327
  common_iterator tmp = *this;
1328
  ++*this;
1329
  return tmp;
1330
  ```
1331
 
1332
- Otherwise, equivalent to: `return get<I>(v_)++;`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1333
 
1334
  #### Comparisons <a id="common.iter.cmp">[[common.iter.cmp]]</a>
1335
 
1336
  ``` cpp
1337
  template<class I2, sentinel_for<I> S2>
1338
  requires sentinel_for<S, I2>
1339
- friend bool operator==(
1340
  const common_iterator& x, const common_iterator<I2, S2>& y);
1341
  ```
1342
 
1343
  *Preconditions:* `x.v_.valueless_by_exception()` and
1344
  `y.v_.valueless_by_exception()` are each `false`.
@@ -1348,11 +1813,11 @@ friend bool operator==(
1348
  `y.v_.index()`.
1349
 
1350
  ``` cpp
1351
  template<class I2, sentinel_for<I> S2>
1352
  requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
1353
- friend bool operator==(
1354
  const common_iterator& x, const common_iterator<I2, S2>& y);
1355
  ```
1356
 
1357
  *Preconditions:* `x.v_.valueless_by_exception()` and
1358
  `y.v_.valueless_by_exception()` are each `false`.
@@ -1362,46 +1827,46 @@ friend bool operator==(
1362
  `y.v_.index()`.
1363
 
1364
  ``` cpp
1365
  template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
1366
  requires sized_sentinel_for<S, I2>
1367
- friend iter_difference_t<I2> operator-(
1368
  const common_iterator& x, const common_iterator<I2, S2>& y);
1369
  ```
1370
 
1371
  *Preconditions:* `x.v_.valueless_by_exception()` and
1372
  `y.v_.valueless_by_exception()` are each `false`.
1373
 
1374
  *Returns:* `0` if i and j are each `1`, and otherwise
1375
  `get<`i`>(x.v_) - get<`j`>(y.v_)`, where i is `x.v_.index()` and j is
1376
  `y.v_.index()`.
1377
 
1378
- #### Customization <a id="common.iter.cust">[[common.iter.cust]]</a>
1379
 
1380
  ``` cpp
1381
- friend iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
1382
  noexcept(noexcept(ranges::iter_move(declval<const I&>())))
1383
  requires input_iterator<I>;
1384
  ```
1385
 
1386
- *Preconditions:* `holds_alternative<I>(v_)`.
1387
 
1388
  *Effects:* Equivalent to: `return ranges::iter_move(get<I>(i.v_));`
1389
 
1390
  ``` cpp
1391
  template<indirectly_swappable<I> I2, class S2>
1392
- friend void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
1393
  noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
1394
  ```
1395
 
1396
  *Preconditions:* `holds_alternative<I>(x.v_)` and
1397
  `holds_alternative<I2>(y.v_)` are each `true`.
1398
 
1399
  *Effects:* Equivalent to
1400
  `ranges::iter_swap(get<I>(x.v_), get<I2>(y.v_))`.
1401
 
1402
- ### Default sentinels <a id="default.sentinels">[[default.sentinels]]</a>
1403
 
1404
  ``` cpp
1405
  namespace std {
1406
  struct default_sentinel_t { };
1407
  }
@@ -1434,39 +1899,49 @@ ranges::copy(counted_iterator(s.begin(), 10), default_sentinel, back_inserter(v)
1434
 
1435
  — *end example*]
1436
 
1437
  Two values `i1` and `i2` of types `counted_iterator<I1>` and
1438
  `counted_iterator<I2>` refer to elements of the same sequence if and
1439
- only if `next(i1.base(), i1.count())` and `next(i2.base(), i2.count())`
 
1440
  refer to the same (possibly past-the-end) element.
1441
 
1442
  ``` cpp
1443
  namespace std {
1444
  template<input_or_output_iterator I>
1445
  class counted_iterator {
1446
  public:
1447
  using iterator_type = I;
1448
-
1449
- constexpr counted_iterator() = default;
 
 
 
 
 
 
1450
  constexpr counted_iterator(I x, iter_difference_t<I> n);
1451
  template<class I2>
1452
  requires convertible_to<const I2&, I>
1453
  constexpr counted_iterator(const counted_iterator<I2>& x);
1454
 
1455
  template<class I2>
1456
  requires assignable_from<I&, const I2&>
1457
  constexpr counted_iterator& operator=(const counted_iterator<I2>& x);
1458
 
1459
- constexpr I base() const & requires copy_constructible<I>;
1460
  constexpr I base() &&;
1461
  constexpr iter_difference_t<I> count() const noexcept;
1462
  constexpr decltype(auto) operator*();
1463
  constexpr decltype(auto) operator*() const
1464
  requires dereferenceable<const I>;
1465
 
 
 
 
1466
  constexpr counted_iterator& operator++();
1467
- decltype(auto) operator++(int);
1468
  constexpr counted_iterator operator++(int)
1469
  requires forward_iterator<I>;
1470
  constexpr counted_iterator& operator--()
1471
  requires bidirectional_iterator<I>;
1472
  constexpr counted_iterator operator--(int)
@@ -1515,18 +1990,15 @@ namespace std {
1515
  private:
1516
  I current = I(); // exposition only
1517
  iter_difference_t<I> length = 0; // exposition only
1518
  };
1519
 
1520
- template<class I>
1521
- struct incrementable_traits<counted_iterator<I>> {
1522
- using difference_type = iter_difference_t<I>;
1523
- };
1524
-
1525
  template<input_iterator I>
 
1526
  struct iterator_traits<counted_iterator<I>> : iterator_traits<I> {
1527
- using pointer = void;
 
1528
  };
1529
  }
1530
  ```
1531
 
1532
  #### Constructors and conversions <a id="counted.iter.const">[[counted.iter.const]]</a>
@@ -1560,11 +2032,11 @@ template<class I2>
1560
  *Returns:* `*this`.
1561
 
1562
  #### Accessors <a id="counted.iter.access">[[counted.iter.access]]</a>
1563
 
1564
  ``` cpp
1565
- constexpr I base() const & requires copy_constructible<I>;
1566
  ```
1567
 
1568
  *Effects:* Equivalent to: `return current;`
1569
 
1570
  ``` cpp
@@ -1585,12 +2057,21 @@ constexpr iter_difference_t<I> count() const noexcept;
1585
  constexpr decltype(auto) operator*();
1586
  constexpr decltype(auto) operator*() const
1587
  requires dereferenceable<const I>;
1588
  ```
1589
 
 
 
1590
  *Effects:* Equivalent to: `return *current;`
1591
 
 
 
 
 
 
 
 
1592
  ``` cpp
1593
  constexpr decltype(auto) operator[](iter_difference_t<I> n) const
1594
  requires random_access_iterator<I>;
1595
  ```
1596
 
@@ -1613,11 +2094,11 @@ constexpr counted_iterator& operator++();
1613
  --length;
1614
  return *this;
1615
  ```
1616
 
1617
  ``` cpp
1618
- decltype(auto) operator++(int);
1619
  ```
1620
 
1621
  *Preconditions:* `length > 0`.
1622
 
1623
  *Effects:* Equivalent to:
@@ -1787,24 +2268,26 @@ friend constexpr iter_rvalue_reference_t<I>
1787
  iter_move(const counted_iterator& i)
1788
  noexcept(noexcept(ranges::iter_move(i.current)))
1789
  requires input_iterator<I>;
1790
  ```
1791
 
 
 
1792
  *Effects:* Equivalent to: `return ranges::iter_move(i.current);`
1793
 
1794
  ``` cpp
1795
  template<indirectly_swappable<I> I2>
1796
  friend constexpr void
1797
  iter_swap(const counted_iterator& x, const counted_iterator<I2>& y)
1798
  noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
1799
  ```
1800
 
 
 
1801
  *Effects:* Equivalent to `ranges::iter_swap(x.current, y.current)`.
1802
 
1803
- ### Unreachable sentinel <a id="unreachable.sentinels">[[unreachable.sentinels]]</a>
1804
-
1805
- #### Class `unreachable_sentinel_t` <a id="unreachable.sentinel">[[unreachable.sentinel]]</a>
1806
 
1807
  Class `unreachable_sentinel_t` can be used with any
1808
  `weakly_incrementable` type to denote the “upper bound” of an unbounded
1809
  interval.
1810
 
 
1
  ## Iterator adaptors <a id="predef.iterators">[[predef.iterators]]</a>
2
 
3
  ### Reverse iterators <a id="reverse.iterators">[[reverse.iterators]]</a>
4
 
5
+ #### General <a id="reverse.iterators.general">[[reverse.iterators.general]]</a>
6
+
7
  Class template `reverse_iterator` is an iterator adaptor that iterates
8
  from the end of the sequence defined by its underlying iterator to the
9
  beginning of that sequence.
10
 
11
  #### Class template `reverse_iterator` <a id="reverse.iterator">[[reverse.iterator]]</a>
 
110
 
111
  ``` cpp
112
  template<class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
113
  ```
114
 
115
+ *Constraints:* `is_same_v<U, Iterator>` is `false` and `const U&` models
116
+ `convertible_to<Iterator>`.
117
+
118
  *Effects:* Initializes `current` with `u.current`.
119
 
120
  ``` cpp
121
  template<class U>
122
  constexpr reverse_iterator&
123
  operator=(const reverse_iterator<U>& u);
124
  ```
125
 
126
+ *Constraints:* `is_same_v<U, Iterator>` is `false`, `const U&` models
127
+ `convertible_to<Iterator>`, and `assignable_from<Iterator&, const U&>`
128
+ is modeled.
129
+
130
+ *Effects:* Assigns `u.current` to `current`.
131
 
132
  *Returns:* `*this`.
133
 
134
  #### Conversion <a id="reverse.iter.conv">[[reverse.iter.conv]]</a>
135
 
136
  ``` cpp
137
+ constexpr Iterator base() const;
138
  ```
139
 
140
  *Returns:* `current`.
141
 
142
  #### Element access <a id="reverse.iter.elem">[[reverse.iter.elem]]</a>
 
186
 
187
  ``` cpp
188
  constexpr reverse_iterator& operator++();
189
  ```
190
 
191
+ *Effects:* As if by: `current;`
192
 
193
  *Returns:* `*this`.
194
 
195
  ``` cpp
196
  constexpr reverse_iterator operator++(int);
 
338
  *Returns:* `y.base() - x.base()`.
339
 
340
  ``` cpp
341
  template<class Iterator>
342
  constexpr reverse_iterator<Iterator> operator+(
343
+ iter_difference_t<Iterator> n,
344
  const reverse_iterator<Iterator>& x);
345
  ```
346
 
347
  *Returns:* `reverse_iterator<Iterator>(x.base() - n)`.
348
 
 
356
  ``` cpp
357
  auto tmp = i.base();
358
  return ranges::iter_move(--tmp);
359
  ```
360
 
361
+ *Remarks:* The exception specification is equivalent to:
362
 
363
  ``` cpp
364
  is_nothrow_copy_constructible_v<Iterator> &&
365
  noexcept(ranges::iter_move(--declval<Iterator&>()))
366
  ```
 
378
  auto xtmp = x.base();
379
  auto ytmp = y.base();
380
  ranges::iter_swap(--xtmp, --ytmp);
381
  ```
382
 
383
+ *Remarks:* The exception specification is equivalent to:
384
 
385
  ``` cpp
386
  is_nothrow_copy_constructible_v<Iterator> &&
387
  is_nothrow_copy_constructible_v<Iterator2> &&
388
  noexcept(ranges::iter_swap(--declval<Iterator&>(), --declval<Iterator2&>()))
 
395
 
396
  *Returns:* `reverse_iterator<Iterator>(i)`.
397
 
398
  ### Insert iterators <a id="insert.iterators">[[insert.iterators]]</a>
399
 
400
+ #### General <a id="insert.iterators.general">[[insert.iterators.general]]</a>
401
+
402
  To make it possible to deal with insertion in the same way as writing
403
  into an array, a special kind of iterator adaptors, called *insert
404
  iterators*, are provided in the library. With regular iterator classes,
405
 
406
  ``` cpp
 
433
  ``` cpp
434
  namespace std {
435
  template<class Container>
436
  class back_insert_iterator {
437
  protected:
438
+ Container* container;
439
 
440
  public:
441
  using iterator_category = output_iterator_tag;
442
  using value_type = void;
443
  using difference_type = ptrdiff_t;
444
  using pointer = void;
445
  using reference = void;
446
  using container_type = Container;
447
 
 
448
  constexpr explicit back_insert_iterator(Container& x);
449
  constexpr back_insert_iterator& operator=(const typename Container::value_type& value);
450
  constexpr back_insert_iterator& operator=(typename Container::value_type&& value);
451
 
452
  constexpr back_insert_iterator& operator*();
 
507
  ``` cpp
508
  namespace std {
509
  template<class Container>
510
  class front_insert_iterator {
511
  protected:
512
+ Container* container;
513
 
514
  public:
515
  using iterator_category = output_iterator_tag;
516
  using value_type = void;
517
  using difference_type = ptrdiff_t;
518
  using pointer = void;
519
  using reference = void;
520
  using container_type = Container;
521
 
 
522
  constexpr explicit front_insert_iterator(Container& x);
523
  constexpr front_insert_iterator& operator=(const typename Container::value_type& value);
524
  constexpr front_insert_iterator& operator=(typename Container::value_type&& value);
525
 
526
  constexpr front_insert_iterator& operator*();
 
581
  ``` cpp
582
  namespace std {
583
  template<class Container>
584
  class insert_iterator {
585
  protected:
586
+ Container* container;
587
+ ranges::iterator_t<Container> iter;
588
 
589
  public:
590
  using iterator_category = output_iterator_tag;
591
  using value_type = void;
592
  using difference_type = ptrdiff_t;
593
  using pointer = void;
594
  using reference = void;
595
  using container_type = Container;
596
 
 
597
  constexpr insert_iterator(Container& x, ranges::iterator_t<Container> i);
598
  constexpr insert_iterator& operator=(const typename Container::value_type& value);
599
  constexpr insert_iterator& operator=(typename Container::value_type&& value);
600
 
601
  constexpr insert_iterator& operator*();
 
661
  inserter(Container& x, ranges::iterator_t<Container> i);
662
  ```
663
 
664
  *Returns:* `insert_iterator<Container>(x, i)`.
665
 
666
+ ### Constant iterators and sentinels <a id="const.iterators">[[const.iterators]]</a>
667
+
668
+ #### General <a id="const.iterators.general">[[const.iterators.general]]</a>
669
+
670
+ Class template `basic_const_iterator` is an iterator adaptor with the
671
+ same behavior as the underlying iterator except that its indirection
672
+ operator implicitly converts the value returned by the underlying
673
+ iterator’s indirection operator to a type such that the adapted iterator
674
+ is a constant iterator [[iterator.requirements]]. Some generic
675
+ algorithms can be called with constant iterators to avoid mutation.
676
+
677
+ Specializations of `basic_const_iterator` are constant iterators.
678
+
679
+ #### Alias templates <a id="const.iterators.alias">[[const.iterators.alias]]</a>
680
+
681
+ ``` cpp
682
+ template<indirectly_readable It>
683
+ using iter_const_reference_t =
684
+ common_reference_t<const iter_value_t<It>&&, iter_reference_t<It>>;
685
+
686
+ template<class It>
687
+ concept constant-iterator = // exposition only
688
+ input_iterator<It> && same_as<iter_const_reference_t<It>, iter_reference_t<It>>;
689
+
690
+ template<input_iterator I>
691
+ using const_iterator = see below;
692
+ ```
693
+
694
+ *Result:* If `I` models `constant-iterator`, `I`. Otherwise,
695
+ `basic_const_iterator<I>`.
696
+
697
+ ``` cpp
698
+ template<semiregular S>
699
+ using const_sentinel = see below;
700
+ ```
701
+
702
+ *Result:* If `S` models `input_iterator`, `const_iterator<S>`.
703
+ Otherwise, `S`.
704
+
705
+ #### Class template `basic_const_iterator` <a id="const.iterators.iterator">[[const.iterators.iterator]]</a>
706
+
707
+ ``` cpp
708
+ namespace std {
709
+ template<class I>
710
+ concept not-a-const-iterator = see below; // exposition only
711
+
712
+ template<indirectly_readable I>
713
+ using iter-const-rvalue-reference-t = // exposition only
714
+ common_reference_t<const iter_value_t<I>&&, iter_rvalue_reference_t<I>>;
715
+
716
+ template<input_iterator Iterator>
717
+ class basic_const_iterator {
718
+ Iterator current_ = Iterator(); // exposition only
719
+ using reference = iter_const_reference_t<Iterator>; // exposition only
720
+ using rvalue-reference = // exposition only
721
+ iter-const-rvalue-reference-t<Iterator>;
722
+
723
+ public:
724
+ using iterator_concept = see below;
725
+ using iterator_category = see below; // not always present
726
+ using value_type = iter_value_t<Iterator>;
727
+ using difference_type = iter_difference_t<Iterator>;
728
+
729
+ basic_const_iterator() requires default_initializable<Iterator> = default;
730
+ constexpr basic_const_iterator(Iterator current);
731
+ template<convertible_to<Iterator> U>
732
+ constexpr basic_const_iterator(basic_const_iterator<U> current);
733
+ template<different-from<basic_const_iterator> T>
734
+ requires convertible_to<T, Iterator>
735
+ constexpr basic_const_iterator(T&& current);
736
+
737
+ constexpr const Iterator& base() const & noexcept;
738
+ constexpr Iterator base() &&;
739
+
740
+ constexpr reference operator*() const;
741
+ constexpr const auto* operator->() const
742
+ requires is_lvalue_reference_v<iter_reference_t<Iterator>> &&
743
+ same_as<remove_cvref_t<iter_reference_t<Iterator>>, value_type>;
744
+
745
+ constexpr basic_const_iterator& operator++();
746
+ constexpr void operator++(int);
747
+ constexpr basic_const_iterator operator++(int) requires forward_iterator<Iterator>;
748
+
749
+ constexpr basic_const_iterator& operator--() requires bidirectional_iterator<Iterator>;
750
+ constexpr basic_const_iterator operator--(int) requires bidirectional_iterator<Iterator>;
751
+
752
+ constexpr basic_const_iterator& operator+=(difference_type n)
753
+ requires random_access_iterator<Iterator>;
754
+ constexpr basic_const_iterator& operator-=(difference_type n)
755
+ requires random_access_iterator<Iterator>;
756
+
757
+ constexpr reference operator[](difference_type n) const
758
+ requires random_access_iterator<Iterator>;
759
+
760
+ template<sentinel_for<Iterator> S>
761
+ constexpr bool operator==(const S& s) const;
762
+
763
+ constexpr bool operator<(const basic_const_iterator& y) const
764
+ requires random_access_iterator<Iterator>;
765
+ constexpr bool operator>(const basic_const_iterator& y) const
766
+ requires random_access_iterator<Iterator>;
767
+ constexpr bool operator<=(const basic_const_iterator& y) const
768
+ requires random_access_iterator<Iterator>;
769
+ constexpr bool operator>=(const basic_const_iterator& y) const
770
+ requires random_access_iterator<Iterator>;
771
+ constexpr auto operator<=>(const basic_const_iterator& y) const
772
+ requires random_access_iterator<Iterator> && three_way_comparable<Iterator>;
773
+
774
+ template<different-from<basic_const_iterator> I>
775
+ constexpr bool operator<(const I& y) const
776
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
777
+ template<different-from<basic_const_iterator> I>
778
+ constexpr bool operator>(const I& y) const
779
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
780
+ template<different-from<basic_const_iterator> I>
781
+ constexpr bool operator<=(const I& y) const
782
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
783
+ template<different-from<basic_const_iterator> I>
784
+ constexpr bool operator>=(const I& y) const
785
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
786
+ template<different-from<basic_const_iterator> I>
787
+ constexpr auto operator<=>(const I& y) const
788
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I> &&
789
+ three_way_comparable_with<Iterator, I>;
790
+ template<not-a-const-iterator I>
791
+ friend constexpr bool operator<(const I& x, const basic_const_iterator& y)
792
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
793
+ template<not-a-const-iterator I>
794
+ friend constexpr bool operator>(const I& x, const basic_const_iterator& y)
795
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
796
+ template<not-a-const-iterator I>
797
+ friend constexpr bool operator<=(const I& x, const basic_const_iterator& y)
798
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
799
+ template<not-a-const-iterator I>
800
+ friend constexpr bool operator>=(const I& x, const basic_const_iterator& y)
801
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
802
+
803
+ friend constexpr basic_const_iterator operator+(const basic_const_iterator& i,
804
+ difference_type n)
805
+ requires random_access_iterator<Iterator>;
806
+ friend constexpr basic_const_iterator operator+(difference_type n,
807
+ const basic_const_iterator& i)
808
+ requires random_access_iterator<Iterator>;
809
+ friend constexpr basic_const_iterator operator-(const basic_const_iterator& i,
810
+ difference_type n)
811
+ requires random_access_iterator<Iterator>;
812
+ template<sized_sentinel_for<Iterator> S>
813
+ constexpr difference_type operator-(const S& y) const;
814
+ template<not-a-const-iterator S>
815
+ requires sized_sentinel_for<S, Iterator>
816
+ friend constexpr difference_type operator-(const S& x, const basic_const_iterator& y);
817
+ friend constexpr rvalue-reference iter_move(const basic_const_iterator& i)
818
+ noexcept(noexcept(static_cast<rvalue-reference>(ranges::iter_move(i.current_))))
819
+ {
820
+ return static_cast<rvalue-reference>(ranges::iter_move(i.current_));
821
+ }
822
+ };
823
+ }
824
+ ```
825
+
826
+ Given some type `I`, the concept *not-a-const-iterator* is defined as
827
+ `false` if `I` is a specialization of `basic_const_iterator` and `true`
828
+ otherwise.
829
+
830
+ #### Member types <a id="const.iterators.types">[[const.iterators.types]]</a>
831
+
832
+ `basic_const_iterator<Iterator>::iterator_concept` is defined as
833
+ follows:
834
+
835
+ - If `Iterator` models `contiguous_iterator`, then `iterator_concept`
836
+ denotes `contiguous_iterator_tag`.
837
+ - Otherwise, if `Iterator` models `random_access_iterator`, then
838
+ `iterator_concept` denotes `random_access_iterator_tag`.
839
+ - Otherwise, if `Iterator` models `bidirectional_iterator`, then
840
+ `iterator_concept` denotes `bidirectional_iterator_tag`.
841
+ - Otherwise, if `Iterator` models `forward_iterator`, then
842
+ `iterator_concept` denotes `forward_iterator_tag`.
843
+ - Otherwise, `iterator_concept` denotes `input_iterator_tag`.
844
+
845
+ The member *typedef-name* `iterator_category` is defined if and only if
846
+ `Iterator` models `forward_iterator`. In that case,
847
+ `basic_const_iterator<Iterator>::iterator_category` denotes the type
848
+ `iterator_traits<{}Iterator>::iterator_category`.
849
+
850
+ #### Operations <a id="const.iterators.ops">[[const.iterators.ops]]</a>
851
+
852
+ ``` cpp
853
+ constexpr basic_const_iterator(Iterator current);
854
+ ```
855
+
856
+ *Effects:* Initializes *current\_* with `std::move(current)`.
857
+
858
+ ``` cpp
859
+ template<convertible_to<Iterator> U>
860
+ constexpr basic_const_iterator(basic_const_iterator<U> current);
861
+ ```
862
+
863
+ *Effects:* Initializes *current\_* with
864
+ `std::move(current.`*`current_`*`)`.
865
+
866
+ ``` cpp
867
+ template<different-from<basic_const_iterator> T>
868
+ requires convertible_to<T, Iterator>
869
+ constexpr basic_const_iterator(T&& current);
870
+ ```
871
+
872
+ *Effects:* Initializes *current\_* with `std::forward<T>(current)`.
873
+
874
+ ``` cpp
875
+ constexpr const Iterator& base() const & noexcept;
876
+ ```
877
+
878
+ *Effects:* Equivalent to: `return `*`current_`*`;`
879
+
880
+ ``` cpp
881
+ constexpr Iterator base() &&;
882
+ ```
883
+
884
+ *Effects:* Equivalent to: `return std::move(`*`current_`*`);`
885
+
886
+ ``` cpp
887
+ constexpr reference operator*() const;
888
+ ```
889
+
890
+ *Effects:* Equivalent to:
891
+ `return static_cast<`*`reference`*`>(*`*`current_`*`);`
892
+
893
+ ``` cpp
894
+ constexpr const auto* operator->() const
895
+ requires is_lvalue_reference_v<iter_reference_t<Iterator>> &&
896
+ same_as<remove_cvref_t<iter_reference_t<Iterator>>, value_type>;
897
+ ```
898
+
899
+ *Returns:* If `Iterator` models `contiguous_iterator`,
900
+ `to_address(`*`current_`*`)`; otherwise, `addressof(*`*`current_`*`)`.
901
+
902
+ ``` cpp
903
+ constexpr basic_const_iterator& operator++();
904
+ ```
905
+
906
+ *Effects:* Equivalent to:
907
+
908
+ ``` cpp
909
+ ++current_;
910
+ return *this;
911
+ ```
912
+
913
+ ``` cpp
914
+ constexpr void operator++(int);
915
+ ```
916
+
917
+ *Effects:* Equivalent to: `++`*`current_`*`;`
918
+
919
+ ``` cpp
920
+ constexpr basic_const_iterator operator++(int) requires forward_iterator<Iterator>;
921
+ ```
922
+
923
+ *Effects:* Equivalent to:
924
+
925
+ ``` cpp
926
+ auto tmp = *this;
927
+ ++*this;
928
+ return tmp;
929
+ ```
930
+
931
+ ``` cpp
932
+ constexpr basic_const_iterator& operator--() requires bidirectional_iterator<Iterator>;
933
+ ```
934
+
935
+ *Effects:* Equivalent to:
936
+
937
+ ``` cpp
938
+ --current_;
939
+ return *this;
940
+ ```
941
+
942
+ ``` cpp
943
+ constexpr basic_const_iterator operator--(int) requires bidirectional_iterator<Iterator>;
944
+ ```
945
+
946
+ *Effects:* Equivalent to:
947
+
948
+ ``` cpp
949
+ auto tmp = *this;
950
+ --*this;
951
+ return tmp;
952
+ ```
953
+
954
+ ``` cpp
955
+ constexpr basic_const_iterator& operator+=(difference_type n)
956
+ requires random_access_iterator<Iterator>;
957
+ constexpr basic_const_iterator& operator-=(difference_type n)
958
+ requires random_access_iterator<Iterator>;
959
+ ```
960
+
961
+ Let *`op`* be the operator.
962
+
963
+ *Effects:* Equivalent to:
964
+
965
+ ``` cpp
966
+ current_ op n;
967
+ return *this;
968
+ ```
969
+
970
+ ``` cpp
971
+ constexpr reference operator[](difference_type n) const requires random_access_iterator<Iterator>
972
+ ```
973
+
974
+ *Effects:* Equivalent to:
975
+ `return static_cast<`*`reference`*`>(`*`current_`*`[n]);`
976
+
977
+ ``` cpp
978
+ template<sentinel_for<Iterator> S>
979
+ constexpr bool operator==(const S& s) const;
980
+ ```
981
+
982
+ *Effects:* Equivalent to: `return `*`current_`*` == s;`
983
+
984
+ ``` cpp
985
+ constexpr bool operator<(const basic_const_iterator& y) const
986
+ requires random_access_iterator<Iterator>;
987
+ constexpr bool operator>(const basic_const_iterator& y) const
988
+ requires random_access_iterator<Iterator>;
989
+ constexpr bool operator<=(const basic_const_iterator& y) const
990
+ requires random_access_iterator<Iterator>;
991
+ constexpr bool operator>=(const basic_const_iterator& y) const
992
+ requires random_access_iterator<Iterator>;
993
+ constexpr auto operator<=>(const basic_const_iterator& y) const
994
+ requires random_access_iterator<Iterator> && three_way_comparable<Iterator>;
995
+ ```
996
+
997
+ Let *`op`* be the operator.
998
+
999
+ *Effects:* Equivalent to:
1000
+ `return `*`current_`*` `*`op`*` `*`y.current_`*`;`
1001
+
1002
+ ``` cpp
1003
+ template<different-from<basic_const_iterator> I>
1004
+ constexpr bool operator<(const I& y) const
1005
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
1006
+ template<different-from<basic_const_iterator> I>
1007
+ constexpr bool operator>(const I& y) const
1008
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
1009
+ template<different-from<basic_const_iterator> I>
1010
+ constexpr bool operator<=(const I& y) const
1011
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
1012
+ template<different-from<basic_const_iterator> I>
1013
+ constexpr bool operator>=(const I& y) const
1014
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
1015
+ template<different-from<basic_const_iterator> I>
1016
+ constexpr auto operator<=>(const I& y) const
1017
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I> &&
1018
+ three_way_comparable_with<Iterator, I>;
1019
+ ```
1020
+
1021
+ Let *`op`* be the operator.
1022
+
1023
+ *Effects:* Equivalent to: `return `*`current_`*` `*`op`*` y;`
1024
+
1025
+ ``` cpp
1026
+ template<not-a-const-iterator I>
1027
+ friend constexpr bool operator<(const I& x, const basic_const_iterator& y)
1028
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
1029
+ template<not-a-const-iterator I>
1030
+ friend constexpr bool operator>(const I& x, const basic_const_iterator& y)
1031
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
1032
+ template<not-a-const-iterator I>
1033
+ friend constexpr bool operator<=(const I& x, const basic_const_iterator& y)
1034
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
1035
+ template<not-a-const-iterator I>
1036
+ friend constexpr bool operator>=(const I& x, const basic_const_iterator& y)
1037
+ requires random_access_iterator<Iterator> && totally_ordered_with<Iterator, I>;
1038
+ ```
1039
+
1040
+ Let *`op`* be the operator.
1041
+
1042
+ *Returns:* Equivalent to: `return x `*`op`*` y.`*`current_`*`;`
1043
+
1044
+ ``` cpp
1045
+ friend constexpr basic_const_iterator operator+(const basic_const_iterator& i, difference_type n)
1046
+ requires random_access_iterator<Iterator>;
1047
+ friend constexpr basic_const_iterator operator+(difference_type n, const basic_const_iterator& i)
1048
+ requires random_access_iterator<Iterator>;
1049
+ ```
1050
+
1051
+ *Effects:* Equivalent to:
1052
+ `return basic_const_iterator(i.`*`current_`*` + n);`
1053
+
1054
+ ``` cpp
1055
+ friend constexpr basic_const_iterator operator-(const basic_const_iterator& i, difference_type n)
1056
+ requires random_access_iterator<Iterator>;
1057
+ ```
1058
+
1059
+ *Effects:* Equivalent to:
1060
+ `return basic_const_iterator(i.`*`current_`*` - n);`
1061
+
1062
+ ``` cpp
1063
+ template<sized_sentinel_for<Iterator> S>
1064
+ constexpr difference_type operator-(const S& y) const;
1065
+ ```
1066
+
1067
+ *Effects:* Equivalent to: `return `*`current_`*` - y;`
1068
+
1069
+ ``` cpp
1070
+ template<not-a-const-iterator S>
1071
+ requires sized_sentinel_for<S, Iterator>
1072
+ friend constexpr difference_type operator-(const S& x, const basic_const_iterator& y);
1073
+ ```
1074
+
1075
+ *Effects:* Equivalent to: `return x - y.`*`current_`*`;`
1076
+
1077
  ### Move iterators and sentinels <a id="move.iterators">[[move.iterators]]</a>
1078
 
1079
+ #### General <a id="move.iterators.general">[[move.iterators.general]]</a>
1080
+
1081
  Class template `move_iterator` is an iterator adaptor with the same
1082
  behavior as the underlying iterator except that its indirection operator
1083
  implicitly converts the value returned by the underlying iterator’s
1084
  indirection operator to an rvalue. Some generic algorithms can be called
1085
  with move iterators to replace copying with moving.
 
1102
  namespace std {
1103
  template<class Iterator>
1104
  class move_iterator {
1105
  public:
1106
  using iterator_type = Iterator;
1107
+ using iterator_concept = see below;
1108
+ using iterator_category = see below; // not always present
1109
  using value_type = iter_value_t<Iterator>;
1110
  using difference_type = iter_difference_t<Iterator>;
1111
  using pointer = Iterator;
1112
  using reference = iter_rvalue_reference_t<Iterator>;
1113
 
1114
  constexpr move_iterator();
1115
  constexpr explicit move_iterator(Iterator i);
1116
  template<class U> constexpr move_iterator(const move_iterator<U>& u);
1117
  template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
1118
 
1119
+ constexpr const Iterator& base() const & noexcept;
1120
+ constexpr Iterator base() &&;
1121
  constexpr reference operator*() const;
1122
 
1123
  constexpr move_iterator& operator++();
1124
  constexpr auto operator++(int);
1125
  constexpr move_iterator& operator--();
 
1152
  Iterator current; // exposition only
1153
  };
1154
  }
1155
  ```
1156
 
1157
+ The member *typedef-name* `iterator_concept` is defined as follows:
1158
+
1159
+ - If `Iterator` models `random_access_iterator`, then `iterator_concept`
1160
+ denotes `random_access_iterator_tag`.
1161
+ - Otherwise, if `Iterator` models `bidirectional_iterator`, then
1162
+ `iterator_concept` denotes `bidirectional_iterator_tag`.
1163
+ - Otherwise, if `Iterator` models `forward_iterator`, then
1164
+ `iterator_concept` denotes `forward_iterator_tag`.
1165
+ - Otherwise, `iterator_concept` denotes `input_iterator_tag`.
1166
+
1167
+ The member *typedef-name* `iterator_category` is defined if and only if
1168
+ the *qualified-id* `iterator_traits<Iterator>::iterator_category` is
1169
+ valid and denotes a type. In that case, `iterator_category` denotes
1170
 
1171
  - `random_access_iterator_tag` if the type
1172
  `iterator_traits<{}Iterator>::iterator_category` models
1173
  `derived_from<random_access_iterator_tag>`, and
1174
  - `iterator_traits<{}Iterator>::iterator_category` otherwise.
 
1191
 
1192
  ``` cpp
1193
  constexpr move_iterator();
1194
  ```
1195
 
1196
+ *Effects:* Value-initializes `current`.
 
 
 
1197
 
1198
  ``` cpp
1199
  constexpr explicit move_iterator(Iterator i);
1200
  ```
1201
 
1202
+ *Effects:* Initializes `current` with `std::move(i)`.
 
1203
 
1204
  ``` cpp
1205
  template<class U> constexpr move_iterator(const move_iterator<U>& u);
1206
  ```
1207
 
1208
+ *Constraints:* `is_same_v<U, Iterator>` is `false` and `const U&` models
1209
+ `convertible_to<Iterator>`.
1210
 
1211
+ *Effects:* Initializes `current` with `u.current`.
 
1212
 
1213
  ``` cpp
1214
  template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
1215
  ```
1216
 
1217
+ *Constraints:* `is_same_v<U, Iterator>` is `false`, `const U&` models
1218
+ `convertible_to<Iterator>`, and `assignable_from<Iterator&, const U&>`
1219
+ is modeled.
1220
 
1221
+ *Effects:* Assigns `u.current` to `current`.
1222
+
1223
+ *Returns:* `*this`.
1224
 
1225
  #### Conversion <a id="move.iter.op.conv">[[move.iter.op.conv]]</a>
1226
 
1227
  ``` cpp
1228
+ constexpr const Iterator& base() const & noexcept;
1229
  ```
1230
 
 
 
 
 
1231
  *Returns:* `current`.
1232
 
1233
  ``` cpp
1234
  constexpr Iterator base() &&;
1235
  ```
 
1246
 
1247
  ``` cpp
1248
  constexpr reference operator[](difference_type n) const;
1249
  ```
1250
 
1251
+ *Effects:* Equivalent to: `return ranges::iter_move(current + n);`
1252
 
1253
  #### Navigation <a id="move.iter.nav">[[move.iter.nav]]</a>
1254
 
1255
  ``` cpp
1256
  constexpr move_iterator& operator++();
 
1276
 
1277
  ``` cpp
1278
  constexpr move_iterator& operator--();
1279
  ```
1280
 
1281
+ *Effects:* As if by `current`.
1282
 
1283
  *Returns:* `*this`.
1284
 
1285
  ``` cpp
1286
  constexpr move_iterator operator--(int);
 
1389
 
1390
  #### Non-member functions <a id="move.iter.nonmember">[[move.iter.nonmember]]</a>
1391
 
1392
  ``` cpp
1393
  template<class Iterator1, class Iterator2>
1394
+ constexpr auto operator-(
1395
+ const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y)
1396
  -> decltype(x.base() - y.base());
1397
  template<sized_sentinel_for<Iterator> S>
1398
  friend constexpr iter_difference_t<Iterator>
1399
  operator-(const move_sentinel<S>& x, const move_iterator& y);
1400
  template<sized_sentinel_for<Iterator> S>
 
1408
  template<class Iterator>
1409
  constexpr move_iterator<Iterator>
1410
  operator+(iter_difference_t<Iterator> n, const move_iterator<Iterator>& x);
1411
  ```
1412
 
1413
+ *Constraints:* `x.base() + n` is well-formed and has type `Iterator`.
1414
 
1415
  *Returns:* `x + n`.
1416
 
1417
  ``` cpp
1418
  friend constexpr iter_rvalue_reference_t<Iterator>
 
1442
 
1443
  Class template `move_sentinel` is a sentinel adaptor useful for denoting
1444
  ranges together with `move_iterator`. When an input iterator type `I`
1445
  and sentinel type `S` model `sentinel_for<S, I>`, `move_sentinel<S>` and
1446
  `move_iterator<I>` model
1447
+ `sentinel_for<move_sentinel<S>, move_iterator<I>>` as well.
1448
 
1449
  [*Example 1*:
1450
 
1451
  A `move_if` algorithm is easily implemented with `copy_if` using
1452
  `move_iterator` and `move_sentinel`:
 
1454
  ``` cpp
1455
  template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
1456
  indirect_unary_predicate<I> Pred>
1457
  requires indirectly_movable<I, O>
1458
  void move_if(I first, S last, O out, Pred pred) {
1459
+ ranges::copy_if(move_iterator<I>{std::move(first)}, move_sentinel<S>{last},
1460
+ std::move(out), pred);
1461
  }
1462
  ```
1463
 
1464
  — *end example*]
1465
 
 
1476
  template<class S2>
1477
  requires assignable_from<S&, const S2&>
1478
  constexpr move_sentinel& operator=(const move_sentinel<S2>& s);
1479
 
1480
  constexpr S base() const;
1481
+
1482
  private:
1483
  S last; // exposition only
1484
  };
1485
  }
1486
  ```
 
1556
  namespace std {
1557
  template<input_or_output_iterator I, sentinel_for<I> S>
1558
  requires (!same_as<I, S> && copyable<I>)
1559
  class common_iterator {
1560
  public:
1561
+ constexpr common_iterator() requires default_initializable<I> = default;
1562
  constexpr common_iterator(I i);
1563
  constexpr common_iterator(S s);
1564
  template<class I2, class S2>
1565
  requires convertible_to<const I2&, I> && convertible_to<const S2&, S>
1566
  constexpr common_iterator(const common_iterator<I2, S2>& x);
1567
 
1568
  template<class I2, class S2>
1569
  requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
1570
  assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
1571
+ constexpr common_iterator& operator=(const common_iterator<I2, S2>& x);
1572
 
1573
+ constexpr decltype(auto) operator*();
1574
+ constexpr decltype(auto) operator*() const
1575
  requires dereferenceable<const I>;
1576
+ constexpr auto operator->() const
1577
  requires see below;
1578
 
1579
+ constexpr common_iterator& operator++();
1580
+ constexpr decltype(auto) operator++(int);
1581
 
1582
  template<class I2, sentinel_for<I> S2>
1583
  requires sentinel_for<S, I2>
1584
+ friend constexpr bool operator==(
1585
  const common_iterator& x, const common_iterator<I2, S2>& y);
1586
  template<class I2, sentinel_for<I> S2>
1587
  requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
1588
+ friend constexpr bool operator==(
1589
  const common_iterator& x, const common_iterator<I2, S2>& y);
1590
 
1591
  template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
1592
  requires sized_sentinel_for<S, I2>
1593
+ friend constexpr iter_difference_t<I2> operator-(
1594
  const common_iterator& x, const common_iterator<I2, S2>& y);
1595
 
1596
+ friend constexpr iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
1597
  noexcept(noexcept(ranges::iter_move(declval<const I&>())))
1598
  requires input_iterator<I>;
1599
  template<indirectly_swappable<I> I2, class S2>
1600
+ friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
1601
  noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
1602
 
1603
  private:
1604
  variant<I, S> v_; // exposition only
1605
  };
 
1626
  The nested *typedef-name*s of the specialization of `iterator_traits`
1627
  for `common_iterator<I, S>` are defined as follows.
1628
 
1629
  - `iterator_concept` denotes `forward_iterator_tag` if `I` models
1630
  `forward_iterator`; otherwise it denotes `input_iterator_tag`.
1631
+ - `iterator_category` denotes `forward_iterator_tag` if the
1632
+ *qualified-id* `iterator_traits<I>::iterator_category` is valid and
1633
+ denotes a type that models `derived_from<forward_iterator_tag>`;
1634
+ otherwise it denotes `input_iterator_tag`.
1635
+ - Let `a` denote an lvalue of type `const common_iterator<I, S>`. If the
1636
+ expression `a.operator->()` is well-formed, then `pointer` denotes
1637
+ `decltype(a.operator->())`. Otherwise, `pointer` denotes `void`.
1638
 
1639
  #### Constructors and conversions <a id="common.iter.const">[[common.iter.const]]</a>
1640
 
1641
  ``` cpp
1642
  constexpr common_iterator(I i);
 
1665
 
1666
  ``` cpp
1667
  template<class I2, class S2>
1668
  requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
1669
  assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
1670
+ constexpr common_iterator& operator=(const common_iterator<I2, S2>& x);
1671
  ```
1672
 
1673
  *Preconditions:* `x.v_.valueless_by_exception()` is `false`.
1674
 
1675
  *Effects:* Equivalent to:
 
1682
  *Returns:* `*this`
1683
 
1684
  #### Accessors <a id="common.iter.access">[[common.iter.access]]</a>
1685
 
1686
  ``` cpp
1687
+ constexpr decltype(auto) operator*();
1688
+ constexpr decltype(auto) operator*() const
1689
  requires dereferenceable<const I>;
1690
  ```
1691
 
1692
+ *Preconditions:* `holds_alternative<I>(v_)` is `true`.
1693
 
1694
  *Effects:* Equivalent to: `return *get<I>(v_);`
1695
 
1696
  ``` cpp
1697
+ constexpr auto operator->() const
1698
  requires see below;
1699
  ```
1700
 
1701
+ The expression in the *requires-clause* is equivalent to:
1702
 
1703
  ``` cpp
1704
  indirectly_readable<const I> &&
1705
  (requires(const I& i) { i.operator->(); } ||
1706
  is_reference_v<iter_reference_t<I>> ||
1707
  constructible_from<iter_value_t<I>, iter_reference_t<I>>)
1708
  ```
1709
 
1710
+ *Preconditions:* `holds_alternative<I>(v_)` is `true`.
1711
 
1712
  *Effects:*
1713
 
1714
  - If `I` is a pointer type or if the expression
1715
  `get<I>(v_).operator->()` is well-formed, equivalent to:
 
1723
  - Otherwise, equivalent to: `return `*`proxy`*`(*get<I>(v_));` where
1724
  *proxy* is the exposition-only class:
1725
  ``` cpp
1726
  class proxy {
1727
  iter_value_t<I> keep_;
1728
+ constexpr proxy(iter_reference_t<I>&& x)
1729
  : keep_(std::move(x)) {}
1730
  public:
1731
+ constexpr const iter_value_t<I>* operator->() const noexcept {
1732
  return addressof(keep_);
1733
  }
1734
  };
1735
  ```
1736
 
1737
  #### Navigation <a id="common.iter.nav">[[common.iter.nav]]</a>
1738
 
1739
  ``` cpp
1740
+ constexpr common_iterator& operator++();
1741
  ```
1742
 
1743
+ *Preconditions:* `holds_alternative<I>(v_)` is `true`.
1744
 
1745
  *Effects:* Equivalent to `++get<I>(v_)`.
1746
 
1747
  *Returns:* `*this`.
1748
 
1749
  ``` cpp
1750
+ constexpr decltype(auto) operator++(int);
1751
  ```
1752
 
1753
+ *Preconditions:* `holds_alternative<I>(v_)` is `true`.
1754
 
1755
  *Effects:* If `I` models `forward_iterator`, equivalent to:
1756
 
1757
  ``` cpp
1758
  common_iterator tmp = *this;
1759
  ++*this;
1760
  return tmp;
1761
  ```
1762
 
1763
+ Otherwise, if `requires(I& i) { { *i++ } -> `*`can-reference`*`; }` is
1764
+ `true` or
1765
+
1766
+ ``` cpp
1767
+ indirectly_readable<I> && constructible_from<iter_value_t<I>, iter_reference_t<I>> &&
1768
+ move_constructible<iter_value_t<I>>
1769
+ ```
1770
+
1771
+ is `false`, equivalent to:
1772
+
1773
+ ``` cpp
1774
+ return get<I>(v_)++;
1775
+ ```
1776
+
1777
+ Otherwise, equivalent to:
1778
+
1779
+ ``` cpp
1780
+ postfix-proxy p(**this);
1781
+ ++*this;
1782
+ return p;
1783
+ ```
1784
+
1785
+ where *postfix-proxy* is the exposition-only class:
1786
+
1787
+ ``` cpp
1788
+ class postfix-proxy {
1789
+ iter_value_t<I> keep_;
1790
+ constexpr postfix-proxy(iter_reference_t<I>&& x)
1791
+ : keep_(std::forward<iter_reference_t<I>>(x)) {}
1792
+ public:
1793
+ constexpr const iter_value_t<I>& operator*() const noexcept {
1794
+ return keep_;
1795
+ }
1796
+ };
1797
+ ```
1798
 
1799
  #### Comparisons <a id="common.iter.cmp">[[common.iter.cmp]]</a>
1800
 
1801
  ``` cpp
1802
  template<class I2, sentinel_for<I> S2>
1803
  requires sentinel_for<S, I2>
1804
+ friend constexpr bool operator==(
1805
  const common_iterator& x, const common_iterator<I2, S2>& y);
1806
  ```
1807
 
1808
  *Preconditions:* `x.v_.valueless_by_exception()` and
1809
  `y.v_.valueless_by_exception()` are each `false`.
 
1813
  `y.v_.index()`.
1814
 
1815
  ``` cpp
1816
  template<class I2, sentinel_for<I> S2>
1817
  requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
1818
+ friend constexpr bool operator==(
1819
  const common_iterator& x, const common_iterator<I2, S2>& y);
1820
  ```
1821
 
1822
  *Preconditions:* `x.v_.valueless_by_exception()` and
1823
  `y.v_.valueless_by_exception()` are each `false`.
 
1827
  `y.v_.index()`.
1828
 
1829
  ``` cpp
1830
  template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
1831
  requires sized_sentinel_for<S, I2>
1832
+ friend constexpr iter_difference_t<I2> operator-(
1833
  const common_iterator& x, const common_iterator<I2, S2>& y);
1834
  ```
1835
 
1836
  *Preconditions:* `x.v_.valueless_by_exception()` and
1837
  `y.v_.valueless_by_exception()` are each `false`.
1838
 
1839
  *Returns:* `0` if i and j are each `1`, and otherwise
1840
  `get<`i`>(x.v_) - get<`j`>(y.v_)`, where i is `x.v_.index()` and j is
1841
  `y.v_.index()`.
1842
 
1843
+ #### Customizations <a id="common.iter.cust">[[common.iter.cust]]</a>
1844
 
1845
  ``` cpp
1846
+ friend constexpr iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
1847
  noexcept(noexcept(ranges::iter_move(declval<const I&>())))
1848
  requires input_iterator<I>;
1849
  ```
1850
 
1851
+ *Preconditions:* `holds_alternative<I>(i.v_)` is `true`.
1852
 
1853
  *Effects:* Equivalent to: `return ranges::iter_move(get<I>(i.v_));`
1854
 
1855
  ``` cpp
1856
  template<indirectly_swappable<I> I2, class S2>
1857
+ friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
1858
  noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
1859
  ```
1860
 
1861
  *Preconditions:* `holds_alternative<I>(x.v_)` and
1862
  `holds_alternative<I2>(y.v_)` are each `true`.
1863
 
1864
  *Effects:* Equivalent to
1865
  `ranges::iter_swap(get<I>(x.v_), get<I2>(y.v_))`.
1866
 
1867
+ ### Default sentinel <a id="default.sentinel">[[default.sentinel]]</a>
1868
 
1869
  ``` cpp
1870
  namespace std {
1871
  struct default_sentinel_t { };
1872
  }
 
1899
 
1900
  — *end example*]
1901
 
1902
  Two values `i1` and `i2` of types `counted_iterator<I1>` and
1903
  `counted_iterator<I2>` refer to elements of the same sequence if and
1904
+ only if there exists some integer n such that
1905
+ `next(i1.base(), i1.count() + n)` and `next(i2.base(), i2.count() + n)`
1906
  refer to the same (possibly past-the-end) element.
1907
 
1908
  ``` cpp
1909
  namespace std {
1910
  template<input_or_output_iterator I>
1911
  class counted_iterator {
1912
  public:
1913
  using iterator_type = I;
1914
+ using value_type = iter_value_t<I>; // present only
1915
+ // if I models indirectly_readable
1916
+ using difference_type = iter_difference_t<I>;
1917
+ using iterator_concept = typename I::iterator_concept; // present only
1918
+ // if the qualified-id I::iterator_concept is valid and denotes a type
1919
+ using iterator_category = typename I::iterator_category; // present only
1920
+ // if the qualified-id I::iterator_category is valid and denotes a type
1921
+ constexpr counted_iterator() requires default_initializable<I> = default;
1922
  constexpr counted_iterator(I x, iter_difference_t<I> n);
1923
  template<class I2>
1924
  requires convertible_to<const I2&, I>
1925
  constexpr counted_iterator(const counted_iterator<I2>& x);
1926
 
1927
  template<class I2>
1928
  requires assignable_from<I&, const I2&>
1929
  constexpr counted_iterator& operator=(const counted_iterator<I2>& x);
1930
 
1931
+ constexpr const I& base() const & noexcept;
1932
  constexpr I base() &&;
1933
  constexpr iter_difference_t<I> count() const noexcept;
1934
  constexpr decltype(auto) operator*();
1935
  constexpr decltype(auto) operator*() const
1936
  requires dereferenceable<const I>;
1937
 
1938
+ constexpr auto operator->() const noexcept
1939
+ requires contiguous_iterator<I>;
1940
+
1941
  constexpr counted_iterator& operator++();
1942
+ constexpr decltype(auto) operator++(int);
1943
  constexpr counted_iterator operator++(int)
1944
  requires forward_iterator<I>;
1945
  constexpr counted_iterator& operator--()
1946
  requires bidirectional_iterator<I>;
1947
  constexpr counted_iterator operator--(int)
 
1990
  private:
1991
  I current = I(); // exposition only
1992
  iter_difference_t<I> length = 0; // exposition only
1993
  };
1994
 
 
 
 
 
 
1995
  template<input_iterator I>
1996
+ requires same_as<ITER_TRAITS(I), iterator_traits<I>> // see [iterator.concepts.general]
1997
  struct iterator_traits<counted_iterator<I>> : iterator_traits<I> {
1998
+ using pointer = conditional_t<contiguous_iterator<I>,
1999
+ add_pointer_t<iter_reference_t<I>>, void>;
2000
  };
2001
  }
2002
  ```
2003
 
2004
  #### Constructors and conversions <a id="counted.iter.const">[[counted.iter.const]]</a>
 
2032
  *Returns:* `*this`.
2033
 
2034
  #### Accessors <a id="counted.iter.access">[[counted.iter.access]]</a>
2035
 
2036
  ``` cpp
2037
+ constexpr const I& base() const & noexcept;
2038
  ```
2039
 
2040
  *Effects:* Equivalent to: `return current;`
2041
 
2042
  ``` cpp
 
2057
  constexpr decltype(auto) operator*();
2058
  constexpr decltype(auto) operator*() const
2059
  requires dereferenceable<const I>;
2060
  ```
2061
 
2062
+ *Preconditions:* `length > 0` is `true`.
2063
+
2064
  *Effects:* Equivalent to: `return *current;`
2065
 
2066
+ ``` cpp
2067
+ constexpr auto operator->() const noexcept
2068
+ requires contiguous_iterator<I>;
2069
+ ```
2070
+
2071
+ *Effects:* Equivalent to: `return to_address(current);`
2072
+
2073
  ``` cpp
2074
  constexpr decltype(auto) operator[](iter_difference_t<I> n) const
2075
  requires random_access_iterator<I>;
2076
  ```
2077
 
 
2094
  --length;
2095
  return *this;
2096
  ```
2097
 
2098
  ``` cpp
2099
+ constexpr decltype(auto) operator++(int);
2100
  ```
2101
 
2102
  *Preconditions:* `length > 0`.
2103
 
2104
  *Effects:* Equivalent to:
 
2268
  iter_move(const counted_iterator& i)
2269
  noexcept(noexcept(ranges::iter_move(i.current)))
2270
  requires input_iterator<I>;
2271
  ```
2272
 
2273
+ *Preconditions:* `i.length > 0` is `true`.
2274
+
2275
  *Effects:* Equivalent to: `return ranges::iter_move(i.current);`
2276
 
2277
  ``` cpp
2278
  template<indirectly_swappable<I> I2>
2279
  friend constexpr void
2280
  iter_swap(const counted_iterator& x, const counted_iterator<I2>& y)
2281
  noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
2282
  ```
2283
 
2284
+ *Preconditions:* Both `x.length > 0` and `y.length > 0` are `true`.
2285
+
2286
  *Effects:* Equivalent to `ranges::iter_swap(x.current, y.current)`.
2287
 
2288
+ ### Unreachable sentinel <a id="unreachable.sentinel">[[unreachable.sentinel]]</a>
 
 
2289
 
2290
  Class `unreachable_sentinel_t` can be used with any
2291
  `weakly_incrementable` type to denote the “upper bound” of an unbounded
2292
  interval.
2293