- tmp/tmpo_3wurqs/{from.md → to.md} +1520 -75
tmp/tmpo_3wurqs/{from.md → to.md}
RENAMED
|
@@ -157,11 +157,11 @@ exactly like `optional<T>` with the following differences:
|
|
| 157 |
- Otherwise, `movable-box<T>` should store only a `T` if either `T`
|
| 158 |
models `movable` or `is_nothrow_move_constructible_v<T>` is `true`.
|
| 159 |
|
| 160 |
### Non-propagating cache <a id="range.nonprop.cache">[[range.nonprop.cache]]</a>
|
| 161 |
|
| 162 |
-
Some types in
|
| 163 |
exposition-only class template *`non-propagating-{}cache`*.
|
| 164 |
`non-propagating-cache<T>` behaves exactly like `optional<T>` with the
|
| 165 |
following differences:
|
| 166 |
|
| 167 |
- `non-propagating-cache<T>` constrains its type parameter `T` with
|
|
@@ -236,10 +236,20 @@ namespace std::ranges {
|
|
| 236 |
|
| 237 |
template<class T>
|
| 238 |
constexpr T& as-lvalue(T&& t) { // exposition only
|
| 239 |
return static_cast<T&>(t);
|
| 240 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
}
|
| 242 |
```
|
| 243 |
|
| 244 |
### All view <a id="range.all">[[range.all]]</a>
|
| 245 |
|
|
@@ -283,10 +293,13 @@ namespace std::ranges {
|
|
| 283 |
{ return ranges::empty(*r_); }
|
| 284 |
|
| 285 |
constexpr auto size() const requires sized_range<R>
|
| 286 |
{ return ranges::size(*r_); }
|
| 287 |
|
|
|
|
|
|
|
|
|
|
| 288 |
constexpr auto data() const requires contiguous_range<R>
|
| 289 |
{ return ranges::data(*r_); }
|
| 290 |
};
|
| 291 |
|
| 292 |
template<class R>
|
|
@@ -356,10 +369,15 @@ namespace std::ranges {
|
|
| 356 |
constexpr auto size() requires sized_range<R>
|
| 357 |
{ return ranges::size(r_); }
|
| 358 |
constexpr auto size() const requires sized_range<const R>
|
| 359 |
{ return ranges::size(r_); }
|
| 360 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 361 |
constexpr auto data() requires contiguous_range<R>
|
| 362 |
{ return ranges::data(r_); }
|
| 363 |
constexpr auto data() const requires contiguous_range<const R>
|
| 364 |
{ return ranges::data(r_); }
|
| 365 |
};
|
|
@@ -384,11 +402,11 @@ to replace copying with moving.
|
|
| 384 |
The name `views::as_rvalue` denotes a range adaptor object
|
| 385 |
[[range.adaptor.object]]. Let `E` be an expression and let `T` be
|
| 386 |
`decltype((E))`. The expression `views::as_rvalue(E)` is
|
| 387 |
expression-equivalent to:
|
| 388 |
|
| 389 |
-
- `views::all(E)` if
|
| 390 |
`same_as<range_rvalue_reference_t<T>, range_reference_t<T>>` is
|
| 391 |
`true`.
|
| 392 |
- Otherwise, `as_rvalue_view(E)`.
|
| 393 |
|
| 394 |
[*Example 1*:
|
|
@@ -438,10 +456,15 @@ namespace std::ranges {
|
|
| 438 |
}
|
| 439 |
}
|
| 440 |
|
| 441 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 442 |
constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 443 |
};
|
| 444 |
|
| 445 |
template<class R>
|
| 446 |
as_rvalue_view(R&&) -> as_rvalue_view<views::all_t<R>>;
|
| 447 |
}
|
|
@@ -825,10 +848,15 @@ namespace std::ranges {
|
|
| 825 |
regular_invocable<const F&, range_reference_t<const V>>;
|
| 826 |
|
| 827 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 828 |
constexpr auto size() const requires sized_range<const V>
|
| 829 |
{ return ranges::size(base_); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 830 |
};
|
| 831 |
|
| 832 |
template<class R, class F>
|
| 833 |
transform_view(R&&, F) -> transform_view<views::all_t<R>, F>;
|
| 834 |
}
|
|
@@ -1408,10 +1436,26 @@ namespace std::ranges {
|
|
| 1408 |
|
| 1409 |
constexpr auto size() const requires sized_range<const V> {
|
| 1410 |
auto n = ranges::size(base_);
|
| 1411 |
return ranges::min(n, static_cast<decltype(n)>(count_));
|
| 1412 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1413 |
};
|
| 1414 |
|
| 1415 |
template<class R>
|
| 1416 |
take_view(R&&, range_difference_t<R>)
|
| 1417 |
-> take_view<views::all_t<R>>;
|
|
@@ -1661,12 +1705,12 @@ expression `views::drop(E, F)` is expression-equivalent to:
|
|
| 1661 |
then
|
| 1662 |
`U(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::end(E))`,
|
| 1663 |
except that `E` is evaluated only once, where `U` is
|
| 1664 |
`span<typename T::element_type>` if `T` is a specialization of `span`
|
| 1665 |
and `T` otherwise.
|
| 1666 |
-
- Otherwise, if `T` is a specialization of `subrange`
|
| 1667 |
-
|
| 1668 |
`T(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::{}end(E),
|
| 1669 |
to-unsigned-like(ranges::distance(E) -
|
| 1670 |
std::min<D>(ranges::distance(E), F)))`, except that `E` and `F` are
|
| 1671 |
each evaluated only once.
|
| 1672 |
- Otherwise, if `T` is a specialization of `repeat_view`
|
|
@@ -1727,10 +1771,20 @@ namespace std::ranges {
|
|
| 1727 |
const auto s = ranges::size(base_);
|
| 1728 |
const auto c = static_cast<decltype(s)>(count_);
|
| 1729 |
return s < c ? 0 : s - c;
|
| 1730 |
}
|
| 1731 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1732 |
private:
|
| 1733 |
V base_ = V(); // exposition only
|
| 1734 |
range_difference_t<V> count_ = 0; // exposition only
|
| 1735 |
};
|
| 1736 |
|
|
@@ -2233,11 +2287,11 @@ friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
|
| 2233 |
noexcept(noexcept(ranges::iter_swap(*x.inner_, *y.inner_)))
|
| 2234 |
requires indirectly_swappable<InnerIter>;
|
| 2235 |
```
|
| 2236 |
|
| 2237 |
*Effects:* Equivalent to:
|
| 2238 |
-
`
|
| 2239 |
|
| 2240 |
#### Class template `join_view::sentinel` <a id="range.join.sentinel">[[range.join.sentinel]]</a>
|
| 2241 |
|
| 2242 |
``` cpp
|
| 2243 |
namespace std::ranges {
|
|
@@ -2312,23 +2366,17 @@ for (char c : vs | views::join_with('-')) {
|
|
| 2312 |
|
| 2313 |
#### Class template `join_with_view` <a id="range.join.with.view">[[range.join.with.view]]</a>
|
| 2314 |
|
| 2315 |
``` cpp
|
| 2316 |
namespace std::ranges {
|
| 2317 |
-
template<class R, class P>
|
| 2318 |
-
concept compatible-joinable-ranges = // exposition only
|
| 2319 |
-
common_with<range_value_t<R>, range_value_t<P>> &&
|
| 2320 |
-
common_reference_with<range_reference_t<R>, range_reference_t<P>> &&
|
| 2321 |
-
common_reference_with<range_rvalue_reference_t<R>, range_rvalue_reference_t<P>>;
|
| 2322 |
-
|
| 2323 |
template<class R>
|
| 2324 |
concept bidirectional-common = bidirectional_range<R> && common_range<R>; // exposition only
|
| 2325 |
|
| 2326 |
template<input_range V, forward_range Pattern>
|
| 2327 |
requires view<V> && input_range<range_reference_t<V>>
|
| 2328 |
&& view<Pattern>
|
| 2329 |
-
&&
|
| 2330 |
class join_with_view : public view_interface<join_with_view<V, Pattern>> {
|
| 2331 |
using InnerRng = range_reference_t<V>; // exposition only
|
| 2332 |
|
| 2333 |
V base_ = V(); // exposition only
|
| 2334 |
non-propagating-cache<iterator_t<V>> outer_it_; // exposition only, present only
|
|
@@ -2370,11 +2418,12 @@ namespace std::ranges {
|
|
| 2370 |
}
|
| 2371 |
constexpr auto begin() const
|
| 2372 |
requires forward_range<const V> &&
|
| 2373 |
forward_range<const Pattern> &&
|
| 2374 |
is_reference_v<range_reference_t<const V>> &&
|
| 2375 |
-
input_range<range_reference_t<const V>>
|
|
|
|
| 2376 |
return iterator<true>{*this, ranges::begin(base_)};
|
| 2377 |
}
|
| 2378 |
|
| 2379 |
constexpr auto end() {
|
| 2380 |
if constexpr (forward_range<V> &&
|
|
@@ -2385,11 +2434,12 @@ namespace std::ranges {
|
|
| 2385 |
return sentinel<simple-view<V> && simple-view<Pattern>>{*this};
|
| 2386 |
}
|
| 2387 |
constexpr auto end() const
|
| 2388 |
requires forward_range<const V> && forward_range<const Pattern> &&
|
| 2389 |
is_reference_v<range_reference_t<const V>> &&
|
| 2390 |
-
input_range<range_reference_t<const V>>
|
|
|
|
| 2391 |
using InnerConstRng = range_reference_t<const V>;
|
| 2392 |
if constexpr (forward_range<InnerConstRng> &&
|
| 2393 |
common_range<const V> && common_range<InnerConstRng>)
|
| 2394 |
return iterator<true>{*this, ranges::end(base_)};
|
| 2395 |
else
|
|
@@ -2427,11 +2477,11 @@ and *pattern\_* with `views::single(std::move(e))`.
|
|
| 2427 |
|
| 2428 |
``` cpp
|
| 2429 |
namespace std::ranges {
|
| 2430 |
template<input_range V, forward_range Pattern>
|
| 2431 |
requires view<V> && input_range<range_reference_t<V>>
|
| 2432 |
-
&& view<Pattern> &&
|
| 2433 |
template<bool Const>
|
| 2434 |
class join_with_view<V, Pattern>::iterator {
|
| 2435 |
using Parent = maybe-const<Const, join_with_view>; // exposition only
|
| 2436 |
using Base = maybe-const<Const, V>; // exposition only
|
| 2437 |
using InnerBase = range_reference_t<Base>; // exposition only
|
|
@@ -2530,11 +2580,11 @@ as follows:
|
|
| 2530 |
iter_reference_t<PatternIter>>>
|
| 2531 |
```
|
| 2532 |
|
| 2533 |
is `false`, `iterator_category` denotes `input_iterator_tag`.
|
| 2534 |
- Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
|
| 2535 |
-
`derived_from<
|
| 2536 |
*`PatternBase`* each model `common_range`, `iterator_category` denotes
|
| 2537 |
`bidirectional_iterator_tag`.
|
| 2538 |
- Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
|
| 2539 |
`derived_from<forward_iterator_tag>`, `iterator_category` denotes
|
| 2540 |
`forward_iterator_tag`.
|
|
@@ -2598,20 +2648,20 @@ constexpr void satisfy();
|
|
| 2598 |
``` cpp
|
| 2599 |
while (true) {
|
| 2600 |
if (inner_it_.index() == 0) {
|
| 2601 |
if (std::get<0>(inner_it_) != ranges::end(parent_->pattern_))
|
| 2602 |
break;
|
| 2603 |
-
inner_it_.emplace<1>(ranges::begin(update-inner()));
|
| 2604 |
} else {
|
| 2605 |
if (std::get<1>(inner_it_) != ranges::end(get-inner()))
|
| 2606 |
break;
|
| 2607 |
if (++outer() == ranges::end(parent_->base_)) {
|
| 2608 |
if constexpr (ref-is-glvalue)
|
| 2609 |
-
inner_it_.emplace<0>();
|
| 2610 |
break;
|
| 2611 |
}
|
| 2612 |
-
inner_it_.emplace<0>(ranges::begin(parent_->pattern_));
|
| 2613 |
}
|
| 2614 |
}
|
| 2615 |
```
|
| 2616 |
|
| 2617 |
[*Note 1*: `join_with_view` iterators use the *satisfy* function to
|
|
@@ -2628,11 +2678,11 @@ constexpr explicit iterator(Parent& parent)
|
|
| 2628 |
first overload, also initializes *outer_it\_* with `std::move(outer)`.
|
| 2629 |
Then, equivalent to:
|
| 2630 |
|
| 2631 |
``` cpp
|
| 2632 |
if (outer() != ranges::end(parent_->base_)) {
|
| 2633 |
-
inner_it_.emplace<1>(ranges::begin(update-inner()));
|
| 2634 |
satisfy();
|
| 2635 |
}
|
| 2636 |
```
|
| 2637 |
|
| 2638 |
``` cpp
|
|
@@ -2645,13 +2695,13 @@ constexpr iterator(iterator<!Const> i)
|
|
| 2645 |
*Effects:* Initializes *outer_it\_* with `std::move(i.`*`outer_it_`*`)`
|
| 2646 |
and *parent\_* with `i.`*`parent_`*. Then, equivalent to:
|
| 2647 |
|
| 2648 |
``` cpp
|
| 2649 |
if (i.inner_it_.index() == 0)
|
| 2650 |
-
inner_it_.emplace<0>(std::get<0>(std::move(i.inner_it_)));
|
| 2651 |
else
|
| 2652 |
-
inner_it_.emplace<1>(std::get<1>(std::move(i.inner_it_)));
|
| 2653 |
```
|
| 2654 |
|
| 2655 |
[*Note 2*: `Const` can only be `true` when *Base* models
|
| 2656 |
`forward_range`. — *end note*]
|
| 2657 |
|
|
@@ -2707,27 +2757,27 @@ constexpr iterator& operator--()
|
|
| 2707 |
*Effects:* Equivalent to:
|
| 2708 |
|
| 2709 |
``` cpp
|
| 2710 |
if (outer_it_ == ranges::end(parent_->base_)) {
|
| 2711 |
auto&& inner = *--outer_it_;
|
| 2712 |
-
inner_it_.emplace<1>(ranges::end(inner));
|
| 2713 |
}
|
| 2714 |
|
| 2715 |
while (true) {
|
| 2716 |
if (inner_it_.index() == 0) {
|
| 2717 |
auto& it = std::get<0>(inner_it_);
|
| 2718 |
if (it == ranges::begin(parent_->pattern_)) {
|
| 2719 |
auto&& inner = *--outer_it_;
|
| 2720 |
-
inner_it_.emplace<1>(ranges::end(inner));
|
| 2721 |
} else {
|
| 2722 |
break;
|
| 2723 |
}
|
| 2724 |
} else {
|
| 2725 |
auto& it = std::get<1>(inner_it_);
|
| 2726 |
auto&& inner = *outer_it_;
|
| 2727 |
if (it == ranges::begin(inner)) {
|
| 2728 |
-
inner_it_.emplace<0>(ranges::end(parent_->pattern_));
|
| 2729 |
} else {
|
| 2730 |
break;
|
| 2731 |
}
|
| 2732 |
}
|
| 2733 |
}
|
|
@@ -2765,11 +2815,11 @@ return x.outer_it_ == y.outer_it_ && x.inner_it_ == y.inner_it_;
|
|
| 2765 |
|
| 2766 |
``` cpp
|
| 2767 |
namespace std::ranges {
|
| 2768 |
template<input_range V, forward_range Pattern>
|
| 2769 |
requires view<V> && input_range<range_reference_t<V>>
|
| 2770 |
-
&& view<Pattern> &&
|
| 2771 |
template<bool Const>
|
| 2772 |
class join_with_view<V, Pattern>::sentinel {
|
| 2773 |
using Parent = maybe-const<Const, join_with_view>; // exposition only
|
| 2774 |
using Base = maybe-const<Const, V>; // exposition only
|
| 2775 |
sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
|
|
@@ -3014,12 +3064,13 @@ constexpr outer-iterator(Parent& parent, iterator_t<Base> current)
|
|
| 3014 |
``` cpp
|
| 3015 |
constexpr outer-iterator(outer-iterator<!Const> i)
|
| 3016 |
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
|
| 3017 |
```
|
| 3018 |
|
| 3019 |
-
*Effects:* Initializes *parent\_* with `i.`*`parent_`*
|
| 3020 |
-
|
|
|
|
| 3021 |
|
| 3022 |
``` cpp
|
| 3023 |
constexpr value_type operator*() const;
|
| 3024 |
```
|
| 3025 |
|
|
@@ -3094,14 +3145,13 @@ namespace std::ranges {
|
|
| 3094 |
struct lazy_split_view<V, Pattern>::outer-iterator<Const>::value_type
|
| 3095 |
: view_interface<value_type> {
|
| 3096 |
private:
|
| 3097 |
outer-iterator i_ = outer-iterator(); // exposition only
|
| 3098 |
|
| 3099 |
-
|
| 3100 |
-
value_type() = default;
|
| 3101 |
-
constexpr explicit value_type(outer-iterator i);
|
| 3102 |
|
|
|
|
| 3103 |
constexpr inner-iterator<Const> begin() const;
|
| 3104 |
constexpr default_sentinel_t end() const noexcept;
|
| 3105 |
};
|
| 3106 |
}
|
| 3107 |
```
|
|
@@ -3139,11 +3189,11 @@ namespace std::ranges {
|
|
| 3139 |
using Base = maybe-const<Const, V>; // exposition only
|
| 3140 |
outer-iterator<Const> i_ = outer-iterator<Const>(); // exposition only
|
| 3141 |
bool incremented_ = false; // exposition only
|
| 3142 |
|
| 3143 |
public:
|
| 3144 |
-
using iterator_concept =
|
| 3145 |
|
| 3146 |
using iterator_category = see belownc; // present only if Base
|
| 3147 |
// models forward_range
|
| 3148 |
using value_type = range_value_t<Base>;
|
| 3149 |
using difference_type = range_difference_t<Base>;
|
|
@@ -3434,17 +3484,17 @@ constexpr iterator(split_view& parent, iterator_t<V> current, subrange<iterator_
|
|
| 3434 |
|
| 3435 |
``` cpp
|
| 3436 |
constexpr iterator_t<V> base() const;
|
| 3437 |
```
|
| 3438 |
|
| 3439 |
-
*Effects:* Equivalent to `return `*`cur_`*`;`
|
| 3440 |
|
| 3441 |
``` cpp
|
| 3442 |
constexpr value_type operator*() const;
|
| 3443 |
```
|
| 3444 |
|
| 3445 |
-
*Effects:* Equivalent to `return {`*`cur_`*`, `*`next_`*`.begin()};`
|
| 3446 |
|
| 3447 |
``` cpp
|
| 3448 |
constexpr iterator& operator++();
|
| 3449 |
```
|
| 3450 |
|
|
@@ -3519,10 +3569,798 @@ friend constexpr bool operator==(const iterator& x, const sentinel& y);
|
|
| 3519 |
```
|
| 3520 |
|
| 3521 |
*Effects:* Equivalent to:
|
| 3522 |
`return x.`*`cur_`*` == y.`*`end_`*` && !x.`*`trailing_empty_`*`;`
|
| 3523 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3524 |
### Counted view <a id="range.counted">[[range.counted]]</a>
|
| 3525 |
|
| 3526 |
A counted view presents a view of the elements of the counted range
|
| 3527 |
[[iterator.requirements.general]] `i`+\[0, `n`) for an iterator `i` and
|
| 3528 |
non-negative integer `n`.
|
|
@@ -3599,11 +4437,11 @@ namespace std::ranges {
|
|
| 3599 |
constexpr explicit common_view(V r);
|
| 3600 |
|
| 3601 |
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 3602 |
constexpr V base() && { return std::move(base_); }
|
| 3603 |
|
| 3604 |
-
constexpr auto begin() {
|
| 3605 |
if constexpr (random_access_range<V> && sized_range<V>)
|
| 3606 |
return ranges::begin(base_);
|
| 3607 |
else
|
| 3608 |
return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::begin(base_));
|
| 3609 |
}
|
|
@@ -3613,11 +4451,11 @@ namespace std::ranges {
|
|
| 3613 |
return ranges::begin(base_);
|
| 3614 |
else
|
| 3615 |
return common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::begin(base_));
|
| 3616 |
}
|
| 3617 |
|
| 3618 |
-
constexpr auto end() {
|
| 3619 |
if constexpr (random_access_range<V> && sized_range<V>)
|
| 3620 |
return ranges::begin(base_) + ranges::distance(base_);
|
| 3621 |
else
|
| 3622 |
return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::end(base_));
|
| 3623 |
}
|
|
@@ -3633,10 +4471,17 @@ namespace std::ranges {
|
|
| 3633 |
return ranges::size(base_);
|
| 3634 |
}
|
| 3635 |
constexpr auto size() const requires sized_range<const V> {
|
| 3636 |
return ranges::size(base_);
|
| 3637 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3638 |
};
|
| 3639 |
|
| 3640 |
template<class R>
|
| 3641 |
common_view(R&&) -> common_view<views::all_t<R>>;
|
| 3642 |
}
|
|
@@ -3658,25 +4503,20 @@ iterates the same elements in reverse order.
|
|
| 3658 |
The name `views::reverse` denotes a range adaptor object
|
| 3659 |
[[range.adaptor.object]]. Given a subexpression `E`, the expression
|
| 3660 |
`views::reverse(E)` is expression-equivalent to:
|
| 3661 |
|
| 3662 |
- If the type of `E` is a (possibly cv-qualified) specialization of
|
| 3663 |
-
`reverse_view`,
|
| 3664 |
- Otherwise, if the type of `E` is cv
|
| 3665 |
`subrange<reverse_iterator<I>, reverse_iterator<I>, K>` for some
|
| 3666 |
iterator type `I` and value `K` of type `subrange_kind`,
|
| 3667 |
-
- if `K` is `subrange_kind::sized`,
|
| 3668 |
-
`
|
| 3669 |
-
|
| 3670 |
-
```
|
| 3671 |
-
- otherwise, equivalent to:
|
| 3672 |
-
``` cpp
|
| 3673 |
-
subrange<I, I, K>(E.end().base(), E.begin().base())
|
| 3674 |
-
```
|
| 3675 |
|
| 3676 |
However, in either case `E` is evaluated only once.
|
| 3677 |
-
- Otherwise,
|
| 3678 |
|
| 3679 |
[*Example 1*:
|
| 3680 |
|
| 3681 |
``` cpp
|
| 3682 |
vector<int> is {0,1,2,3,4};
|
|
@@ -3716,10 +4556,17 @@ namespace std::ranges {
|
|
| 3716 |
}
|
| 3717 |
|
| 3718 |
constexpr auto size() const requires sized_range<const V> {
|
| 3719 |
return ranges::size(base_);
|
| 3720 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3721 |
};
|
| 3722 |
|
| 3723 |
template<class R>
|
| 3724 |
reverse_view(R&&) -> reverse_view<views::all_t<R>>;
|
| 3725 |
}
|
|
@@ -3820,10 +4667,15 @@ namespace std::ranges {
|
|
| 3820 |
constexpr auto end() requires (!simple-view<V>) { return ranges::cend(base_); }
|
| 3821 |
constexpr auto end() const requires range<const V> { return ranges::cend(base_); }
|
| 3822 |
|
| 3823 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 3824 |
constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3825 |
};
|
| 3826 |
|
| 3827 |
template<class R>
|
| 3828 |
as_const_view(R&&) -> as_const_view<views::all_t<R>>;
|
| 3829 |
}
|
|
@@ -3944,10 +4796,16 @@ namespace std::ranges {
|
|
| 3944 |
{ return ranges::size(base_); }
|
| 3945 |
|
| 3946 |
constexpr auto size() const requires sized_range<const V>
|
| 3947 |
{ return ranges::size(base_); }
|
| 3948 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3949 |
private:
|
| 3950 |
// [range.elements.iterator], class template elements_view::iterator
|
| 3951 |
template<bool> class iterator; // exposition only
|
| 3952 |
|
| 3953 |
// [range.elements.sentinel], class template elements_view::sentinel
|
|
@@ -4336,13 +5194,13 @@ friend constexpr range_difference_t<maybe-const<OtherConst, V>>
|
|
| 4336 |
#### Overview <a id="range.enumerate.overview">[[range.enumerate.overview]]</a>
|
| 4337 |
|
| 4338 |
`enumerate_view` is a view whose elements represent both the position
|
| 4339 |
and value from a sequence of elements.
|
| 4340 |
|
| 4341 |
-
The name `views::enumerate` denotes a range adaptor object
|
| 4342 |
-
subexpression `E`, the expression
|
| 4343 |
-
expression-equivalent to
|
| 4344 |
`enumerate_view<views::all_t<decltype((E))>>(E)`.
|
| 4345 |
|
| 4346 |
[*Example 1*:
|
| 4347 |
|
| 4348 |
``` cpp
|
|
@@ -4378,27 +5236,32 @@ namespace std::ranges {
|
|
| 4378 |
{ return iterator<false>(ranges::begin(base_), 0); }
|
| 4379 |
constexpr auto begin() const requires range-with-movable-references<const V>
|
| 4380 |
{ return iterator<true>(ranges::begin(base_), 0); }
|
| 4381 |
|
| 4382 |
constexpr auto end() requires (!simple-view<V>) {
|
| 4383 |
-
if constexpr (common_range<V> && sized_range<V>)
|
| 4384 |
return iterator<false>(ranges::end(base_), ranges::distance(base_));
|
| 4385 |
else
|
| 4386 |
return sentinel<false>(ranges::end(base_));
|
| 4387 |
}
|
| 4388 |
constexpr auto end() const requires range-with-movable-references<const V> {
|
| 4389 |
-
if constexpr (common_range<const V> && sized_range<const V>)
|
| 4390 |
return iterator<true>(ranges::end(base_), ranges::distance(base_));
|
| 4391 |
else
|
| 4392 |
return sentinel<true>(ranges::end(base_));
|
| 4393 |
}
|
| 4394 |
|
| 4395 |
constexpr auto size() requires sized_range<V>
|
| 4396 |
{ return ranges::size(base_); }
|
| 4397 |
constexpr auto size() const requires sized_range<const V>
|
| 4398 |
{ return ranges::size(base_); }
|
| 4399 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4400 |
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 4401 |
constexpr V base() && { return std::move(base_); }
|
| 4402 |
};
|
| 4403 |
|
| 4404 |
template<class R>
|
|
@@ -4474,11 +5337,11 @@ namespace std::ranges {
|
|
| 4474 |
requires random_access_range<Base>;
|
| 4475 |
friend constexpr iterator operator+(difference_type x, const iterator& y)
|
| 4476 |
requires random_access_range<Base>;
|
| 4477 |
friend constexpr iterator operator-(const iterator& x, difference_type y)
|
| 4478 |
requires random_access_range<Base>;
|
| 4479 |
-
friend constexpr difference_type operator-(const iterator& x, const iterator& y);
|
| 4480 |
|
| 4481 |
friend constexpr auto iter_move(const iterator& i)
|
| 4482 |
noexcept(noexcept(ranges::iter_move(i.current_)) &&
|
| 4483 |
is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>) {
|
| 4484 |
return tuple<difference_type,
|
|
@@ -4656,11 +5519,11 @@ auto temp = x;
|
|
| 4656 |
temp -= y;
|
| 4657 |
return temp;
|
| 4658 |
```
|
| 4659 |
|
| 4660 |
``` cpp
|
| 4661 |
-
friend constexpr difference_type operator-(const iterator& x, const iterator& y);
|
| 4662 |
```
|
| 4663 |
|
| 4664 |
*Effects:* Equivalent to: `return x.`*`pos_`*` - y.`*`pos_`*`;`
|
| 4665 |
|
| 4666 |
#### Class template `enumerate_view::sentinel` <a id="range.enumerate.sentinel">[[range.enumerate.sentinel]]</a>
|
|
@@ -4867,20 +5730,10 @@ return apply([](auto... sizes) {
|
|
| 4867 |
|
| 4868 |
#### Class template `zip_view::iterator` <a id="range.zip.iterator">[[range.zip.iterator]]</a>
|
| 4869 |
|
| 4870 |
``` cpp
|
| 4871 |
namespace std::ranges {
|
| 4872 |
-
template<bool Const, class... Views>
|
| 4873 |
-
concept all-random-access = // exposition only
|
| 4874 |
-
(random_access_range<maybe-const<Const, Views>> && ...);
|
| 4875 |
-
template<bool Const, class... Views>
|
| 4876 |
-
concept all-bidirectional = // exposition only
|
| 4877 |
-
(bidirectional_range<maybe-const<Const, Views>> && ...);
|
| 4878 |
-
template<bool Const, class... Views>
|
| 4879 |
-
concept all-forward = // exposition only
|
| 4880 |
-
(forward_range<maybe-const<Const, Views>> && ...);
|
| 4881 |
-
|
| 4882 |
template<input_range... Views>
|
| 4883 |
requires (view<Views> && ...) && (sizeof...(Views) > 0)
|
| 4884 |
template<bool Const>
|
| 4885 |
class zip_view<Views...>::iterator {
|
| 4886 |
tuple<iterator_t<maybe-const<Const, Views>>...> current_; // exposition only
|
|
@@ -5247,11 +6100,11 @@ template<bool OtherConst>
|
|
| 5247 |
iterator_t<maybe-const<OtherConst, Views>>> && ...)
|
| 5248 |
friend constexpr common_type_t<range_difference_t<maybe-const<OtherConst, Views>>...>
|
| 5249 |
operator-(const sentinel& y, const iterator<OtherConst>& x);
|
| 5250 |
```
|
| 5251 |
|
| 5252 |
-
*Effects:* Equivalent to `return -(x - y);`
|
| 5253 |
|
| 5254 |
### Zip transform view <a id="range.zip.transform">[[range.zip.transform]]</a>
|
| 5255 |
|
| 5256 |
#### Overview <a id="range.zip.transform.overview">[[range.zip.transform.overview]]</a>
|
| 5257 |
|
|
@@ -5382,11 +6235,11 @@ namespace std::ranges {
|
|
| 5382 |
|
| 5383 |
constexpr iterator(Parent& parent, ziperator<Const> inner); // exposition only
|
| 5384 |
|
| 5385 |
public:
|
| 5386 |
using iterator_category = see belownc; // not always present
|
| 5387 |
-
using iterator_concept =
|
| 5388 |
using value_type =
|
| 5389 |
remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
|
| 5390 |
range_reference_t<maybe-const<Const, Views>>...>>;
|
| 5391 |
using difference_type = range_difference_t<Base>;
|
| 5392 |
|
|
@@ -5685,11 +6538,12 @@ resulting view is empty.
|
|
| 5685 |
The name `views::adjacent<N>` denotes a range adaptor object
|
| 5686 |
[[range.adaptor.object]]. Given a subexpression `E` and a constant
|
| 5687 |
expression `N`, the expression `views::adjacent<N>(E)` is
|
| 5688 |
expression-equivalent to
|
| 5689 |
|
| 5690 |
-
- `((void)E, auto(views::empty<tuple<>>))` if `N` is equal to `0`
|
|
|
|
| 5691 |
- otherwise, `adjacent_view<views::all_t<decltype((E))>, N>(E)`.
|
| 5692 |
|
| 5693 |
[*Example 1*:
|
| 5694 |
|
| 5695 |
``` cpp
|
|
@@ -5753,10 +6607,13 @@ namespace std::ranges {
|
|
| 5753 |
}
|
| 5754 |
}
|
| 5755 |
|
| 5756 |
constexpr auto size() requires sized_range<V>;
|
| 5757 |
constexpr auto size() const requires sized_range<const V>;
|
|
|
|
|
|
|
|
|
|
| 5758 |
};
|
| 5759 |
}
|
| 5760 |
```
|
| 5761 |
|
| 5762 |
``` cpp
|
|
@@ -5778,10 +6635,25 @@ using CT = common_type_t<ST, size_t>;
|
|
| 5778 |
auto sz = static_cast<CT>(ranges::size(base_));
|
| 5779 |
sz -= std::min<CT>(sz, N - 1);
|
| 5780 |
return static_cast<ST>(sz);
|
| 5781 |
```
|
| 5782 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5783 |
#### Class template `adjacent_view::iterator` <a id="range.adjacent.iterator">[[range.adjacent.iterator]]</a>
|
| 5784 |
|
| 5785 |
``` cpp
|
| 5786 |
namespace std::ranges {
|
| 5787 |
template<forward_range V, size_t N>
|
|
@@ -6174,13 +7046,14 @@ resulting view is empty.
|
|
| 6174 |
|
| 6175 |
The name `views::adjacent_transform<N>` denotes a range adaptor object
|
| 6176 |
[[range.adaptor.object]]. Given subexpressions `E` and `F` and a
|
| 6177 |
constant expression `N`:
|
| 6178 |
|
| 6179 |
-
- If `N` is equal to `0`
|
| 6180 |
-
|
| 6181 |
-
|
|
|
|
| 6182 |
- Otherwise, the expression `views::adjacent_transform<N>(E, F)` is
|
| 6183 |
expression-equivalent to
|
| 6184 |
`adjacent_transform_view<views::all_t<decltype((E))>, decay_t<decltype((F))>, N>(E, F)`.
|
| 6185 |
|
| 6186 |
[*Example 1*:
|
|
@@ -6221,11 +7094,11 @@ namespace std::ranges {
|
|
| 6221 |
|
| 6222 |
public:
|
| 6223 |
adjacent_transform_view() = default;
|
| 6224 |
constexpr explicit adjacent_transform_view(V base, F fun);
|
| 6225 |
|
| 6226 |
-
constexpr V base() const & requires copy_constructible<
|
| 6227 |
constexpr V base() && { return std::move(inner_).base(); }
|
| 6228 |
|
| 6229 |
constexpr auto begin() {
|
| 6230 |
return iterator<false>(*this, inner_.begin());
|
| 6231 |
}
|
|
@@ -6259,10 +7132,18 @@ namespace std::ranges {
|
|
| 6259 |
}
|
| 6260 |
|
| 6261 |
constexpr auto size() const requires sized_range<const InnerView> {
|
| 6262 |
return inner_.size();
|
| 6263 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6264 |
};
|
| 6265 |
}
|
| 6266 |
```
|
| 6267 |
|
| 6268 |
``` cpp
|
|
@@ -6289,11 +7170,11 @@ namespace std::ranges {
|
|
| 6289 |
|
| 6290 |
constexpr iterator(Parent& parent, inner-iterator<Const> inner); // exposition only
|
| 6291 |
|
| 6292 |
public:
|
| 6293 |
using iterator_category = see below;
|
| 6294 |
-
using iterator_concept =
|
| 6295 |
using value_type =
|
| 6296 |
remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
|
| 6297 |
REPEAT(range_reference_t<Base>, N)...>>;
|
| 6298 |
using difference_type = range_difference_t<Base>;
|
| 6299 |
|
|
@@ -6563,11 +7444,11 @@ constexpr sentinel(sentinel<!Const> i)
|
|
| 6563 |
template<bool OtherConst>
|
| 6564 |
requires sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 6565 |
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
| 6566 |
```
|
| 6567 |
|
| 6568 |
-
*Effects:* Equivalent to `return x.`*`inner_`*` == y.`*`inner_`*`;`
|
| 6569 |
|
| 6570 |
``` cpp
|
| 6571 |
template<bool OtherConst>
|
| 6572 |
requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 6573 |
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
|
@@ -6577,11 +7458,11 @@ template<bool OtherConst>
|
|
| 6577 |
requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 6578 |
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
| 6579 |
operator-(const sentinel& x, const iterator<OtherConst>& y);
|
| 6580 |
```
|
| 6581 |
|
| 6582 |
-
*Effects:* Equivalent to `return x.`*`inner_`*` - y.`*`inner_`*`;`
|
| 6583 |
|
| 6584 |
### Chunk view <a id="range.chunk">[[range.chunk]]</a>
|
| 6585 |
|
| 6586 |
#### Overview <a id="range.chunk.overview">[[range.chunk.overview]]</a>
|
| 6587 |
|
|
@@ -6650,10 +7531,13 @@ namespace std::ranges {
|
|
| 6650 |
constexpr outer-iterator begin();
|
| 6651 |
constexpr default_sentinel_t end() const noexcept;
|
| 6652 |
|
| 6653 |
constexpr auto size() requires sized_range<V>;
|
| 6654 |
constexpr auto size() const requires sized_range<const V>;
|
|
|
|
|
|
|
|
|
|
| 6655 |
};
|
| 6656 |
|
| 6657 |
template<class R>
|
| 6658 |
chunk_view(R&&, range_difference_t<R>) -> chunk_view<views::all_t<R>>;
|
| 6659 |
}
|
|
@@ -6695,10 +7579,22 @@ constexpr auto size() const requires sized_range<const V>;
|
|
| 6695 |
|
| 6696 |
``` cpp
|
| 6697 |
return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
|
| 6698 |
```
|
| 6699 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6700 |
#### Class `chunk_view::outer-iterator` <a id="range.chunk.outer.iter">[[range.chunk.outer.iter]]</a>
|
| 6701 |
|
| 6702 |
``` cpp
|
| 6703 |
namespace std::ranges {
|
| 6704 |
template<view V>
|
|
@@ -6814,10 +7710,12 @@ namespace std::ranges {
|
|
| 6814 |
constexpr inner-iterator begin() const noexcept;
|
| 6815 |
constexpr default_sentinel_t end() const noexcept;
|
| 6816 |
|
| 6817 |
constexpr auto size() const
|
| 6818 |
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
|
|
|
|
|
|
| 6819 |
};
|
| 6820 |
}
|
| 6821 |
```
|
| 6822 |
|
| 6823 |
``` cpp
|
|
@@ -6848,10 +7746,20 @@ constexpr auto size() const
|
|
| 6848 |
``` cpp
|
| 6849 |
return to-unsigned-like(ranges::min(parent_->remainder_,
|
| 6850 |
ranges::end(parent_->base_) - *parent_->current_));
|
| 6851 |
```
|
| 6852 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6853 |
#### Class `chunk_view::inner-iterator` <a id="range.chunk.inner.iter">[[range.chunk.inner.iter]]</a>
|
| 6854 |
|
| 6855 |
``` cpp
|
| 6856 |
namespace std::ranges {
|
| 6857 |
template<view V>
|
|
@@ -7026,10 +7934,13 @@ namespace std::ranges {
|
|
| 7026 |
}
|
| 7027 |
}
|
| 7028 |
|
| 7029 |
constexpr auto size() requires sized_range<V>;
|
| 7030 |
constexpr auto size() const requires sized_range<const V>;
|
|
|
|
|
|
|
|
|
|
| 7031 |
};
|
| 7032 |
}
|
| 7033 |
```
|
| 7034 |
|
| 7035 |
``` cpp
|
|
@@ -7050,10 +7961,22 @@ constexpr auto size() const requires sized_range<const V>;
|
|
| 7050 |
|
| 7051 |
``` cpp
|
| 7052 |
return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
|
| 7053 |
```
|
| 7054 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7055 |
#### Class template `chunk_view::iterator` for forward ranges <a id="range.chunk.fwd.iter">[[range.chunk.fwd.iter]]</a>
|
| 7056 |
|
| 7057 |
``` cpp
|
| 7058 |
namespace std::ranges {
|
| 7059 |
template<view V>
|
|
@@ -7426,10 +8349,13 @@ namespace std::ranges {
|
|
| 7426 |
requires (!(simple-view<V> && slide-caches-nothing<const V>));
|
| 7427 |
constexpr auto end() const requires slide-caches-nothing<const V>;
|
| 7428 |
|
| 7429 |
constexpr auto size() requires sized_range<V>;
|
| 7430 |
constexpr auto size() const requires sized_range<const V>;
|
|
|
|
|
|
|
|
|
|
| 7431 |
};
|
| 7432 |
|
| 7433 |
template<class R>
|
| 7434 |
slide_view(R&&, range_difference_t<R>) -> slide_view<views::all_t<R>>;
|
| 7435 |
}
|
|
@@ -7513,10 +8439,24 @@ constexpr auto size() const requires sized_range<const V>;
|
|
| 7513 |
auto sz = ranges::distance(base_) - n_ + 1;
|
| 7514 |
if (sz < 0) sz = 0;
|
| 7515 |
return to-unsigned-like(sz);
|
| 7516 |
```
|
| 7517 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7518 |
#### Class template `slide_view::iterator` <a id="range.slide.iterator">[[range.slide.iterator]]</a>
|
| 7519 |
|
| 7520 |
``` cpp
|
| 7521 |
namespace std::ranges {
|
| 7522 |
template<forward_range V>
|
|
@@ -8180,10 +9120,13 @@ namespace std::ranges {
|
|
| 8180 |
}
|
| 8181 |
}
|
| 8182 |
|
| 8183 |
constexpr auto size() requires sized_range<V>;
|
| 8184 |
constexpr auto size() const requires sized_range<const V>;
|
|
|
|
|
|
|
|
|
|
| 8185 |
};
|
| 8186 |
|
| 8187 |
template<class R>
|
| 8188 |
stride_view(R&&, range_difference_t<R>) -> stride_view<views::all_t<R>>;
|
| 8189 |
}
|
|
@@ -8213,10 +9156,22 @@ constexpr auto size() const requires sized_range<const V>;
|
|
| 8213 |
|
| 8214 |
``` cpp
|
| 8215 |
return to-unsigned-like(div-ceil(ranges::distance(base_), stride_));
|
| 8216 |
```
|
| 8217 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8218 |
#### Class template `stride_view::iterator` <a id="range.stride.iterator">[[range.stride.iterator]]</a>
|
| 8219 |
|
| 8220 |
``` cpp
|
| 8221 |
namespace std::ranges {
|
| 8222 |
template<input_range V>
|
|
@@ -8374,11 +9329,11 @@ return *this;
|
|
| 8374 |
|
| 8375 |
``` cpp
|
| 8376 |
constexpr void operator++(int);
|
| 8377 |
```
|
| 8378 |
|
| 8379 |
-
*Effects:* Equivalent to
|
| 8380 |
|
| 8381 |
``` cpp
|
| 8382 |
constexpr iterator operator++(int) requires forward_range<Base>;
|
| 8383 |
```
|
| 8384 |
|
|
@@ -8616,11 +9571,11 @@ namespace std::ranges {
|
|
| 8616 |
concept cartesian-product-is-bidirectional = // exposition only
|
| 8617 |
(bidirectional_range<maybe-const<Const, First>> && ... &&
|
| 8618 |
(bidirectional_range<maybe-const<Const, Vs>>
|
| 8619 |
&& cartesian-product-common-arg<maybe-const<Const, Vs>>));
|
| 8620 |
|
| 8621 |
-
template<class First, class...
|
| 8622 |
concept cartesian-product-is-common = // exposition only
|
| 8623 |
cartesian-product-common-arg<First>;
|
| 8624 |
|
| 8625 |
template<class... Vs>
|
| 8626 |
concept cartesian-product-is-sized = // exposition only
|
|
@@ -9159,5 +10114,495 @@ ranges::iter_swap(std::get<i>(l.current_), std::get<i>(r.current_))
|
|
| 9159 |
the following expressions:
|
| 9160 |
|
| 9161 |
- `noexcept(ranges::iter_swap(std::get<`i`>(l.`*`current_`*`), std::get<`i`>(r.`*`current_`*`)))`
|
| 9162 |
for every integer 0 ≤ i ≤ `sizeof...(Vs)`.
|
| 9163 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
- Otherwise, `movable-box<T>` should store only a `T` if either `T`
|
| 158 |
models `movable` or `is_nothrow_move_constructible_v<T>` is `true`.
|
| 159 |
|
| 160 |
### Non-propagating cache <a id="range.nonprop.cache">[[range.nonprop.cache]]</a>
|
| 161 |
|
| 162 |
+
Some types in [[range.adaptors]] are specified in terms of an
|
| 163 |
exposition-only class template *`non-propagating-{}cache`*.
|
| 164 |
`non-propagating-cache<T>` behaves exactly like `optional<T>` with the
|
| 165 |
following differences:
|
| 166 |
|
| 167 |
- `non-propagating-cache<T>` constrains its type parameter `T` with
|
|
|
|
| 236 |
|
| 237 |
template<class T>
|
| 238 |
constexpr T& as-lvalue(T&& t) { // exposition only
|
| 239 |
return static_cast<T&>(t);
|
| 240 |
}
|
| 241 |
+
|
| 242 |
+
template<bool Const, class... Views>
|
| 243 |
+
concept all-random-access = // exposition only
|
| 244 |
+
(random_access_range<maybe-const<Const, Views>> && ...);
|
| 245 |
+
template<bool Const, class... Views>
|
| 246 |
+
concept all-bidirectional = // exposition only
|
| 247 |
+
(bidirectional_range<maybe-const<Const, Views>> && ...);
|
| 248 |
+
template<bool Const, class... Views>
|
| 249 |
+
concept all-forward = // exposition only
|
| 250 |
+
(forward_range<maybe-const<Const, Views>> && ...);
|
| 251 |
}
|
| 252 |
```
|
| 253 |
|
| 254 |
### All view <a id="range.all">[[range.all]]</a>
|
| 255 |
|
|
|
|
| 293 |
{ return ranges::empty(*r_); }
|
| 294 |
|
| 295 |
constexpr auto size() const requires sized_range<R>
|
| 296 |
{ return ranges::size(*r_); }
|
| 297 |
|
| 298 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<R>
|
| 299 |
+
{ return ranges::reserve_hint(*r_); }
|
| 300 |
+
|
| 301 |
constexpr auto data() const requires contiguous_range<R>
|
| 302 |
{ return ranges::data(*r_); }
|
| 303 |
};
|
| 304 |
|
| 305 |
template<class R>
|
|
|
|
| 369 |
constexpr auto size() requires sized_range<R>
|
| 370 |
{ return ranges::size(r_); }
|
| 371 |
constexpr auto size() const requires sized_range<const R>
|
| 372 |
{ return ranges::size(r_); }
|
| 373 |
|
| 374 |
+
constexpr auto reserve_hint() requires approximately_sized_range<R>
|
| 375 |
+
{ return ranges::reserve_hint(r_); }
|
| 376 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const R>
|
| 377 |
+
{ return ranges::reserve_hint(r_); }
|
| 378 |
+
|
| 379 |
constexpr auto data() requires contiguous_range<R>
|
| 380 |
{ return ranges::data(r_); }
|
| 381 |
constexpr auto data() const requires contiguous_range<const R>
|
| 382 |
{ return ranges::data(r_); }
|
| 383 |
};
|
|
|
|
| 402 |
The name `views::as_rvalue` denotes a range adaptor object
|
| 403 |
[[range.adaptor.object]]. Let `E` be an expression and let `T` be
|
| 404 |
`decltype((E))`. The expression `views::as_rvalue(E)` is
|
| 405 |
expression-equivalent to:
|
| 406 |
|
| 407 |
+
- `views::all(E)` if `T` models `input_range` and
|
| 408 |
`same_as<range_rvalue_reference_t<T>, range_reference_t<T>>` is
|
| 409 |
`true`.
|
| 410 |
- Otherwise, `as_rvalue_view(E)`.
|
| 411 |
|
| 412 |
[*Example 1*:
|
|
|
|
| 456 |
}
|
| 457 |
}
|
| 458 |
|
| 459 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 460 |
constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
|
| 461 |
+
|
| 462 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>
|
| 463 |
+
{ return ranges::reserve_hint(base_); }
|
| 464 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>
|
| 465 |
+
{ return ranges::reserve_hint(base_); }
|
| 466 |
};
|
| 467 |
|
| 468 |
template<class R>
|
| 469 |
as_rvalue_view(R&&) -> as_rvalue_view<views::all_t<R>>;
|
| 470 |
}
|
|
|
|
| 848 |
regular_invocable<const F&, range_reference_t<const V>>;
|
| 849 |
|
| 850 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 851 |
constexpr auto size() const requires sized_range<const V>
|
| 852 |
{ return ranges::size(base_); }
|
| 853 |
+
|
| 854 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>
|
| 855 |
+
{ return ranges::reserve_hint(base_); }
|
| 856 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>
|
| 857 |
+
{ return ranges::reserve_hint(base_); }
|
| 858 |
};
|
| 859 |
|
| 860 |
template<class R, class F>
|
| 861 |
transform_view(R&&, F) -> transform_view<views::all_t<R>, F>;
|
| 862 |
}
|
|
|
|
| 1436 |
|
| 1437 |
constexpr auto size() const requires sized_range<const V> {
|
| 1438 |
auto n = ranges::size(base_);
|
| 1439 |
return ranges::min(n, static_cast<decltype(n)>(count_));
|
| 1440 |
}
|
| 1441 |
+
|
| 1442 |
+
constexpr auto reserve_hint() {
|
| 1443 |
+
if constexpr (approximately_sized_range<V>) {
|
| 1444 |
+
auto n = static_cast<range_difference_t<V>>(ranges::reserve_hint(base_));
|
| 1445 |
+
return to-unsigned-like(ranges::min(n, count_));
|
| 1446 |
+
}
|
| 1447 |
+
return to-unsigned-like(count_);
|
| 1448 |
+
}
|
| 1449 |
+
|
| 1450 |
+
constexpr auto reserve_hint() const {
|
| 1451 |
+
if constexpr (approximately_sized_range<const V>) {
|
| 1452 |
+
auto n = static_cast<range_difference_t<const V>>(ranges::reserve_hint(base_));
|
| 1453 |
+
return to-unsigned-like(ranges::min(n, count_));
|
| 1454 |
+
}
|
| 1455 |
+
return to-unsigned-like(count_);
|
| 1456 |
+
}
|
| 1457 |
};
|
| 1458 |
|
| 1459 |
template<class R>
|
| 1460 |
take_view(R&&, range_difference_t<R>)
|
| 1461 |
-> take_view<views::all_t<R>>;
|
|
|
|
| 1705 |
then
|
| 1706 |
`U(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::end(E))`,
|
| 1707 |
except that `E` is evaluated only once, where `U` is
|
| 1708 |
`span<typename T::element_type>` if `T` is a specialization of `span`
|
| 1709 |
and `T` otherwise.
|
| 1710 |
+
- Otherwise, if `T` is a specialization of `subrange` that models
|
| 1711 |
+
`random_access_range` and `sized_range`, then
|
| 1712 |
`T(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::{}end(E),
|
| 1713 |
to-unsigned-like(ranges::distance(E) -
|
| 1714 |
std::min<D>(ranges::distance(E), F)))`, except that `E` and `F` are
|
| 1715 |
each evaluated only once.
|
| 1716 |
- Otherwise, if `T` is a specialization of `repeat_view`
|
|
|
|
| 1771 |
const auto s = ranges::size(base_);
|
| 1772 |
const auto c = static_cast<decltype(s)>(count_);
|
| 1773 |
return s < c ? 0 : s - c;
|
| 1774 |
}
|
| 1775 |
|
| 1776 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V> {
|
| 1777 |
+
const auto s = static_cast<range_difference_t<V>>(ranges::reserve_hint(base_));
|
| 1778 |
+
return to-unsigned-like(s < count_ ? 0 : s - count_);
|
| 1779 |
+
}
|
| 1780 |
+
|
| 1781 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V> {
|
| 1782 |
+
const auto s = static_cast<range_difference_t<const V>>(ranges::reserve_hint(base_));
|
| 1783 |
+
return to-unsigned-like(s < count_ ? 0 : s - count_);
|
| 1784 |
+
}
|
| 1785 |
+
|
| 1786 |
private:
|
| 1787 |
V base_ = V(); // exposition only
|
| 1788 |
range_difference_t<V> count_ = 0; // exposition only
|
| 1789 |
};
|
| 1790 |
|
|
|
|
| 2287 |
noexcept(noexcept(ranges::iter_swap(*x.inner_, *y.inner_)))
|
| 2288 |
requires indirectly_swappable<InnerIter>;
|
| 2289 |
```
|
| 2290 |
|
| 2291 |
*Effects:* Equivalent to:
|
| 2292 |
+
`ranges::iter_swap(*x.`*`inner_`*`, *y.`*`inner_`*`);`
|
| 2293 |
|
| 2294 |
#### Class template `join_view::sentinel` <a id="range.join.sentinel">[[range.join.sentinel]]</a>
|
| 2295 |
|
| 2296 |
``` cpp
|
| 2297 |
namespace std::ranges {
|
|
|
|
| 2366 |
|
| 2367 |
#### Class template `join_with_view` <a id="range.join.with.view">[[range.join.with.view]]</a>
|
| 2368 |
|
| 2369 |
``` cpp
|
| 2370 |
namespace std::ranges {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2371 |
template<class R>
|
| 2372 |
concept bidirectional-common = bidirectional_range<R> && common_range<R>; // exposition only
|
| 2373 |
|
| 2374 |
template<input_range V, forward_range Pattern>
|
| 2375 |
requires view<V> && input_range<range_reference_t<V>>
|
| 2376 |
&& view<Pattern>
|
| 2377 |
+
&& concatable<range_reference_t<V>, Pattern>
|
| 2378 |
class join_with_view : public view_interface<join_with_view<V, Pattern>> {
|
| 2379 |
using InnerRng = range_reference_t<V>; // exposition only
|
| 2380 |
|
| 2381 |
V base_ = V(); // exposition only
|
| 2382 |
non-propagating-cache<iterator_t<V>> outer_it_; // exposition only, present only
|
|
|
|
| 2418 |
}
|
| 2419 |
constexpr auto begin() const
|
| 2420 |
requires forward_range<const V> &&
|
| 2421 |
forward_range<const Pattern> &&
|
| 2422 |
is_reference_v<range_reference_t<const V>> &&
|
| 2423 |
+
input_range<range_reference_t<const V>> &&
|
| 2424 |
+
concatable<range_reference_t<const V>, const Pattern> {
|
| 2425 |
return iterator<true>{*this, ranges::begin(base_)};
|
| 2426 |
}
|
| 2427 |
|
| 2428 |
constexpr auto end() {
|
| 2429 |
if constexpr (forward_range<V> &&
|
|
|
|
| 2434 |
return sentinel<simple-view<V> && simple-view<Pattern>>{*this};
|
| 2435 |
}
|
| 2436 |
constexpr auto end() const
|
| 2437 |
requires forward_range<const V> && forward_range<const Pattern> &&
|
| 2438 |
is_reference_v<range_reference_t<const V>> &&
|
| 2439 |
+
input_range<range_reference_t<const V>> &&
|
| 2440 |
+
concatable<range_reference_t<const V>, const Pattern> {
|
| 2441 |
using InnerConstRng = range_reference_t<const V>;
|
| 2442 |
if constexpr (forward_range<InnerConstRng> &&
|
| 2443 |
common_range<const V> && common_range<InnerConstRng>)
|
| 2444 |
return iterator<true>{*this, ranges::end(base_)};
|
| 2445 |
else
|
|
|
|
| 2477 |
|
| 2478 |
``` cpp
|
| 2479 |
namespace std::ranges {
|
| 2480 |
template<input_range V, forward_range Pattern>
|
| 2481 |
requires view<V> && input_range<range_reference_t<V>>
|
| 2482 |
+
&& view<Pattern> && concatable<range_reference_t<V>, Pattern>
|
| 2483 |
template<bool Const>
|
| 2484 |
class join_with_view<V, Pattern>::iterator {
|
| 2485 |
using Parent = maybe-const<Const, join_with_view>; // exposition only
|
| 2486 |
using Base = maybe-const<Const, V>; // exposition only
|
| 2487 |
using InnerBase = range_reference_t<Base>; // exposition only
|
|
|
|
| 2580 |
iter_reference_t<PatternIter>>>
|
| 2581 |
```
|
| 2582 |
|
| 2583 |
is `false`, `iterator_category` denotes `input_iterator_tag`.
|
| 2584 |
- Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
|
| 2585 |
+
`derived_from<bidirectional_iterator_tag>` and *`InnerBase`* and
|
| 2586 |
*`PatternBase`* each model `common_range`, `iterator_category` denotes
|
| 2587 |
`bidirectional_iterator_tag`.
|
| 2588 |
- Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
|
| 2589 |
`derived_from<forward_iterator_tag>`, `iterator_category` denotes
|
| 2590 |
`forward_iterator_tag`.
|
|
|
|
| 2648 |
``` cpp
|
| 2649 |
while (true) {
|
| 2650 |
if (inner_it_.index() == 0) {
|
| 2651 |
if (std::get<0>(inner_it_) != ranges::end(parent_->pattern_))
|
| 2652 |
break;
|
| 2653 |
+
inner_it_.template emplace<1>(ranges::begin(update-inner()));
|
| 2654 |
} else {
|
| 2655 |
if (std::get<1>(inner_it_) != ranges::end(get-inner()))
|
| 2656 |
break;
|
| 2657 |
if (++outer() == ranges::end(parent_->base_)) {
|
| 2658 |
if constexpr (ref-is-glvalue)
|
| 2659 |
+
inner_it_.template emplace<0>();
|
| 2660 |
break;
|
| 2661 |
}
|
| 2662 |
+
inner_it_.template emplace<0>(ranges::begin(parent_->pattern_));
|
| 2663 |
}
|
| 2664 |
}
|
| 2665 |
```
|
| 2666 |
|
| 2667 |
[*Note 1*: `join_with_view` iterators use the *satisfy* function to
|
|
|
|
| 2678 |
first overload, also initializes *outer_it\_* with `std::move(outer)`.
|
| 2679 |
Then, equivalent to:
|
| 2680 |
|
| 2681 |
``` cpp
|
| 2682 |
if (outer() != ranges::end(parent_->base_)) {
|
| 2683 |
+
inner_it_.template emplace<1>(ranges::begin(update-inner()));
|
| 2684 |
satisfy();
|
| 2685 |
}
|
| 2686 |
```
|
| 2687 |
|
| 2688 |
``` cpp
|
|
|
|
| 2695 |
*Effects:* Initializes *outer_it\_* with `std::move(i.`*`outer_it_`*`)`
|
| 2696 |
and *parent\_* with `i.`*`parent_`*. Then, equivalent to:
|
| 2697 |
|
| 2698 |
``` cpp
|
| 2699 |
if (i.inner_it_.index() == 0)
|
| 2700 |
+
inner_it_.template emplace<0>(std::get<0>(std::move(i.inner_it_)));
|
| 2701 |
else
|
| 2702 |
+
inner_it_.template emplace<1>(std::get<1>(std::move(i.inner_it_)));
|
| 2703 |
```
|
| 2704 |
|
| 2705 |
[*Note 2*: `Const` can only be `true` when *Base* models
|
| 2706 |
`forward_range`. — *end note*]
|
| 2707 |
|
|
|
|
| 2757 |
*Effects:* Equivalent to:
|
| 2758 |
|
| 2759 |
``` cpp
|
| 2760 |
if (outer_it_ == ranges::end(parent_->base_)) {
|
| 2761 |
auto&& inner = *--outer_it_;
|
| 2762 |
+
inner_it_.template emplace<1>(ranges::end(inner));
|
| 2763 |
}
|
| 2764 |
|
| 2765 |
while (true) {
|
| 2766 |
if (inner_it_.index() == 0) {
|
| 2767 |
auto& it = std::get<0>(inner_it_);
|
| 2768 |
if (it == ranges::begin(parent_->pattern_)) {
|
| 2769 |
auto&& inner = *--outer_it_;
|
| 2770 |
+
inner_it_.template emplace<1>(ranges::end(inner));
|
| 2771 |
} else {
|
| 2772 |
break;
|
| 2773 |
}
|
| 2774 |
} else {
|
| 2775 |
auto& it = std::get<1>(inner_it_);
|
| 2776 |
auto&& inner = *outer_it_;
|
| 2777 |
if (it == ranges::begin(inner)) {
|
| 2778 |
+
inner_it_.template emplace<0>(ranges::end(parent_->pattern_));
|
| 2779 |
} else {
|
| 2780 |
break;
|
| 2781 |
}
|
| 2782 |
}
|
| 2783 |
}
|
|
|
|
| 2815 |
|
| 2816 |
``` cpp
|
| 2817 |
namespace std::ranges {
|
| 2818 |
template<input_range V, forward_range Pattern>
|
| 2819 |
requires view<V> && input_range<range_reference_t<V>>
|
| 2820 |
+
&& view<Pattern> && concatable<range_reference_t<V>, Pattern>
|
| 2821 |
template<bool Const>
|
| 2822 |
class join_with_view<V, Pattern>::sentinel {
|
| 2823 |
using Parent = maybe-const<Const, join_with_view>; // exposition only
|
| 2824 |
using Base = maybe-const<Const, V>; // exposition only
|
| 2825 |
sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
|
|
|
|
| 3064 |
``` cpp
|
| 3065 |
constexpr outer-iterator(outer-iterator<!Const> i)
|
| 3066 |
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
|
| 3067 |
```
|
| 3068 |
|
| 3069 |
+
*Effects:* Initializes *parent\_* with `i.`*`parent_`*, *current\_* with
|
| 3070 |
+
`std::move(i.`*`current_`*`)`, and *trailing_empty\_* with
|
| 3071 |
+
`i.`*`trailing_empty_`*.
|
| 3072 |
|
| 3073 |
``` cpp
|
| 3074 |
constexpr value_type operator*() const;
|
| 3075 |
```
|
| 3076 |
|
|
|
|
| 3145 |
struct lazy_split_view<V, Pattern>::outer-iterator<Const>::value_type
|
| 3146 |
: view_interface<value_type> {
|
| 3147 |
private:
|
| 3148 |
outer-iterator i_ = outer-iterator(); // exposition only
|
| 3149 |
|
| 3150 |
+
constexpr explicit value_type(outer-iterator i); // exposition only
|
|
|
|
|
|
|
| 3151 |
|
| 3152 |
+
public:
|
| 3153 |
constexpr inner-iterator<Const> begin() const;
|
| 3154 |
constexpr default_sentinel_t end() const noexcept;
|
| 3155 |
};
|
| 3156 |
}
|
| 3157 |
```
|
|
|
|
| 3189 |
using Base = maybe-const<Const, V>; // exposition only
|
| 3190 |
outer-iterator<Const> i_ = outer-iterator<Const>(); // exposition only
|
| 3191 |
bool incremented_ = false; // exposition only
|
| 3192 |
|
| 3193 |
public:
|
| 3194 |
+
using iterator_concept = outer-iterator<Const>::iterator_concept;
|
| 3195 |
|
| 3196 |
using iterator_category = see belownc; // present only if Base
|
| 3197 |
// models forward_range
|
| 3198 |
using value_type = range_value_t<Base>;
|
| 3199 |
using difference_type = range_difference_t<Base>;
|
|
|
|
| 3484 |
|
| 3485 |
``` cpp
|
| 3486 |
constexpr iterator_t<V> base() const;
|
| 3487 |
```
|
| 3488 |
|
| 3489 |
+
*Effects:* Equivalent to: `return `*`cur_`*`;`
|
| 3490 |
|
| 3491 |
``` cpp
|
| 3492 |
constexpr value_type operator*() const;
|
| 3493 |
```
|
| 3494 |
|
| 3495 |
+
*Effects:* Equivalent to: `return {`*`cur_`*`, `*`next_`*`.begin()};`
|
| 3496 |
|
| 3497 |
``` cpp
|
| 3498 |
constexpr iterator& operator++();
|
| 3499 |
```
|
| 3500 |
|
|
|
|
| 3569 |
```
|
| 3570 |
|
| 3571 |
*Effects:* Equivalent to:
|
| 3572 |
`return x.`*`cur_`*` == y.`*`end_`*` && !x.`*`trailing_empty_`*`;`
|
| 3573 |
|
| 3574 |
+
### Concat view <a id="range.concat">[[range.concat]]</a>
|
| 3575 |
+
|
| 3576 |
+
#### Overview <a id="range.concat.overview">[[range.concat.overview]]</a>
|
| 3577 |
+
|
| 3578 |
+
`concat_view` presents a view that concatenates all the underlying
|
| 3579 |
+
ranges.
|
| 3580 |
+
|
| 3581 |
+
The name `views::concat` denotes a customization point object
|
| 3582 |
+
[[customization.point.object]]. Given a pack of subexpressions `Es...`,
|
| 3583 |
+
the expression `views::concat(Es...)` is expression-equivalent to
|
| 3584 |
+
|
| 3585 |
+
- `views::all(Es...)` if `Es` is a pack with only one element whose type
|
| 3586 |
+
models `input_range`,
|
| 3587 |
+
- otherwise, `concat_view(Es...)`.
|
| 3588 |
+
|
| 3589 |
+
[*Example 1*:
|
| 3590 |
+
|
| 3591 |
+
``` cpp
|
| 3592 |
+
vector<int> v1{1, 2, 3}, v2{4, 5}, v3{};
|
| 3593 |
+
array a{6, 7, 8};
|
| 3594 |
+
auto s = views::single(9);
|
| 3595 |
+
for (auto&& i : views::concat(v1, v2, v3, a, s)) {
|
| 3596 |
+
print("{} ", i); // prints 1 2 3 4 5 6 7 8 9
|
| 3597 |
+
}
|
| 3598 |
+
```
|
| 3599 |
+
|
| 3600 |
+
— *end example*]
|
| 3601 |
+
|
| 3602 |
+
#### Class template `concat_view` <a id="range.concat.view">[[range.concat.view]]</a>
|
| 3603 |
+
|
| 3604 |
+
``` cpp
|
| 3605 |
+
namespace std::ranges {
|
| 3606 |
+
template<class... Rs>
|
| 3607 |
+
using concat-reference-t = common_reference_t<range_reference_t<Rs>...>; // exposition only
|
| 3608 |
+
template<class... Rs>
|
| 3609 |
+
using concat-value-t = common_type_t<range_value_t<Rs>...>; // exposition only
|
| 3610 |
+
template<class... Rs>
|
| 3611 |
+
using concat-rvalue-reference-t = // exposition only
|
| 3612 |
+
common_reference_t<range_rvalue_reference_t<Rs>...>;
|
| 3613 |
+
|
| 3614 |
+
template<class... Rs>
|
| 3615 |
+
concept concat-indirectly-readable = see below; // exposition only
|
| 3616 |
+
template<class... Rs>
|
| 3617 |
+
concept concatable = see below; // exposition only
|
| 3618 |
+
template<bool Const, class... Rs>
|
| 3619 |
+
concept concat-is-random-access = see below; // exposition only
|
| 3620 |
+
template<bool Const, class... Rs>
|
| 3621 |
+
concept concat-is-bidirectional = see below; // exposition only
|
| 3622 |
+
|
| 3623 |
+
template<input_range... Views>
|
| 3624 |
+
requires (view<Views> && ...) && (sizeof...(Views) > 0) &&
|
| 3625 |
+
concatable<Views...>
|
| 3626 |
+
class concat_view : public view_interface<concat_view<Views...>> {
|
| 3627 |
+
|
| 3628 |
+
tuple<Views...> views_; // exposition only
|
| 3629 |
+
|
| 3630 |
+
// [range.concat.iterator], class template concat_view::iterator
|
| 3631 |
+
template<bool> class iterator; // exposition only
|
| 3632 |
+
|
| 3633 |
+
public:
|
| 3634 |
+
constexpr concat_view() = default;
|
| 3635 |
+
constexpr explicit concat_view(Views... views);
|
| 3636 |
+
|
| 3637 |
+
constexpr iterator<false> begin() requires (!(simple-view<Views> && ...));
|
| 3638 |
+
constexpr iterator<true> begin() const
|
| 3639 |
+
requires (range<const Views> && ...) && concatable<const Views...>;
|
| 3640 |
+
|
| 3641 |
+
constexpr auto end() requires (!(simple-view<Views> && ...));
|
| 3642 |
+
constexpr auto end() const
|
| 3643 |
+
requires (range<const Views> && ...) && concatable<const Views...>;
|
| 3644 |
+
|
| 3645 |
+
constexpr auto size() requires (sized_range<Views> && ...);
|
| 3646 |
+
constexpr auto size() const requires (sized_range<const Views> && ...);
|
| 3647 |
+
};
|
| 3648 |
+
|
| 3649 |
+
template<class... R>
|
| 3650 |
+
concat_view(R&&...) -> concat_view<views::all_t<R>...>;
|
| 3651 |
+
}
|
| 3652 |
+
```
|
| 3653 |
+
|
| 3654 |
+
``` cpp
|
| 3655 |
+
template<class... Rs>
|
| 3656 |
+
concept concat-indirectly-readable = see below; // exposition only
|
| 3657 |
+
```
|
| 3658 |
+
|
| 3659 |
+
The exposition-only `concat-indirectly-readable` concept is equivalent
|
| 3660 |
+
to:
|
| 3661 |
+
|
| 3662 |
+
``` cpp
|
| 3663 |
+
template<class Ref, class RRef, class It>
|
| 3664 |
+
concept concat-indirectly-readable-impl = // exposition only
|
| 3665 |
+
requires (const It it) {
|
| 3666 |
+
{ *it } -> convertible_to<Ref>;
|
| 3667 |
+
{ ranges::iter_move(it) } -> convertible_to<RRef>;
|
| 3668 |
+
};
|
| 3669 |
+
|
| 3670 |
+
template<class... Rs>
|
| 3671 |
+
concept concat-indirectly-readable = // exposition only
|
| 3672 |
+
common_reference_with<concat-reference-t<Rs...>&&,
|
| 3673 |
+
concat-value-t<Rs...>&> &&
|
| 3674 |
+
common_reference_with<concat-reference-t<Rs...>&&,
|
| 3675 |
+
concat-rvalue-reference-t<Rs...>&&> &&
|
| 3676 |
+
common_reference_with<concat-rvalue-reference-t<Rs...>&&,
|
| 3677 |
+
concat-value-t<Rs...> const&> &&
|
| 3678 |
+
(concat-indirectly-readable-impl<concat-reference-t<Rs...>,
|
| 3679 |
+
concat-rvalue-reference-t<Rs...>,
|
| 3680 |
+
iterator_t<Rs>> && ...);
|
| 3681 |
+
```
|
| 3682 |
+
|
| 3683 |
+
``` cpp
|
| 3684 |
+
template<class... Rs>
|
| 3685 |
+
concept concatable = see below; // exposition only
|
| 3686 |
+
```
|
| 3687 |
+
|
| 3688 |
+
The exposition-only `concatable` concept is equivalent to:
|
| 3689 |
+
|
| 3690 |
+
``` cpp
|
| 3691 |
+
template<class... Rs>
|
| 3692 |
+
concept concatable = requires { // exposition only
|
| 3693 |
+
typename concat-reference-t<Rs...>;
|
| 3694 |
+
typename concat-value-t<Rs...>;
|
| 3695 |
+
typename concat-rvalue-reference-t<Rs...>;
|
| 3696 |
+
} && concat-indirectly-readable<Rs...>;
|
| 3697 |
+
```
|
| 3698 |
+
|
| 3699 |
+
``` cpp
|
| 3700 |
+
template<bool Const, class... Rs>
|
| 3701 |
+
concept concat-is-random-access = see below; // exposition only
|
| 3702 |
+
```
|
| 3703 |
+
|
| 3704 |
+
Let `Fs` be the pack that consists of all elements of `Rs` except the
|
| 3705 |
+
last element, then *`concat-is-random-access`* is equivalent to:
|
| 3706 |
+
|
| 3707 |
+
``` cpp
|
| 3708 |
+
template<bool Const, class... Rs>
|
| 3709 |
+
concept concat-is-random-access = // exposition only
|
| 3710 |
+
all-random-access<Const, Rs...> &&
|
| 3711 |
+
(common_range<maybe-const<Const, Fs>> && ...);
|
| 3712 |
+
```
|
| 3713 |
+
|
| 3714 |
+
``` cpp
|
| 3715 |
+
template<bool Const, class... Rs>
|
| 3716 |
+
concept concat-is-bidirectional = see below; // exposition only
|
| 3717 |
+
```
|
| 3718 |
+
|
| 3719 |
+
Let `Fs` be the pack that consists of all elements of `Rs` except the
|
| 3720 |
+
last element, then *`concat-is-bidirectional`* is equivalent to:
|
| 3721 |
+
|
| 3722 |
+
``` cpp
|
| 3723 |
+
template<bool Const, class... Rs>
|
| 3724 |
+
concept concat-is-bidirectional = // exposition only
|
| 3725 |
+
all-bidirectional<Const, Rs...> &&
|
| 3726 |
+
(common_range<maybe-const<Const, Fs>> && ...);
|
| 3727 |
+
```
|
| 3728 |
+
|
| 3729 |
+
``` cpp
|
| 3730 |
+
constexpr explicit concat_view(Views... views);
|
| 3731 |
+
```
|
| 3732 |
+
|
| 3733 |
+
*Effects:* Initializes *views\_* with `std::move(views)...`.
|
| 3734 |
+
|
| 3735 |
+
``` cpp
|
| 3736 |
+
constexpr iterator<false> begin() requires (!(simple-view<Views> && ...));
|
| 3737 |
+
constexpr iterator<true> begin() const
|
| 3738 |
+
requires (range<const Views> && ...) && concatable<const Views...>;
|
| 3739 |
+
```
|
| 3740 |
+
|
| 3741 |
+
*Effects:* Let *is-const* be `true` for the const-qualified overload,
|
| 3742 |
+
and `false` otherwise. Equivalent to:
|
| 3743 |
+
|
| 3744 |
+
``` cpp
|
| 3745 |
+
iterator<is-const> it(this, in_place_index<0>, ranges::begin(std::get<0>(views_)));
|
| 3746 |
+
it.template satisfy<0>();
|
| 3747 |
+
return it;
|
| 3748 |
+
```
|
| 3749 |
+
|
| 3750 |
+
``` cpp
|
| 3751 |
+
constexpr auto end() requires (!(simple-view<Views> && ...));
|
| 3752 |
+
constexpr auto end() const
|
| 3753 |
+
requires (range<const Views> && ...) && concatable<const Views...>;
|
| 3754 |
+
```
|
| 3755 |
+
|
| 3756 |
+
*Effects:* Let *is-const* be `true` for the const-qualified overload,
|
| 3757 |
+
and `false` otherwise. Equivalent to:
|
| 3758 |
+
|
| 3759 |
+
``` cpp
|
| 3760 |
+
constexpr auto N = sizeof...(Views);
|
| 3761 |
+
if constexpr (common_range<maybe-const<is-const, Views...[N - 1]>>) {
|
| 3762 |
+
return iterator<is-const>(this, in_place_index<N - 1>,
|
| 3763 |
+
ranges::end(std::get<N - 1>(views_)));
|
| 3764 |
+
} else {
|
| 3765 |
+
return default_sentinel;
|
| 3766 |
+
}
|
| 3767 |
+
```
|
| 3768 |
+
|
| 3769 |
+
``` cpp
|
| 3770 |
+
constexpr auto size() requires (sized_range<Views> && ...);
|
| 3771 |
+
constexpr auto size() const requires (sized_range<const Views> && ...);
|
| 3772 |
+
```
|
| 3773 |
+
|
| 3774 |
+
*Effects:* Equivalent to:
|
| 3775 |
+
|
| 3776 |
+
``` cpp
|
| 3777 |
+
return apply(
|
| 3778 |
+
[](auto... sizes) {
|
| 3779 |
+
using CT = make-unsigned-like-t<common_type_t<decltype(sizes)...>>;
|
| 3780 |
+
return (CT(sizes) + ...);
|
| 3781 |
+
},
|
| 3782 |
+
tuple-transform(ranges::size, views_));
|
| 3783 |
+
```
|
| 3784 |
+
|
| 3785 |
+
#### Class `concat_view::iterator` <a id="range.concat.iterator">[[range.concat.iterator]]</a>
|
| 3786 |
+
|
| 3787 |
+
``` cpp
|
| 3788 |
+
namespace std::ranges {
|
| 3789 |
+
template<input_range... Views>
|
| 3790 |
+
requires (view<Views> && ...) && (sizeof...(Views) > 0) &&
|
| 3791 |
+
concatable<Views...>
|
| 3792 |
+
template<bool Const>
|
| 3793 |
+
class concat_view<Views...>::iterator {
|
| 3794 |
+
|
| 3795 |
+
public:
|
| 3796 |
+
using iterator_category = see below; // not always present
|
| 3797 |
+
using iterator_concept = see below;
|
| 3798 |
+
using value_type = concat-value-t<maybe-const<Const, Views>...>;
|
| 3799 |
+
using difference_type = common_type_t<range_difference_t<maybe-const<Const, Views>>...>;
|
| 3800 |
+
|
| 3801 |
+
private:
|
| 3802 |
+
using base-iter = // exposition only
|
| 3803 |
+
variant<iterator_t<maybe-const<Const, Views>>...>;
|
| 3804 |
+
|
| 3805 |
+
maybe-const<Const, concat_view>* parent_ = nullptr; // exposition only
|
| 3806 |
+
base-iter it_; // exposition only
|
| 3807 |
+
|
| 3808 |
+
template<size_t N>
|
| 3809 |
+
constexpr void satisfy(); // exposition only
|
| 3810 |
+
template<size_t N>
|
| 3811 |
+
constexpr void prev(); // exposition only
|
| 3812 |
+
|
| 3813 |
+
template<size_t N>
|
| 3814 |
+
constexpr void advance-fwd(difference_type offset, // exposition only
|
| 3815 |
+
difference_type steps);
|
| 3816 |
+
template<size_t N>
|
| 3817 |
+
constexpr void advance-bwd(difference_type offset, // exposition only
|
| 3818 |
+
difference_type steps);
|
| 3819 |
+
|
| 3820 |
+
template<class... Args>
|
| 3821 |
+
constexpr explicit iterator(maybe-const<Const, concat_view>* parent, // exposition only
|
| 3822 |
+
Args&&... args)
|
| 3823 |
+
requires constructible_from<base-iter, Args&&...>;
|
| 3824 |
+
|
| 3825 |
+
public:
|
| 3826 |
+
iterator() = default;
|
| 3827 |
+
|
| 3828 |
+
constexpr iterator(iterator<!Const> i)
|
| 3829 |
+
requires Const && (convertible_to<iterator_t<Views>, iterator_t<const Views>> && ...);
|
| 3830 |
+
|
| 3831 |
+
constexpr decltype(auto) operator*() const;
|
| 3832 |
+
constexpr iterator& operator++();
|
| 3833 |
+
constexpr void operator++(int);
|
| 3834 |
+
constexpr iterator operator++(int)
|
| 3835 |
+
requires all-forward<Const, Views...>;
|
| 3836 |
+
constexpr iterator& operator--()
|
| 3837 |
+
requires concat-is-bidirectional<Const, Views...>;
|
| 3838 |
+
constexpr iterator operator--(int)
|
| 3839 |
+
requires concat-is-bidirectional<Const, Views...>;
|
| 3840 |
+
constexpr iterator& operator+=(difference_type n)
|
| 3841 |
+
requires concat-is-random-access<Const, Views...>;
|
| 3842 |
+
constexpr iterator& operator-=(difference_type n)
|
| 3843 |
+
requires concat-is-random-access<Const, Views...>;
|
| 3844 |
+
constexpr decltype(auto) operator[](difference_type n) const
|
| 3845 |
+
requires concat-is-random-access<Const, Views...>;
|
| 3846 |
+
|
| 3847 |
+
friend constexpr bool operator==(const iterator& x, const iterator& y)
|
| 3848 |
+
requires (equality_comparable<iterator_t<maybe-const<Const, Views>>> && ...);
|
| 3849 |
+
friend constexpr bool operator==(const iterator& it, default_sentinel_t);
|
| 3850 |
+
friend constexpr bool operator<(const iterator& x, const iterator& y)
|
| 3851 |
+
requires all-random-access<Const, Views...>;
|
| 3852 |
+
friend constexpr bool operator>(const iterator& x, const iterator& y)
|
| 3853 |
+
requires all-random-access<Const, Views...>;
|
| 3854 |
+
friend constexpr bool operator<=(const iterator& x, const iterator& y)
|
| 3855 |
+
requires all-random-access<Const, Views...>;
|
| 3856 |
+
friend constexpr bool operator>=(const iterator& x, const iterator& y)
|
| 3857 |
+
requires all-random-access<Const, Views...>;
|
| 3858 |
+
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
|
| 3859 |
+
requires (all-random-access<Const, Views...> &&
|
| 3860 |
+
(three_way_comparable<iterator_t<maybe-const<Const, Views>>> && ...));
|
| 3861 |
+
friend constexpr iterator operator+(const iterator& it, difference_type n)
|
| 3862 |
+
requires concat-is-random-access<Const, Views...>;
|
| 3863 |
+
friend constexpr iterator operator+(difference_type n, const iterator& it)
|
| 3864 |
+
requires concat-is-random-access<Const, Views...>;
|
| 3865 |
+
friend constexpr iterator operator-(const iterator& it, difference_type n)
|
| 3866 |
+
requires concat-is-random-access<Const, Views...>;
|
| 3867 |
+
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
|
| 3868 |
+
requires concat-is-random-access<Const, Views...>;
|
| 3869 |
+
friend constexpr difference_type operator-(const iterator& x, default_sentinel_t)
|
| 3870 |
+
requires see below;
|
| 3871 |
+
friend constexpr difference_type operator-(default_sentinel_t, const iterator& x)
|
| 3872 |
+
requires see below;
|
| 3873 |
+
friend constexpr decltype(auto) iter_move(const iterator& it) noexcept(see below);
|
| 3874 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(see below)
|
| 3875 |
+
requires see below;
|
| 3876 |
+
};
|
| 3877 |
+
}
|
| 3878 |
+
```
|
| 3879 |
+
|
| 3880 |
+
`iterator::iterator_concept` is defined as follows:
|
| 3881 |
+
|
| 3882 |
+
- If `concat-is-random-access<Const, Views...>` is modeled, then
|
| 3883 |
+
`iterator_concept` denotes `random_access_iterator_tag`.
|
| 3884 |
+
- Otherwise, if `concat-is-bidirectional<Const, Views...>` is modeled,
|
| 3885 |
+
then `iterator_concept` denotes `bidirectional_iterator_tag`.
|
| 3886 |
+
- Otherwise, if `all-forward<Const, Views...>` is modeled, then
|
| 3887 |
+
`iterator_concept` denotes `forward_iterator_tag`.
|
| 3888 |
+
- Otherwise, `iterator_concept` denotes `input_iterator_tag`.
|
| 3889 |
+
|
| 3890 |
+
The member *typedef-name* `iterator_category` is defined if and only if
|
| 3891 |
+
`all-forward<Const, Views...>` is modeled. In that case,
|
| 3892 |
+
`iterator::iterator_category` is defined as follows:
|
| 3893 |
+
|
| 3894 |
+
- If `is_reference_v<concat-reference-t<maybe-const<Const, Views>...>>`
|
| 3895 |
+
is `false`, then `iterator_category` denotes `input_iterator_tag`.
|
| 3896 |
+
- Otherwise, let `Cs` denote the pack of types
|
| 3897 |
+
`iterator_traits<iterator_t<maybe-const<Const, Views>>>::iterator_category...`.
|
| 3898 |
+
- If
|
| 3899 |
+
`(derived_from<Cs, random_access_iterator_tag> && ...) && concat-is-random-ac-{cess}<Const, Views...>`
|
| 3900 |
+
is `true`, `iterator_category` denotes `random_access_iterator_tag`.
|
| 3901 |
+
- Otherwise, if
|
| 3902 |
+
`(derived_from<Cs, bidirectional_iterator_tag> && ...) && concat-is-{bidirectional}<Const, Views...>`
|
| 3903 |
+
is `true`, `iterator_category` denotes `bidirectional_iterator_tag`.
|
| 3904 |
+
- Otherwise, if `(derived_from<Cs, forward_iterator_tag> && ...)` is
|
| 3905 |
+
`true`, `iterator_category` denotes `forward_iterator_tag`.
|
| 3906 |
+
- Otherwise, `iterator_category` denotes `input_iterator_tag`.
|
| 3907 |
+
|
| 3908 |
+
``` cpp
|
| 3909 |
+
template<size_t N>
|
| 3910 |
+
constexpr void satisfy();
|
| 3911 |
+
```
|
| 3912 |
+
|
| 3913 |
+
*Effects:* Equivalent to:
|
| 3914 |
+
|
| 3915 |
+
``` cpp
|
| 3916 |
+
if constexpr (N < (sizeof...(Views) - 1)) {
|
| 3917 |
+
if (std::get<N>(it_) == ranges::end(std::get<N>(parent_->views_))) {
|
| 3918 |
+
it_.template emplace<N + 1>(ranges::begin(std::get<N + 1>(parent_->views_)));
|
| 3919 |
+
satisfy<N + 1>();
|
| 3920 |
+
}
|
| 3921 |
+
}
|
| 3922 |
+
```
|
| 3923 |
+
|
| 3924 |
+
``` cpp
|
| 3925 |
+
template<size_t N>
|
| 3926 |
+
constexpr void prev();
|
| 3927 |
+
```
|
| 3928 |
+
|
| 3929 |
+
*Effects:* Equivalent to:
|
| 3930 |
+
|
| 3931 |
+
``` cpp
|
| 3932 |
+
if constexpr (N == 0) {
|
| 3933 |
+
--std::get<0>(it_);
|
| 3934 |
+
} else {
|
| 3935 |
+
if (std::get<N>(it_) == ranges::begin(std::get<N>(parent_->views_))) {
|
| 3936 |
+
it_.template emplace<N - 1>(ranges::end(std::get<N - 1>(parent_->views_)));
|
| 3937 |
+
prev<N - 1>();
|
| 3938 |
+
} else {
|
| 3939 |
+
--std::get<N>(it_);
|
| 3940 |
+
}
|
| 3941 |
+
}
|
| 3942 |
+
```
|
| 3943 |
+
|
| 3944 |
+
``` cpp
|
| 3945 |
+
template<size_t N>
|
| 3946 |
+
constexpr void advance-fwd(difference_type offset, difference_type steps);
|
| 3947 |
+
```
|
| 3948 |
+
|
| 3949 |
+
*Effects:* Equivalent to:
|
| 3950 |
+
|
| 3951 |
+
``` cpp
|
| 3952 |
+
using underlying_diff_type = iter_difference_t<variant_alternative_t<N, base-iter>>;
|
| 3953 |
+
if constexpr (N == sizeof...(Views) - 1) {
|
| 3954 |
+
std::get<N>(it_) += static_cast<underlying_diff_type>(steps);
|
| 3955 |
+
} else {
|
| 3956 |
+
auto n_size = ranges::distance(std::get<N>(parent_->views_));
|
| 3957 |
+
if (offset + steps < n_size) {
|
| 3958 |
+
std::get<N>(it_) += static_cast<underlying_diff_type>(steps);
|
| 3959 |
+
} else {
|
| 3960 |
+
it_.template emplace<N + 1>(ranges::begin(std::get<N + 1>(parent_->views_)));
|
| 3961 |
+
advance-fwd<N + 1>(0, offset + steps - n_size);
|
| 3962 |
+
}
|
| 3963 |
+
}
|
| 3964 |
+
```
|
| 3965 |
+
|
| 3966 |
+
``` cpp
|
| 3967 |
+
template<size_t N>
|
| 3968 |
+
constexpr void advance-bwd(difference_type offset, difference_type steps);
|
| 3969 |
+
```
|
| 3970 |
+
|
| 3971 |
+
*Effects:* Equivalent to:
|
| 3972 |
+
|
| 3973 |
+
``` cpp
|
| 3974 |
+
using underlying_diff_type = iter_difference_t<variant_alternative_t<N, base-iter>>;
|
| 3975 |
+
if constexpr (N == 0) {
|
| 3976 |
+
std::get<N>(it_) -= static_cast<underlying_diff_type>(steps);
|
| 3977 |
+
} else {
|
| 3978 |
+
if (offset >= steps) {
|
| 3979 |
+
std::get<N>(it_) -= static_cast<underlying_diff_type>(steps);
|
| 3980 |
+
} else {
|
| 3981 |
+
auto prev_size = ranges::distance(std::get<N - 1>(parent_->views_));
|
| 3982 |
+
it_.template emplace<N - 1>(ranges::end(std::get<N - 1>(parent_->views_)));
|
| 3983 |
+
advance-bwd<N - 1>(prev_size, steps - offset);
|
| 3984 |
+
}
|
| 3985 |
+
}
|
| 3986 |
+
```
|
| 3987 |
+
|
| 3988 |
+
``` cpp
|
| 3989 |
+
template<class... Args>
|
| 3990 |
+
constexpr explicit iterator(maybe-const<Const, concat_view>* parent,
|
| 3991 |
+
Args&&... args)
|
| 3992 |
+
requires constructible_from<base-iter, Args&&...>;
|
| 3993 |
+
```
|
| 3994 |
+
|
| 3995 |
+
*Effects:* Initializes *parent\_* with `parent`, and initializes *it\_*
|
| 3996 |
+
with `std::forward<Args>(args)...`.
|
| 3997 |
+
|
| 3998 |
+
``` cpp
|
| 3999 |
+
constexpr iterator(iterator<!Const> it)
|
| 4000 |
+
requires Const &&
|
| 4001 |
+
(convertible_to<iterator_t<Views>, iterator_t<const Views>> && ...);
|
| 4002 |
+
```
|
| 4003 |
+
|
| 4004 |
+
*Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
|
| 4005 |
+
|
| 4006 |
+
*Effects:* Initializes *parent\_* with `it.`*`parent_`*, and let i be
|
| 4007 |
+
`it.`*`it_`*`.index()`, initializes *it\_* with
|
| 4008 |
+
*`base-iter`*`(in_place_index<`i`>, std::get<`i`>(std::move(it.`*`it_`*`)))`.
|
| 4009 |
+
|
| 4010 |
+
``` cpp
|
| 4011 |
+
constexpr decltype(auto) operator*() const;
|
| 4012 |
+
```
|
| 4013 |
+
|
| 4014 |
+
*Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
|
| 4015 |
+
|
| 4016 |
+
*Effects:* Equivalent to:
|
| 4017 |
+
|
| 4018 |
+
``` cpp
|
| 4019 |
+
using reference = concat-reference-t<maybe-const<Const, Views>...>;
|
| 4020 |
+
return std::visit([](auto&& it) -> reference { return *it; },
|
| 4021 |
+
it_);
|
| 4022 |
+
```
|
| 4023 |
+
|
| 4024 |
+
``` cpp
|
| 4025 |
+
constexpr iterator& operator++();
|
| 4026 |
+
```
|
| 4027 |
+
|
| 4028 |
+
*Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
|
| 4029 |
+
|
| 4030 |
+
*Effects:* Let i be *`it_`*`.index()`. Equivalent to:
|
| 4031 |
+
|
| 4032 |
+
``` cpp
|
| 4033 |
+
++std::get<i>(it_);
|
| 4034 |
+
satisfy<i>();
|
| 4035 |
+
return *this;
|
| 4036 |
+
```
|
| 4037 |
+
|
| 4038 |
+
``` cpp
|
| 4039 |
+
constexpr void operator++(int);
|
| 4040 |
+
```
|
| 4041 |
+
|
| 4042 |
+
*Effects:* Equivalent to:
|
| 4043 |
+
|
| 4044 |
+
``` cpp
|
| 4045 |
+
++*this;
|
| 4046 |
+
```
|
| 4047 |
+
|
| 4048 |
+
``` cpp
|
| 4049 |
+
constexpr iterator operator++(int)
|
| 4050 |
+
requires all-forward<Const, Views...>;
|
| 4051 |
+
```
|
| 4052 |
+
|
| 4053 |
+
*Effects:* Equivalent to:
|
| 4054 |
+
|
| 4055 |
+
``` cpp
|
| 4056 |
+
auto tmp = *this;
|
| 4057 |
+
++*this;
|
| 4058 |
+
return tmp;
|
| 4059 |
+
```
|
| 4060 |
+
|
| 4061 |
+
``` cpp
|
| 4062 |
+
constexpr iterator& operator--()
|
| 4063 |
+
requires concat-is-bidirectional<Const, Views...>;
|
| 4064 |
+
```
|
| 4065 |
+
|
| 4066 |
+
*Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
|
| 4067 |
+
|
| 4068 |
+
*Effects:* Let i be *`it_`*`.index()`. Equivalent to:
|
| 4069 |
+
|
| 4070 |
+
``` cpp
|
| 4071 |
+
prev<i>();
|
| 4072 |
+
return *this;
|
| 4073 |
+
```
|
| 4074 |
+
|
| 4075 |
+
``` cpp
|
| 4076 |
+
constexpr iterator operator--(int)
|
| 4077 |
+
requires concat-is-bidirectional<Const, Views...>;
|
| 4078 |
+
```
|
| 4079 |
+
|
| 4080 |
+
*Effects:* Equivalent to:
|
| 4081 |
+
|
| 4082 |
+
``` cpp
|
| 4083 |
+
auto tmp = *this;
|
| 4084 |
+
--*this;
|
| 4085 |
+
return tmp;
|
| 4086 |
+
```
|
| 4087 |
+
|
| 4088 |
+
``` cpp
|
| 4089 |
+
constexpr iterator& operator+=(difference_type n)
|
| 4090 |
+
requires concat-is-random-access<Const, Views...>;
|
| 4091 |
+
```
|
| 4092 |
+
|
| 4093 |
+
*Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
|
| 4094 |
+
|
| 4095 |
+
*Effects:* Let i be *`it_`*`.index()`. Equivalent to:
|
| 4096 |
+
|
| 4097 |
+
``` cpp
|
| 4098 |
+
if (n > 0) {
|
| 4099 |
+
advance-fwd<i>(std::get<i>(it_) - ranges::begin(std::get<i>(parent_->views_)), n);
|
| 4100 |
+
} else if (n < 0) {
|
| 4101 |
+
advance-bwd<i>(std::get<i>(it_) - ranges::begin(std::get<i>(parent_->views_)), -n);
|
| 4102 |
+
}
|
| 4103 |
+
return *this;
|
| 4104 |
+
```
|
| 4105 |
+
|
| 4106 |
+
``` cpp
|
| 4107 |
+
constexpr iterator& operator-=(difference_type n)
|
| 4108 |
+
requires concat-is-random-access<Const, Views...>;
|
| 4109 |
+
```
|
| 4110 |
+
|
| 4111 |
+
*Effects:* Equivalent to:
|
| 4112 |
+
|
| 4113 |
+
``` cpp
|
| 4114 |
+
*this += -n;
|
| 4115 |
+
return *this;
|
| 4116 |
+
```
|
| 4117 |
+
|
| 4118 |
+
``` cpp
|
| 4119 |
+
constexpr decltype(auto) operator[](difference_type n) const
|
| 4120 |
+
requires concat-is-random-access<Const, Views...>;
|
| 4121 |
+
```
|
| 4122 |
+
|
| 4123 |
+
*Effects:* Equivalent to:
|
| 4124 |
+
|
| 4125 |
+
``` cpp
|
| 4126 |
+
return *((*this) + n);
|
| 4127 |
+
```
|
| 4128 |
+
|
| 4129 |
+
``` cpp
|
| 4130 |
+
friend constexpr bool operator==(const iterator& x, const iterator& y)
|
| 4131 |
+
requires (equality_comparable<iterator_t<maybe-const<Const, Views>>> && ...);
|
| 4132 |
+
```
|
| 4133 |
+
|
| 4134 |
+
*Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
|
| 4135 |
+
`y.`*`it_`*`.valueless_by_exception()` are each `false`.
|
| 4136 |
+
|
| 4137 |
+
*Effects:* Equivalent to:
|
| 4138 |
+
|
| 4139 |
+
``` cpp
|
| 4140 |
+
return x.it_ == y.it_;
|
| 4141 |
+
```
|
| 4142 |
+
|
| 4143 |
+
``` cpp
|
| 4144 |
+
friend constexpr bool operator==(const iterator& it, default_sentinel_t);
|
| 4145 |
+
```
|
| 4146 |
+
|
| 4147 |
+
*Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
|
| 4148 |
+
|
| 4149 |
+
*Effects:* Equivalent to:
|
| 4150 |
+
|
| 4151 |
+
``` cpp
|
| 4152 |
+
constexpr auto last_idx = sizeof...(Views) - 1;
|
| 4153 |
+
return it.it_.index() == last_idx &&
|
| 4154 |
+
std::get<last_idx>(it.it_) == ranges::end(std::get<last_idx>(it.parent_->views_));
|
| 4155 |
+
```
|
| 4156 |
+
|
| 4157 |
+
``` cpp
|
| 4158 |
+
friend constexpr bool operator<(const iterator& x, const iterator& y)
|
| 4159 |
+
requires all-random-access<Const, Views...>;
|
| 4160 |
+
friend constexpr bool operator>(const iterator& x, const iterator& y)
|
| 4161 |
+
requires all-random-access<Const, Views...>;
|
| 4162 |
+
friend constexpr bool operator<=(const iterator& x, const iterator& y)
|
| 4163 |
+
requires all-random-access<Const, Views...>;
|
| 4164 |
+
friend constexpr bool operator>=(const iterator& x, const iterator& y)
|
| 4165 |
+
requires all-random-access<Const, Views...>;
|
| 4166 |
+
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
|
| 4167 |
+
requires (all-random-access<Const, Views...> &&
|
| 4168 |
+
(three_way_comparable<iterator_t<maybe-const<Const, Views>>> && ...));
|
| 4169 |
+
```
|
| 4170 |
+
|
| 4171 |
+
*Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
|
| 4172 |
+
`y.`*`it_`*`.valueless_by_exception()` are each `false`.
|
| 4173 |
+
|
| 4174 |
+
Let op be the operator.
|
| 4175 |
+
|
| 4176 |
+
*Effects:* Equivalent to:
|
| 4177 |
+
|
| 4178 |
+
``` cpp
|
| 4179 |
+
return x.it_ op y.it_;
|
| 4180 |
+
```
|
| 4181 |
+
|
| 4182 |
+
``` cpp
|
| 4183 |
+
friend constexpr iterator operator+(const iterator& it, difference_type n)
|
| 4184 |
+
requires concat-is-random-access<Const, Views...>;
|
| 4185 |
+
```
|
| 4186 |
+
|
| 4187 |
+
*Effects:* Equivalent to:
|
| 4188 |
+
|
| 4189 |
+
``` cpp
|
| 4190 |
+
auto temp = it;
|
| 4191 |
+
temp += n;
|
| 4192 |
+
return temp;
|
| 4193 |
+
```
|
| 4194 |
+
|
| 4195 |
+
``` cpp
|
| 4196 |
+
friend constexpr iterator operator+(difference_type n, const iterator& it)
|
| 4197 |
+
requires concat-is-random-access<Const, Views...>;
|
| 4198 |
+
```
|
| 4199 |
+
|
| 4200 |
+
*Effects:* Equivalent to:
|
| 4201 |
+
|
| 4202 |
+
``` cpp
|
| 4203 |
+
return it + n;
|
| 4204 |
+
```
|
| 4205 |
+
|
| 4206 |
+
``` cpp
|
| 4207 |
+
friend constexpr iterator operator-(const iterator& it, difference_type n)
|
| 4208 |
+
requires concat-is-random-access<Const, Views...>;
|
| 4209 |
+
```
|
| 4210 |
+
|
| 4211 |
+
*Effects:* Equivalent to:
|
| 4212 |
+
|
| 4213 |
+
``` cpp
|
| 4214 |
+
auto temp = it;
|
| 4215 |
+
temp -= n;
|
| 4216 |
+
return temp;
|
| 4217 |
+
```
|
| 4218 |
+
|
| 4219 |
+
``` cpp
|
| 4220 |
+
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
|
| 4221 |
+
requires concat-is-random-access<Const, Views...>;
|
| 4222 |
+
```
|
| 4223 |
+
|
| 4224 |
+
*Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
|
| 4225 |
+
`y.`*`it_`*`.valueless_by_exception()` are each `false`.
|
| 4226 |
+
|
| 4227 |
+
*Effects:* Let i_`x` denote `x.`*`it_`*`.index()` and i_`y` denote
|
| 4228 |
+
`y.`*`it_`*`.index()`.
|
| 4229 |
+
|
| 4230 |
+
- If i_`x`` > `i_`y`, let d_`y` be
|
| 4231 |
+
`ranges::distance(std::get<`i_`y``>(y.`*`it_`*`), ranges::end(std::get<`i_`y``>(y.`*`parent_`*`->`*`views_`*`)))`,
|
| 4232 |
+
d_`x` be
|
| 4233 |
+
`ranges::distance(ranges::begin(std::get<`i_`x``>(x.`*`parent_`*`->`*`views_`*`)), std::get<`i_`x``>(x.`*`it_`*`))`.
|
| 4234 |
+
Let s denote the sum of the sizes of all the ranges
|
| 4235 |
+
`std::get<`i`>(x.`*`parent_`*`->`*`views_`*`)` for every integer i in
|
| 4236 |
+
the range \[i_`y`` + 1`, i_`x`) if there is any, and `0` otherwise, of
|
| 4237 |
+
type `difference_type`, equivalent to:
|
| 4238 |
+
``` cpp
|
| 4239 |
+
return $d_y$ + s + $d_x$;
|
| 4240 |
+
```
|
| 4241 |
+
- otherwise, if i_`x`` < `i_`y` is `true`, equivalent to:
|
| 4242 |
+
``` cpp
|
| 4243 |
+
return -(y - x);
|
| 4244 |
+
```
|
| 4245 |
+
- otherwise, equivalent to:
|
| 4246 |
+
``` cpp
|
| 4247 |
+
return std::get<$i_x$>(x.it_) - std::get<$i_y$>(y.it_);
|
| 4248 |
+
```
|
| 4249 |
+
|
| 4250 |
+
``` cpp
|
| 4251 |
+
friend constexpr difference_type operator-(const iterator& x, default_sentinel_t)
|
| 4252 |
+
requires see below;
|
| 4253 |
+
```
|
| 4254 |
+
|
| 4255 |
+
*Preconditions:* `x.`*`it_`*`.valueless_by_exception()` is `false`.
|
| 4256 |
+
|
| 4257 |
+
*Effects:* Let i_`x` denote `x.`*`it_`*`.index()`, d_`x` be
|
| 4258 |
+
`ranges::distance(std::get<`i_`x``>(x.`*`it_`*`), ranges::end(std::get<`i_`x``>(x.`*`parent_`*`->`*`views_`*`)))`.
|
| 4259 |
+
Let s denote the sum of the sizes of all the ranges
|
| 4260 |
+
`std::get<`i`>(x.`*`parent_`*`->`*`views_`*`)` for every integer i in
|
| 4261 |
+
the range \[i_`x`` + 1`, `sizeof...(Views)`) if there is any, and `0`
|
| 4262 |
+
otherwise, of type difference_type, equivalent to:
|
| 4263 |
+
|
| 4264 |
+
``` cpp
|
| 4265 |
+
return -($d_x$ + s);
|
| 4266 |
+
```
|
| 4267 |
+
|
| 4268 |
+
*Remarks:* Let `Fs` be the pack that consists of all elements of `Views`
|
| 4269 |
+
except the first element, the expression in the *requires-clause* is
|
| 4270 |
+
equivalent to:
|
| 4271 |
+
|
| 4272 |
+
``` cpp
|
| 4273 |
+
(sized_sentinel_for<sentinel_t<maybe-const<Const, Views>>,
|
| 4274 |
+
iterator_t<maybe-const<Const, Views>>> && ...) &&
|
| 4275 |
+
(sized_range<maybe-const<Const, Fs>> && ...)
|
| 4276 |
+
```
|
| 4277 |
+
|
| 4278 |
+
``` cpp
|
| 4279 |
+
friend constexpr difference_type operator-(default_sentinel_t, const iterator& x)
|
| 4280 |
+
requires see below;
|
| 4281 |
+
```
|
| 4282 |
+
|
| 4283 |
+
*Effects:* Equivalent to:
|
| 4284 |
+
|
| 4285 |
+
``` cpp
|
| 4286 |
+
return -(x - default_sentinel);
|
| 4287 |
+
```
|
| 4288 |
+
|
| 4289 |
+
*Remarks:* Let `Fs` be the pack that consists of all elements of `Views`
|
| 4290 |
+
except the first element, the expression in the *requires-clause* is
|
| 4291 |
+
equivalent to:
|
| 4292 |
+
|
| 4293 |
+
``` cpp
|
| 4294 |
+
(sized_sentinel_for<sentinel_t<maybe-const<Const, Views>>,
|
| 4295 |
+
iterator_t<maybe-const<Const, Views>>> && ...) &&
|
| 4296 |
+
(sized_range<maybe-const<Const, Fs>> && ...)
|
| 4297 |
+
```
|
| 4298 |
+
|
| 4299 |
+
``` cpp
|
| 4300 |
+
friend constexpr decltype(auto) iter_move(const iterator& it) noexcept(see below);
|
| 4301 |
+
```
|
| 4302 |
+
|
| 4303 |
+
*Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
|
| 4304 |
+
|
| 4305 |
+
*Effects:* Equivalent to:
|
| 4306 |
+
|
| 4307 |
+
``` cpp
|
| 4308 |
+
return std::visit([](const auto& i)
|
| 4309 |
+
-> concat-rvalue-reference-t<maybe-const<Const, Views>...> {
|
| 4310 |
+
return ranges::iter_move(i);
|
| 4311 |
+
},
|
| 4312 |
+
it.it_);
|
| 4313 |
+
```
|
| 4314 |
+
|
| 4315 |
+
*Remarks:* The exception specification is equivalent to:
|
| 4316 |
+
|
| 4317 |
+
``` cpp
|
| 4318 |
+
((is_nothrow_invocable_v<decltype(ranges::iter_move),
|
| 4319 |
+
const iterator_t<maybe-const<Const, Views>>&> &&
|
| 4320 |
+
is_nothrow_convertible_v<range_rvalue_reference_t<maybe-const<Const, Views>>,
|
| 4321 |
+
concat-rvalue-reference-t<maybe-const<Const, Views>...>>) &&
|
| 4322 |
+
...)
|
| 4323 |
+
```
|
| 4324 |
+
|
| 4325 |
+
``` cpp
|
| 4326 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(see below)
|
| 4327 |
+
requires see below;
|
| 4328 |
+
```
|
| 4329 |
+
|
| 4330 |
+
*Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
|
| 4331 |
+
`y.`*`it_`*`.valueless_by_exception()` are each `false`.
|
| 4332 |
+
|
| 4333 |
+
*Effects:* Equivalent to:
|
| 4334 |
+
|
| 4335 |
+
``` cpp
|
| 4336 |
+
std::visit([&](const auto& it1, const auto& it2) {
|
| 4337 |
+
if constexpr (is_same_v<decltype(it1), decltype(it2)>) {
|
| 4338 |
+
ranges::iter_swap(it1, it2);
|
| 4339 |
+
} else {
|
| 4340 |
+
ranges::swap(*x, *y);
|
| 4341 |
+
}
|
| 4342 |
+
},
|
| 4343 |
+
x.it_, y.it_);
|
| 4344 |
+
```
|
| 4345 |
+
|
| 4346 |
+
*Remarks:* The exception specification is equivalent to
|
| 4347 |
+
|
| 4348 |
+
``` cpp
|
| 4349 |
+
(noexcept(ranges::swap(*x, *y)) && ... && noexcept(ranges::iter_swap(its, its)))
|
| 4350 |
+
```
|
| 4351 |
+
|
| 4352 |
+
where `its` is a pack of lvalues of type
|
| 4353 |
+
`const iterator_t<`*`maybe-const`*`<Const, Views>>` respectively.
|
| 4354 |
+
|
| 4355 |
+
The expression in the *requires-clause* is equivalent to
|
| 4356 |
+
|
| 4357 |
+
``` cpp
|
| 4358 |
+
swappable_with<iter_reference_t<iterator>, iter_reference_t<iterator>> &&
|
| 4359 |
+
(... && indirectly_swappable<iterator_t<maybe-const<Const, Views>>>)
|
| 4360 |
+
```
|
| 4361 |
+
|
| 4362 |
### Counted view <a id="range.counted">[[range.counted]]</a>
|
| 4363 |
|
| 4364 |
A counted view presents a view of the elements of the counted range
|
| 4365 |
[[iterator.requirements.general]] `i`+\[0, `n`) for an iterator `i` and
|
| 4366 |
non-negative integer `n`.
|
|
|
|
| 4437 |
constexpr explicit common_view(V r);
|
| 4438 |
|
| 4439 |
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 4440 |
constexpr V base() && { return std::move(base_); }
|
| 4441 |
|
| 4442 |
+
constexpr auto begin() requires (!simple-view<V>) {
|
| 4443 |
if constexpr (random_access_range<V> && sized_range<V>)
|
| 4444 |
return ranges::begin(base_);
|
| 4445 |
else
|
| 4446 |
return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::begin(base_));
|
| 4447 |
}
|
|
|
|
| 4451 |
return ranges::begin(base_);
|
| 4452 |
else
|
| 4453 |
return common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::begin(base_));
|
| 4454 |
}
|
| 4455 |
|
| 4456 |
+
constexpr auto end() requires (!simple-view<V>) {
|
| 4457 |
if constexpr (random_access_range<V> && sized_range<V>)
|
| 4458 |
return ranges::begin(base_) + ranges::distance(base_);
|
| 4459 |
else
|
| 4460 |
return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::end(base_));
|
| 4461 |
}
|
|
|
|
| 4471 |
return ranges::size(base_);
|
| 4472 |
}
|
| 4473 |
constexpr auto size() const requires sized_range<const V> {
|
| 4474 |
return ranges::size(base_);
|
| 4475 |
}
|
| 4476 |
+
|
| 4477 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V> {
|
| 4478 |
+
return ranges::reserve_hint(base_);
|
| 4479 |
+
}
|
| 4480 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V> {
|
| 4481 |
+
return ranges::reserve_hint(base_);
|
| 4482 |
+
}
|
| 4483 |
};
|
| 4484 |
|
| 4485 |
template<class R>
|
| 4486 |
common_view(R&&) -> common_view<views::all_t<R>>;
|
| 4487 |
}
|
|
|
|
| 4503 |
The name `views::reverse` denotes a range adaptor object
|
| 4504 |
[[range.adaptor.object]]. Given a subexpression `E`, the expression
|
| 4505 |
`views::reverse(E)` is expression-equivalent to:
|
| 4506 |
|
| 4507 |
- If the type of `E` is a (possibly cv-qualified) specialization of
|
| 4508 |
+
`reverse_view`, then `E.base()`.
|
| 4509 |
- Otherwise, if the type of `E` is cv
|
| 4510 |
`subrange<reverse_iterator<I>, reverse_iterator<I>, K>` for some
|
| 4511 |
iterator type `I` and value `K` of type `subrange_kind`,
|
| 4512 |
+
- if `K` is `subrange_kind::sized`, then
|
| 4513 |
+
`subrange<I, I, K>(E.end().base(), E.begin().base(), E.size())`;
|
| 4514 |
+
- otherwise, `subrange<I, I, K>(E.end().base(), E.begin().base())`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4515 |
|
| 4516 |
However, in either case `E` is evaluated only once.
|
| 4517 |
+
- Otherwise, `reverse_view{E}`.
|
| 4518 |
|
| 4519 |
[*Example 1*:
|
| 4520 |
|
| 4521 |
``` cpp
|
| 4522 |
vector<int> is {0,1,2,3,4};
|
|
|
|
| 4556 |
}
|
| 4557 |
|
| 4558 |
constexpr auto size() const requires sized_range<const V> {
|
| 4559 |
return ranges::size(base_);
|
| 4560 |
}
|
| 4561 |
+
|
| 4562 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V> {
|
| 4563 |
+
return ranges::reserve_hint(base_);
|
| 4564 |
+
}
|
| 4565 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V> {
|
| 4566 |
+
return ranges::reserve_hint(base_);
|
| 4567 |
+
}
|
| 4568 |
};
|
| 4569 |
|
| 4570 |
template<class R>
|
| 4571 |
reverse_view(R&&) -> reverse_view<views::all_t<R>>;
|
| 4572 |
}
|
|
|
|
| 4667 |
constexpr auto end() requires (!simple-view<V>) { return ranges::cend(base_); }
|
| 4668 |
constexpr auto end() const requires range<const V> { return ranges::cend(base_); }
|
| 4669 |
|
| 4670 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 4671 |
constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
|
| 4672 |
+
|
| 4673 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>
|
| 4674 |
+
{ return ranges::reserve_hint(base_); }
|
| 4675 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>
|
| 4676 |
+
{ return ranges::reserve_hint(base_); }
|
| 4677 |
};
|
| 4678 |
|
| 4679 |
template<class R>
|
| 4680 |
as_const_view(R&&) -> as_const_view<views::all_t<R>>;
|
| 4681 |
}
|
|
|
|
| 4796 |
{ return ranges::size(base_); }
|
| 4797 |
|
| 4798 |
constexpr auto size() const requires sized_range<const V>
|
| 4799 |
{ return ranges::size(base_); }
|
| 4800 |
|
| 4801 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>
|
| 4802 |
+
{ return ranges::reserve_hint(base_); }
|
| 4803 |
+
|
| 4804 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>
|
| 4805 |
+
{ return ranges::reserve_hint(base_); }
|
| 4806 |
+
|
| 4807 |
private:
|
| 4808 |
// [range.elements.iterator], class template elements_view::iterator
|
| 4809 |
template<bool> class iterator; // exposition only
|
| 4810 |
|
| 4811 |
// [range.elements.sentinel], class template elements_view::sentinel
|
|
|
|
| 5194 |
#### Overview <a id="range.enumerate.overview">[[range.enumerate.overview]]</a>
|
| 5195 |
|
| 5196 |
`enumerate_view` is a view whose elements represent both the position
|
| 5197 |
and value from a sequence of elements.
|
| 5198 |
|
| 5199 |
+
The name `views::enumerate` denotes a range adaptor object
|
| 5200 |
+
[[range.adaptor.object]]. Given a subexpression `E`, the expression
|
| 5201 |
+
`views::enumerate(E)` is expression-equivalent to
|
| 5202 |
`enumerate_view<views::all_t<decltype((E))>>(E)`.
|
| 5203 |
|
| 5204 |
[*Example 1*:
|
| 5205 |
|
| 5206 |
``` cpp
|
|
|
|
| 5236 |
{ return iterator<false>(ranges::begin(base_), 0); }
|
| 5237 |
constexpr auto begin() const requires range-with-movable-references<const V>
|
| 5238 |
{ return iterator<true>(ranges::begin(base_), 0); }
|
| 5239 |
|
| 5240 |
constexpr auto end() requires (!simple-view<V>) {
|
| 5241 |
+
if constexpr (forward_range<V> && common_range<V> && sized_range<V>)
|
| 5242 |
return iterator<false>(ranges::end(base_), ranges::distance(base_));
|
| 5243 |
else
|
| 5244 |
return sentinel<false>(ranges::end(base_));
|
| 5245 |
}
|
| 5246 |
constexpr auto end() const requires range-with-movable-references<const V> {
|
| 5247 |
+
if constexpr (forward_range<const V> && common_range<const V> && sized_range<const V>)
|
| 5248 |
return iterator<true>(ranges::end(base_), ranges::distance(base_));
|
| 5249 |
else
|
| 5250 |
return sentinel<true>(ranges::end(base_));
|
| 5251 |
}
|
| 5252 |
|
| 5253 |
constexpr auto size() requires sized_range<V>
|
| 5254 |
{ return ranges::size(base_); }
|
| 5255 |
constexpr auto size() const requires sized_range<const V>
|
| 5256 |
{ return ranges::size(base_); }
|
| 5257 |
|
| 5258 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>
|
| 5259 |
+
{ return ranges::reserve_hint(base_); }
|
| 5260 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>
|
| 5261 |
+
{ return ranges::reserve_hint(base_); }
|
| 5262 |
+
|
| 5263 |
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 5264 |
constexpr V base() && { return std::move(base_); }
|
| 5265 |
};
|
| 5266 |
|
| 5267 |
template<class R>
|
|
|
|
| 5337 |
requires random_access_range<Base>;
|
| 5338 |
friend constexpr iterator operator+(difference_type x, const iterator& y)
|
| 5339 |
requires random_access_range<Base>;
|
| 5340 |
friend constexpr iterator operator-(const iterator& x, difference_type y)
|
| 5341 |
requires random_access_range<Base>;
|
| 5342 |
+
friend constexpr difference_type operator-(const iterator& x, const iterator& y) noexcept;
|
| 5343 |
|
| 5344 |
friend constexpr auto iter_move(const iterator& i)
|
| 5345 |
noexcept(noexcept(ranges::iter_move(i.current_)) &&
|
| 5346 |
is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>) {
|
| 5347 |
return tuple<difference_type,
|
|
|
|
| 5519 |
temp -= y;
|
| 5520 |
return temp;
|
| 5521 |
```
|
| 5522 |
|
| 5523 |
``` cpp
|
| 5524 |
+
friend constexpr difference_type operator-(const iterator& x, const iterator& y) noexcept;
|
| 5525 |
```
|
| 5526 |
|
| 5527 |
*Effects:* Equivalent to: `return x.`*`pos_`*` - y.`*`pos_`*`;`
|
| 5528 |
|
| 5529 |
#### Class template `enumerate_view::sentinel` <a id="range.enumerate.sentinel">[[range.enumerate.sentinel]]</a>
|
|
|
|
| 5730 |
|
| 5731 |
#### Class template `zip_view::iterator` <a id="range.zip.iterator">[[range.zip.iterator]]</a>
|
| 5732 |
|
| 5733 |
``` cpp
|
| 5734 |
namespace std::ranges {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5735 |
template<input_range... Views>
|
| 5736 |
requires (view<Views> && ...) && (sizeof...(Views) > 0)
|
| 5737 |
template<bool Const>
|
| 5738 |
class zip_view<Views...>::iterator {
|
| 5739 |
tuple<iterator_t<maybe-const<Const, Views>>...> current_; // exposition only
|
|
|
|
| 6100 |
iterator_t<maybe-const<OtherConst, Views>>> && ...)
|
| 6101 |
friend constexpr common_type_t<range_difference_t<maybe-const<OtherConst, Views>>...>
|
| 6102 |
operator-(const sentinel& y, const iterator<OtherConst>& x);
|
| 6103 |
```
|
| 6104 |
|
| 6105 |
+
*Effects:* Equivalent to: `return -(x - y);`
|
| 6106 |
|
| 6107 |
### Zip transform view <a id="range.zip.transform">[[range.zip.transform]]</a>
|
| 6108 |
|
| 6109 |
#### Overview <a id="range.zip.transform.overview">[[range.zip.transform.overview]]</a>
|
| 6110 |
|
|
|
|
| 6235 |
|
| 6236 |
constexpr iterator(Parent& parent, ziperator<Const> inner); // exposition only
|
| 6237 |
|
| 6238 |
public:
|
| 6239 |
using iterator_category = see belownc; // not always present
|
| 6240 |
+
using iterator_concept = ziperator<Const>::iterator_concept;
|
| 6241 |
using value_type =
|
| 6242 |
remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
|
| 6243 |
range_reference_t<maybe-const<Const, Views>>...>>;
|
| 6244 |
using difference_type = range_difference_t<Base>;
|
| 6245 |
|
|
|
|
| 6538 |
The name `views::adjacent<N>` denotes a range adaptor object
|
| 6539 |
[[range.adaptor.object]]. Given a subexpression `E` and a constant
|
| 6540 |
expression `N`, the expression `views::adjacent<N>(E)` is
|
| 6541 |
expression-equivalent to
|
| 6542 |
|
| 6543 |
+
- `((void)E, auto(views::empty<tuple<>>))` if `N` is equal to `0` and
|
| 6544 |
+
`decltype((E))` models `forward_range`,
|
| 6545 |
- otherwise, `adjacent_view<views::all_t<decltype((E))>, N>(E)`.
|
| 6546 |
|
| 6547 |
[*Example 1*:
|
| 6548 |
|
| 6549 |
``` cpp
|
|
|
|
| 6607 |
}
|
| 6608 |
}
|
| 6609 |
|
| 6610 |
constexpr auto size() requires sized_range<V>;
|
| 6611 |
constexpr auto size() const requires sized_range<const V>;
|
| 6612 |
+
|
| 6613 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 6614 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 6615 |
};
|
| 6616 |
}
|
| 6617 |
```
|
| 6618 |
|
| 6619 |
``` cpp
|
|
|
|
| 6635 |
auto sz = static_cast<CT>(ranges::size(base_));
|
| 6636 |
sz -= std::min<CT>(sz, N - 1);
|
| 6637 |
return static_cast<ST>(sz);
|
| 6638 |
```
|
| 6639 |
|
| 6640 |
+
``` cpp
|
| 6641 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 6642 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 6643 |
+
```
|
| 6644 |
+
|
| 6645 |
+
*Effects:* Equivalent to:
|
| 6646 |
+
|
| 6647 |
+
``` cpp
|
| 6648 |
+
using DT = range_difference_t<decltype((base_))>;
|
| 6649 |
+
using CT = common_type_t<DT, size_t>;
|
| 6650 |
+
auto sz = static_cast<CT>(ranges::reserve_hint(base_));
|
| 6651 |
+
sz -= std::min<CT>(sz, N - 1);
|
| 6652 |
+
return to-unsigned-like(sz);
|
| 6653 |
+
```
|
| 6654 |
+
|
| 6655 |
#### Class template `adjacent_view::iterator` <a id="range.adjacent.iterator">[[range.adjacent.iterator]]</a>
|
| 6656 |
|
| 6657 |
``` cpp
|
| 6658 |
namespace std::ranges {
|
| 6659 |
template<forward_range V, size_t N>
|
|
|
|
| 7046 |
|
| 7047 |
The name `views::adjacent_transform<N>` denotes a range adaptor object
|
| 7048 |
[[range.adaptor.object]]. Given subexpressions `E` and `F` and a
|
| 7049 |
constant expression `N`:
|
| 7050 |
|
| 7051 |
+
- If `N` is equal to `0` and `decltype((E))` models `forward_range`,
|
| 7052 |
+
`views::adjacent_transform<N>(E, F)` is expression-equivalent to
|
| 7053 |
+
`((void)E, views::zip_transform(F))`, except that the evaluations of
|
| 7054 |
+
`E` and `F` are indeterminately sequenced.
|
| 7055 |
- Otherwise, the expression `views::adjacent_transform<N>(E, F)` is
|
| 7056 |
expression-equivalent to
|
| 7057 |
`adjacent_transform_view<views::all_t<decltype((E))>, decay_t<decltype((F))>, N>(E, F)`.
|
| 7058 |
|
| 7059 |
[*Example 1*:
|
|
|
|
| 7094 |
|
| 7095 |
public:
|
| 7096 |
adjacent_transform_view() = default;
|
| 7097 |
constexpr explicit adjacent_transform_view(V base, F fun);
|
| 7098 |
|
| 7099 |
+
constexpr V base() const & requires copy_constructible<V> { return inner_.base(); }
|
| 7100 |
constexpr V base() && { return std::move(inner_).base(); }
|
| 7101 |
|
| 7102 |
constexpr auto begin() {
|
| 7103 |
return iterator<false>(*this, inner_.begin());
|
| 7104 |
}
|
|
|
|
| 7132 |
}
|
| 7133 |
|
| 7134 |
constexpr auto size() const requires sized_range<const InnerView> {
|
| 7135 |
return inner_.size();
|
| 7136 |
}
|
| 7137 |
+
|
| 7138 |
+
constexpr auto reserve_hint() requires approximately_sized_range<InnerView> {
|
| 7139 |
+
return inner_.reserve_hint();
|
| 7140 |
+
}
|
| 7141 |
+
|
| 7142 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const InnerView> {
|
| 7143 |
+
return inner_.reserve_hint();
|
| 7144 |
+
}
|
| 7145 |
};
|
| 7146 |
}
|
| 7147 |
```
|
| 7148 |
|
| 7149 |
``` cpp
|
|
|
|
| 7170 |
|
| 7171 |
constexpr iterator(Parent& parent, inner-iterator<Const> inner); // exposition only
|
| 7172 |
|
| 7173 |
public:
|
| 7174 |
using iterator_category = see below;
|
| 7175 |
+
using iterator_concept = inner-iterator<Const>::iterator_concept;
|
| 7176 |
using value_type =
|
| 7177 |
remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
|
| 7178 |
REPEAT(range_reference_t<Base>, N)...>>;
|
| 7179 |
using difference_type = range_difference_t<Base>;
|
| 7180 |
|
|
|
|
| 7444 |
template<bool OtherConst>
|
| 7445 |
requires sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 7446 |
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
| 7447 |
```
|
| 7448 |
|
| 7449 |
+
*Effects:* Equivalent to: `return x.`*`inner_`*` == y.`*`inner_`*`;`
|
| 7450 |
|
| 7451 |
``` cpp
|
| 7452 |
template<bool OtherConst>
|
| 7453 |
requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 7454 |
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
|
|
|
| 7458 |
requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 7459 |
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
| 7460 |
operator-(const sentinel& x, const iterator<OtherConst>& y);
|
| 7461 |
```
|
| 7462 |
|
| 7463 |
+
*Effects:* Equivalent to: `return x.`*`inner_`*` - y.`*`inner_`*`;`
|
| 7464 |
|
| 7465 |
### Chunk view <a id="range.chunk">[[range.chunk]]</a>
|
| 7466 |
|
| 7467 |
#### Overview <a id="range.chunk.overview">[[range.chunk.overview]]</a>
|
| 7468 |
|
|
|
|
| 7531 |
constexpr outer-iterator begin();
|
| 7532 |
constexpr default_sentinel_t end() const noexcept;
|
| 7533 |
|
| 7534 |
constexpr auto size() requires sized_range<V>;
|
| 7535 |
constexpr auto size() const requires sized_range<const V>;
|
| 7536 |
+
|
| 7537 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 7538 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 7539 |
};
|
| 7540 |
|
| 7541 |
template<class R>
|
| 7542 |
chunk_view(R&&, range_difference_t<R>) -> chunk_view<views::all_t<R>>;
|
| 7543 |
}
|
|
|
|
| 7579 |
|
| 7580 |
``` cpp
|
| 7581 |
return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
|
| 7582 |
```
|
| 7583 |
|
| 7584 |
+
``` cpp
|
| 7585 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 7586 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 7587 |
+
```
|
| 7588 |
+
|
| 7589 |
+
*Effects:* Equivalent to:
|
| 7590 |
+
|
| 7591 |
+
``` cpp
|
| 7592 |
+
auto s = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_));
|
| 7593 |
+
return to-unsigned-like(div-ceil(s, n_));
|
| 7594 |
+
```
|
| 7595 |
+
|
| 7596 |
#### Class `chunk_view::outer-iterator` <a id="range.chunk.outer.iter">[[range.chunk.outer.iter]]</a>
|
| 7597 |
|
| 7598 |
``` cpp
|
| 7599 |
namespace std::ranges {
|
| 7600 |
template<view V>
|
|
|
|
| 7710 |
constexpr inner-iterator begin() const noexcept;
|
| 7711 |
constexpr default_sentinel_t end() const noexcept;
|
| 7712 |
|
| 7713 |
constexpr auto size() const
|
| 7714 |
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
| 7715 |
+
|
| 7716 |
+
constexpr auto reserve_hint() const noexcept;
|
| 7717 |
};
|
| 7718 |
}
|
| 7719 |
```
|
| 7720 |
|
| 7721 |
``` cpp
|
|
|
|
| 7746 |
``` cpp
|
| 7747 |
return to-unsigned-like(ranges::min(parent_->remainder_,
|
| 7748 |
ranges::end(parent_->base_) - *parent_->current_));
|
| 7749 |
```
|
| 7750 |
|
| 7751 |
+
``` cpp
|
| 7752 |
+
constexpr auto reserve_hint() const noexcept;
|
| 7753 |
+
```
|
| 7754 |
+
|
| 7755 |
+
*Effects:* Equivalent to:
|
| 7756 |
+
|
| 7757 |
+
``` cpp
|
| 7758 |
+
return to-unsigned-like(parent_->remainder_);
|
| 7759 |
+
```
|
| 7760 |
+
|
| 7761 |
#### Class `chunk_view::inner-iterator` <a id="range.chunk.inner.iter">[[range.chunk.inner.iter]]</a>
|
| 7762 |
|
| 7763 |
``` cpp
|
| 7764 |
namespace std::ranges {
|
| 7765 |
template<view V>
|
|
|
|
| 7934 |
}
|
| 7935 |
}
|
| 7936 |
|
| 7937 |
constexpr auto size() requires sized_range<V>;
|
| 7938 |
constexpr auto size() const requires sized_range<const V>;
|
| 7939 |
+
|
| 7940 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 7941 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 7942 |
};
|
| 7943 |
}
|
| 7944 |
```
|
| 7945 |
|
| 7946 |
``` cpp
|
|
|
|
| 7961 |
|
| 7962 |
``` cpp
|
| 7963 |
return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
|
| 7964 |
```
|
| 7965 |
|
| 7966 |
+
``` cpp
|
| 7967 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 7968 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 7969 |
+
```
|
| 7970 |
+
|
| 7971 |
+
*Effects:* Equivalent to:
|
| 7972 |
+
|
| 7973 |
+
``` cpp
|
| 7974 |
+
auto s = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_));
|
| 7975 |
+
return to-unsigned-like(div-ceil(s, n_));
|
| 7976 |
+
```
|
| 7977 |
+
|
| 7978 |
#### Class template `chunk_view::iterator` for forward ranges <a id="range.chunk.fwd.iter">[[range.chunk.fwd.iter]]</a>
|
| 7979 |
|
| 7980 |
``` cpp
|
| 7981 |
namespace std::ranges {
|
| 7982 |
template<view V>
|
|
|
|
| 8349 |
requires (!(simple-view<V> && slide-caches-nothing<const V>));
|
| 8350 |
constexpr auto end() const requires slide-caches-nothing<const V>;
|
| 8351 |
|
| 8352 |
constexpr auto size() requires sized_range<V>;
|
| 8353 |
constexpr auto size() const requires sized_range<const V>;
|
| 8354 |
+
|
| 8355 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 8356 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 8357 |
};
|
| 8358 |
|
| 8359 |
template<class R>
|
| 8360 |
slide_view(R&&, range_difference_t<R>) -> slide_view<views::all_t<R>>;
|
| 8361 |
}
|
|
|
|
| 8439 |
auto sz = ranges::distance(base_) - n_ + 1;
|
| 8440 |
if (sz < 0) sz = 0;
|
| 8441 |
return to-unsigned-like(sz);
|
| 8442 |
```
|
| 8443 |
|
| 8444 |
+
``` cpp
|
| 8445 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 8446 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 8447 |
+
```
|
| 8448 |
+
|
| 8449 |
+
*Effects:* Equivalent to:
|
| 8450 |
+
|
| 8451 |
+
``` cpp
|
| 8452 |
+
auto sz = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_)) -
|
| 8453 |
+
n_ + 1;
|
| 8454 |
+
if (sz < 0) sz = 0;
|
| 8455 |
+
return to-unsigned-like(sz);
|
| 8456 |
+
```
|
| 8457 |
+
|
| 8458 |
#### Class template `slide_view::iterator` <a id="range.slide.iterator">[[range.slide.iterator]]</a>
|
| 8459 |
|
| 8460 |
``` cpp
|
| 8461 |
namespace std::ranges {
|
| 8462 |
template<forward_range V>
|
|
|
|
| 9120 |
}
|
| 9121 |
}
|
| 9122 |
|
| 9123 |
constexpr auto size() requires sized_range<V>;
|
| 9124 |
constexpr auto size() const requires sized_range<const V>;
|
| 9125 |
+
|
| 9126 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 9127 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 9128 |
};
|
| 9129 |
|
| 9130 |
template<class R>
|
| 9131 |
stride_view(R&&, range_difference_t<R>) -> stride_view<views::all_t<R>>;
|
| 9132 |
}
|
|
|
|
| 9156 |
|
| 9157 |
``` cpp
|
| 9158 |
return to-unsigned-like(div-ceil(ranges::distance(base_), stride_));
|
| 9159 |
```
|
| 9160 |
|
| 9161 |
+
``` cpp
|
| 9162 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 9163 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 9164 |
+
```
|
| 9165 |
+
|
| 9166 |
+
*Effects:* Equivalent to:
|
| 9167 |
+
|
| 9168 |
+
``` cpp
|
| 9169 |
+
auto s = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_));
|
| 9170 |
+
return to-unsigned-like(div-ceil(s, stride_));
|
| 9171 |
+
```
|
| 9172 |
+
|
| 9173 |
#### Class template `stride_view::iterator` <a id="range.stride.iterator">[[range.stride.iterator]]</a>
|
| 9174 |
|
| 9175 |
``` cpp
|
| 9176 |
namespace std::ranges {
|
| 9177 |
template<input_range V>
|
|
|
|
| 9329 |
|
| 9330 |
``` cpp
|
| 9331 |
constexpr void operator++(int);
|
| 9332 |
```
|
| 9333 |
|
| 9334 |
+
*Effects:* Equivalent to `++*this;`
|
| 9335 |
|
| 9336 |
``` cpp
|
| 9337 |
constexpr iterator operator++(int) requires forward_range<Base>;
|
| 9338 |
```
|
| 9339 |
|
|
|
|
| 9571 |
concept cartesian-product-is-bidirectional = // exposition only
|
| 9572 |
(bidirectional_range<maybe-const<Const, First>> && ... &&
|
| 9573 |
(bidirectional_range<maybe-const<Const, Vs>>
|
| 9574 |
&& cartesian-product-common-arg<maybe-const<Const, Vs>>));
|
| 9575 |
|
| 9576 |
+
template<class First, class...>
|
| 9577 |
concept cartesian-product-is-common = // exposition only
|
| 9578 |
cartesian-product-common-arg<First>;
|
| 9579 |
|
| 9580 |
template<class... Vs>
|
| 9581 |
concept cartesian-product-is-sized = // exposition only
|
|
|
|
| 10114 |
the following expressions:
|
| 10115 |
|
| 10116 |
- `noexcept(ranges::iter_swap(std::get<`i`>(l.`*`current_`*`), std::get<`i`>(r.`*`current_`*`)))`
|
| 10117 |
for every integer 0 ≤ i ≤ `sizeof...(Vs)`.
|
| 10118 |
|
| 10119 |
+
### Cache latest view <a id="range.cache.latest">[[range.cache.latest]]</a>
|
| 10120 |
+
|
| 10121 |
+
#### Overview <a id="range.cache.latest.overview">[[range.cache.latest.overview]]</a>
|
| 10122 |
+
|
| 10123 |
+
`cache_latest_view` caches the last-accessed element of its underlying
|
| 10124 |
+
sequence so that the element does not have to be recomputed on repeated
|
| 10125 |
+
access.
|
| 10126 |
+
|
| 10127 |
+
[*Note 1*: This is useful if computation of the element to produce is
|
| 10128 |
+
expensive. — *end note*]
|
| 10129 |
+
|
| 10130 |
+
The name `views::cache_latest` denotes a range adaptor object
|
| 10131 |
+
[[range.adaptor.object]]. Let `E` be an expression. The expression
|
| 10132 |
+
`views::cache_latest(E)` is expression-equivalent to
|
| 10133 |
+
`cache_latest_view(E)`.
|
| 10134 |
+
|
| 10135 |
+
#### Class template `cache_latest_view` <a id="range.cache.latest.view">[[range.cache.latest.view]]</a>
|
| 10136 |
+
|
| 10137 |
+
``` cpp
|
| 10138 |
+
namespace std::ranges {
|
| 10139 |
+
template<input_range V>
|
| 10140 |
+
requires view<V>
|
| 10141 |
+
class cache_latest_view : public view_interface<cache_latest_view<V>> {
|
| 10142 |
+
V base_ = V(); // exposition only
|
| 10143 |
+
using cache-t = conditional_t<is_reference_v<range_reference_t<V>>, // exposition only
|
| 10144 |
+
add_pointer_t<range_reference_t<V>>,
|
| 10145 |
+
range_reference_t<V>>;
|
| 10146 |
+
|
| 10147 |
+
non-propagating-cache<cache-t> cache_; // exposition only
|
| 10148 |
+
|
| 10149 |
+
// [range.cache.latest.iterator], class cache_latest_view::iterator
|
| 10150 |
+
class iterator; // exposition only
|
| 10151 |
+
// [range.cache.latest.sentinel], class cache_latest_view::sentinel
|
| 10152 |
+
class sentinel; // exposition only
|
| 10153 |
+
|
| 10154 |
+
public:
|
| 10155 |
+
cache_latest_view() requires default_initializable<V> = default;
|
| 10156 |
+
constexpr explicit cache_latest_view(V base);
|
| 10157 |
+
|
| 10158 |
+
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 10159 |
+
constexpr V base() && { return std::move(base_); }
|
| 10160 |
+
|
| 10161 |
+
constexpr auto begin();
|
| 10162 |
+
constexpr auto end();
|
| 10163 |
+
|
| 10164 |
+
constexpr auto size() requires sized_range<V>;
|
| 10165 |
+
constexpr auto size() const requires sized_range<const V>;
|
| 10166 |
+
|
| 10167 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 10168 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 10169 |
+
};
|
| 10170 |
+
|
| 10171 |
+
template<class R>
|
| 10172 |
+
cache_latest_view(R&&) -> cache_latest_view<views::all_t<R>>;
|
| 10173 |
+
}
|
| 10174 |
+
```
|
| 10175 |
+
|
| 10176 |
+
``` cpp
|
| 10177 |
+
constexpr explicit cache_latest_view(V base);
|
| 10178 |
+
```
|
| 10179 |
+
|
| 10180 |
+
*Effects:* Initializes *base\_* with `std::move(base)`.
|
| 10181 |
+
|
| 10182 |
+
``` cpp
|
| 10183 |
+
constexpr auto begin();
|
| 10184 |
+
```
|
| 10185 |
+
|
| 10186 |
+
*Effects:* Equivalent to: `return `*`iterator`*`(*this);`
|
| 10187 |
+
|
| 10188 |
+
``` cpp
|
| 10189 |
+
constexpr auto end();
|
| 10190 |
+
```
|
| 10191 |
+
|
| 10192 |
+
*Effects:* Equivalent to: `return `*`sentinel`*`(*this);`
|
| 10193 |
+
|
| 10194 |
+
``` cpp
|
| 10195 |
+
constexpr auto size() requires sized_range<V>;
|
| 10196 |
+
constexpr auto size() const requires sized_range<const V>;
|
| 10197 |
+
```
|
| 10198 |
+
|
| 10199 |
+
*Effects:* Equivalent to: `return ranges::size(`*`base_`*`);`
|
| 10200 |
+
|
| 10201 |
+
``` cpp
|
| 10202 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 10203 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 10204 |
+
```
|
| 10205 |
+
|
| 10206 |
+
*Effects:* Equivalent to: `return ranges::reserve_hint(`*`base_`*`);`
|
| 10207 |
+
|
| 10208 |
+
#### Class `cache_latest_view::iterator` <a id="range.cache.latest.iterator">[[range.cache.latest.iterator]]</a>
|
| 10209 |
+
|
| 10210 |
+
``` cpp
|
| 10211 |
+
namespace std::ranges {
|
| 10212 |
+
template<input_range V>
|
| 10213 |
+
requires view<V>
|
| 10214 |
+
class cache_latest_view<V>::iterator {
|
| 10215 |
+
cache_latest_view* parent_; // exposition only
|
| 10216 |
+
iterator_t<V> current_; // exposition only
|
| 10217 |
+
|
| 10218 |
+
constexpr explicit iterator(cache_latest_view& parent); // exposition only
|
| 10219 |
+
|
| 10220 |
+
public:
|
| 10221 |
+
using difference_type = range_difference_t<V>;
|
| 10222 |
+
using value_type = range_value_t<V>;
|
| 10223 |
+
using iterator_concept = input_iterator_tag;
|
| 10224 |
+
|
| 10225 |
+
iterator(iterator&&) = default;
|
| 10226 |
+
iterator& operator=(iterator&&) = default;
|
| 10227 |
+
|
| 10228 |
+
constexpr iterator_t<V> base() &&;
|
| 10229 |
+
constexpr const iterator_t<V>& base() const & noexcept;
|
| 10230 |
+
|
| 10231 |
+
constexpr range_reference_t<V>& operator*() const;
|
| 10232 |
+
|
| 10233 |
+
constexpr iterator& operator++();
|
| 10234 |
+
constexpr void operator++(int);
|
| 10235 |
+
|
| 10236 |
+
friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
|
| 10237 |
+
noexcept(noexcept(ranges::iter_move(i.current_)));
|
| 10238 |
+
|
| 10239 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
| 10240 |
+
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
| 10241 |
+
requires indirectly_swappable<iterator_t<V>>;
|
| 10242 |
+
};
|
| 10243 |
+
}
|
| 10244 |
+
```
|
| 10245 |
+
|
| 10246 |
+
``` cpp
|
| 10247 |
+
constexpr explicit iterator(cache_latest_view& parent);
|
| 10248 |
+
```
|
| 10249 |
+
|
| 10250 |
+
*Effects:* Initializes *current\_* with
|
| 10251 |
+
`ranges::begin(parent.`*`base_`*`)` and *parent\_* with
|
| 10252 |
+
`addressof(parent)`.
|
| 10253 |
+
|
| 10254 |
+
``` cpp
|
| 10255 |
+
constexpr iterator_t<V> base() &&;
|
| 10256 |
+
```
|
| 10257 |
+
|
| 10258 |
+
*Returns:* `std::move(`*`current_`*`)`.
|
| 10259 |
+
|
| 10260 |
+
``` cpp
|
| 10261 |
+
constexpr const iterator_t<V>& base() const & noexcept;
|
| 10262 |
+
```
|
| 10263 |
+
|
| 10264 |
+
*Returns:* *current\_*.
|
| 10265 |
+
|
| 10266 |
+
``` cpp
|
| 10267 |
+
constexpr iterator& operator++();
|
| 10268 |
+
```
|
| 10269 |
+
|
| 10270 |
+
*Effects:* Equivalent to:
|
| 10271 |
+
|
| 10272 |
+
``` cpp
|
| 10273 |
+
parent_->cache_.reset();
|
| 10274 |
+
++current_;
|
| 10275 |
+
return *this;
|
| 10276 |
+
```
|
| 10277 |
+
|
| 10278 |
+
``` cpp
|
| 10279 |
+
constexpr void operator++(int);
|
| 10280 |
+
```
|
| 10281 |
+
|
| 10282 |
+
*Effects:* Equivalent to: `++*this`.
|
| 10283 |
+
|
| 10284 |
+
``` cpp
|
| 10285 |
+
constexpr range_reference_t<V>& operator*() const;
|
| 10286 |
+
```
|
| 10287 |
+
|
| 10288 |
+
*Effects:* Equivalent to:
|
| 10289 |
+
|
| 10290 |
+
``` cpp
|
| 10291 |
+
if constexpr (is_reference_v<range_reference_t<V>>) {
|
| 10292 |
+
if (!parent_->cache_) {
|
| 10293 |
+
parent_->cache_ = addressof(as-lvalue(*current_));
|
| 10294 |
+
}
|
| 10295 |
+
return **parent_->cache_;
|
| 10296 |
+
} else {
|
| 10297 |
+
if (!parent_->cache_) {
|
| 10298 |
+
parent_->cache_.emplace-deref(current_);
|
| 10299 |
+
}
|
| 10300 |
+
return *parent_->cache_;
|
| 10301 |
+
}
|
| 10302 |
+
```
|
| 10303 |
+
|
| 10304 |
+
[*Note 1*: Evaluations of `operator*` on the same iterator object can
|
| 10305 |
+
conflict [[intro.races]]. — *end note*]
|
| 10306 |
+
|
| 10307 |
+
``` cpp
|
| 10308 |
+
friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
|
| 10309 |
+
noexcept(noexcept(ranges::iter_move(i.current_)));
|
| 10310 |
+
```
|
| 10311 |
+
|
| 10312 |
+
*Effects:* Equivalent to: `return ranges::iter_move(i.`*`current_`*`);`
|
| 10313 |
+
|
| 10314 |
+
``` cpp
|
| 10315 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
| 10316 |
+
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
| 10317 |
+
requires indirectly_swappable<iterator_t<V>>;
|
| 10318 |
+
```
|
| 10319 |
+
|
| 10320 |
+
*Effects:* Equivalent to
|
| 10321 |
+
`ranges::iter_swap(x.`*`current_`*`, y.`*`current_`*`)`.
|
| 10322 |
+
|
| 10323 |
+
#### Class `cache_latest_view::sentinel` <a id="range.cache.latest.sentinel">[[range.cache.latest.sentinel]]</a>
|
| 10324 |
+
|
| 10325 |
+
``` cpp
|
| 10326 |
+
namespace std::ranges {
|
| 10327 |
+
template<input_range V>
|
| 10328 |
+
requires view<V>
|
| 10329 |
+
class cache_latest_view<V>::sentinel {
|
| 10330 |
+
sentinel_t<V> end_ = sentinel_t<V>(); // exposition only
|
| 10331 |
+
|
| 10332 |
+
constexpr explicit sentinel(cache_latest_view& parent); // exposition only
|
| 10333 |
+
|
| 10334 |
+
public:
|
| 10335 |
+
sentinel() = default;
|
| 10336 |
+
|
| 10337 |
+
constexpr sentinel_t<V> base() const;
|
| 10338 |
+
|
| 10339 |
+
friend constexpr bool operator==(const iterator& x, const sentinel& y);
|
| 10340 |
+
|
| 10341 |
+
friend constexpr range_difference_t<V> operator-(const iterator& x, const sentinel& y)
|
| 10342 |
+
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
| 10343 |
+
friend constexpr range_difference_t<V> operator-(const sentinel& x, const iterator& y)
|
| 10344 |
+
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
| 10345 |
+
};
|
| 10346 |
+
}
|
| 10347 |
+
```
|
| 10348 |
+
|
| 10349 |
+
``` cpp
|
| 10350 |
+
constexpr explicit sentinel(cache_latest_view& parent);
|
| 10351 |
+
```
|
| 10352 |
+
|
| 10353 |
+
*Effects:* Initializes *end\_* with `ranges::end(parent.`*`base_`*`)`.
|
| 10354 |
+
|
| 10355 |
+
``` cpp
|
| 10356 |
+
constexpr sentinel_t<V> base() const;
|
| 10357 |
+
```
|
| 10358 |
+
|
| 10359 |
+
*Returns:* *end\_*.
|
| 10360 |
+
|
| 10361 |
+
``` cpp
|
| 10362 |
+
friend constexpr bool operator==(const iterator& x, const sentinel& y);
|
| 10363 |
+
```
|
| 10364 |
+
|
| 10365 |
+
*Returns:* `x.`*`current_`*` == y.`*`end_`*.
|
| 10366 |
+
|
| 10367 |
+
``` cpp
|
| 10368 |
+
friend constexpr range_difference_t<V> operator-(const iterator& x, const sentinel& y)
|
| 10369 |
+
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
| 10370 |
+
```
|
| 10371 |
+
|
| 10372 |
+
*Returns:* `x.`*`current_`*` - y.`*`end_`*.
|
| 10373 |
+
|
| 10374 |
+
``` cpp
|
| 10375 |
+
friend constexpr range_difference_t<V> operator-(const sentinel& x, const iterator& y)
|
| 10376 |
+
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
| 10377 |
+
```
|
| 10378 |
+
|
| 10379 |
+
*Returns:* `x.`*`end_`*` - y.`*`current_`*.
|
| 10380 |
+
|
| 10381 |
+
### To input view <a id="range.to.input">[[range.to.input]]</a>
|
| 10382 |
+
|
| 10383 |
+
#### Overview <a id="range.to.input.overview">[[range.to.input.overview]]</a>
|
| 10384 |
+
|
| 10385 |
+
`to_input_view` presents a view of an underlying sequence as an
|
| 10386 |
+
input-only non-common range.
|
| 10387 |
+
|
| 10388 |
+
[*Note 1*: This is useful to avoid overhead that can be necessary to
|
| 10389 |
+
provide support for the operations needed for greater iterator
|
| 10390 |
+
strength. — *end note*]
|
| 10391 |
+
|
| 10392 |
+
The name `views::to_input` denotes a range adaptor object
|
| 10393 |
+
[[range.adaptor.object]]. Let `E` be an expression and let `T` be
|
| 10394 |
+
`decltype((E))`. The expression `views::to_input(E)` is
|
| 10395 |
+
expression-equivalent to:
|
| 10396 |
+
|
| 10397 |
+
- `views::all(E)` if `T` models `input_range`, does not satisfy
|
| 10398 |
+
`common_range`, and does not satisfy `forward_range`.
|
| 10399 |
+
- Otherwise, `to_input_view(E)`.
|
| 10400 |
+
|
| 10401 |
+
#### Class template `to_input_view` <a id="range.to.input.view">[[range.to.input.view]]</a>
|
| 10402 |
+
|
| 10403 |
+
``` cpp
|
| 10404 |
+
namespace std::ranges {
|
| 10405 |
+
template<input_range V>
|
| 10406 |
+
requires view<V>
|
| 10407 |
+
class to_input_view : public view_interface<to_input_view<V>> {
|
| 10408 |
+
V base_ = V(); // exposition only
|
| 10409 |
+
|
| 10410 |
+
// [range.to.input.iterator], class template to_input_view::iterator
|
| 10411 |
+
template<bool Const> class iterator; // exposition only
|
| 10412 |
+
|
| 10413 |
+
public:
|
| 10414 |
+
to_input_view() requires default_initializable<V> = default;
|
| 10415 |
+
constexpr explicit to_input_view(V base);
|
| 10416 |
+
|
| 10417 |
+
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 10418 |
+
constexpr V base() && { return std::move(base_); }
|
| 10419 |
+
|
| 10420 |
+
constexpr auto begin() requires (!simple-view<V>);
|
| 10421 |
+
constexpr auto begin() const requires range<const V>;
|
| 10422 |
+
|
| 10423 |
+
constexpr auto end() requires (!simple-view<V>);
|
| 10424 |
+
constexpr auto end() const requires range<const V>;
|
| 10425 |
+
|
| 10426 |
+
constexpr auto size() requires sized_range<V>;
|
| 10427 |
+
constexpr auto size() const requires sized_range<const V>;
|
| 10428 |
+
|
| 10429 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 10430 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 10431 |
+
};
|
| 10432 |
+
|
| 10433 |
+
template<class R>
|
| 10434 |
+
to_input_view(R&&) -> to_input_view<views::all_t<R>>;
|
| 10435 |
+
}
|
| 10436 |
+
```
|
| 10437 |
+
|
| 10438 |
+
``` cpp
|
| 10439 |
+
constexpr explicit to_input_view(V base);
|
| 10440 |
+
```
|
| 10441 |
+
|
| 10442 |
+
*Effects:* Initializes *base\_* with `std::move(base)`.
|
| 10443 |
+
|
| 10444 |
+
``` cpp
|
| 10445 |
+
constexpr auto begin() requires (!simple-view<V>);
|
| 10446 |
+
```
|
| 10447 |
+
|
| 10448 |
+
*Effects:* Equivalent to:
|
| 10449 |
+
`return `*`iterator`*`<false>(ranges::begin(`*`base_`*`));`
|
| 10450 |
+
|
| 10451 |
+
``` cpp
|
| 10452 |
+
constexpr auto begin() const requires range<const V>;
|
| 10453 |
+
```
|
| 10454 |
+
|
| 10455 |
+
*Effects:* Equivalent to:
|
| 10456 |
+
`return `*`iterator`*`<true>(ranges::begin(`*`base_`*`));`
|
| 10457 |
+
|
| 10458 |
+
``` cpp
|
| 10459 |
+
constexpr auto end() requires (!simple-view<V>);
|
| 10460 |
+
constexpr auto end() const requires range<const V>;
|
| 10461 |
+
```
|
| 10462 |
+
|
| 10463 |
+
*Effects:* Equivalent to: `return ranges::end(`*`base_`*`);`
|
| 10464 |
+
|
| 10465 |
+
``` cpp
|
| 10466 |
+
constexpr auto size() requires sized_range<V>;
|
| 10467 |
+
constexpr auto size() const requires sized_range<const V>;
|
| 10468 |
+
```
|
| 10469 |
+
|
| 10470 |
+
*Effects:* Equivalent to: `return ranges::size(`*`base_`*`);`
|
| 10471 |
+
|
| 10472 |
+
``` cpp
|
| 10473 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 10474 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 10475 |
+
```
|
| 10476 |
+
|
| 10477 |
+
*Effects:* Equivalent to: `return ranges::reserve_hint(`*`base_`*`);`
|
| 10478 |
+
|
| 10479 |
+
#### Class template `to_input_view::iterator` <a id="range.to.input.iterator">[[range.to.input.iterator]]</a>
|
| 10480 |
+
|
| 10481 |
+
``` cpp
|
| 10482 |
+
namespace std::ranges {
|
| 10483 |
+
template<input_range V>
|
| 10484 |
+
requires view<V>
|
| 10485 |
+
template<bool Const>
|
| 10486 |
+
class to_input_view<V>::iterator {
|
| 10487 |
+
using Base = maybe-const<Const, V>; // exposition only
|
| 10488 |
+
|
| 10489 |
+
iterator_t<Base> current_ = iterator_t<Base>(); // exposition only
|
| 10490 |
+
|
| 10491 |
+
constexpr explicit iterator(iterator_t<Base> current); // exposition only
|
| 10492 |
+
|
| 10493 |
+
public:
|
| 10494 |
+
using difference_type = range_difference_t<Base>;
|
| 10495 |
+
using value_type = range_value_t<Base>;
|
| 10496 |
+
using iterator_concept = input_iterator_tag;
|
| 10497 |
+
|
| 10498 |
+
iterator() requires default_initializable<iterator_t<Base>> = default;
|
| 10499 |
+
|
| 10500 |
+
iterator(iterator&&) = default;
|
| 10501 |
+
iterator& operator=(iterator&&) = default;
|
| 10502 |
+
|
| 10503 |
+
constexpr iterator(iterator<!Const> i)
|
| 10504 |
+
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
|
| 10505 |
+
|
| 10506 |
+
constexpr iterator_t<Base> base() &&;
|
| 10507 |
+
constexpr const iterator_t<Base>& base() const & noexcept;
|
| 10508 |
+
|
| 10509 |
+
constexpr decltype(auto) operator*() const { return *current_; }
|
| 10510 |
+
|
| 10511 |
+
constexpr iterator& operator++();
|
| 10512 |
+
constexpr void operator++(int);
|
| 10513 |
+
|
| 10514 |
+
friend constexpr bool operator==(const iterator& x, const sentinel_t<Base>& y);
|
| 10515 |
+
|
| 10516 |
+
friend constexpr difference_type operator-(const sentinel_t<Base>& y, const iterator& x)
|
| 10517 |
+
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
|
| 10518 |
+
friend constexpr difference_type operator-(const iterator& x, const sentinel_t<Base>& y)
|
| 10519 |
+
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
|
| 10520 |
+
|
| 10521 |
+
friend constexpr range_rvalue_reference_t<Base> iter_move(const iterator& i)
|
| 10522 |
+
noexcept(noexcept(ranges::iter_move(i.current_)));
|
| 10523 |
+
|
| 10524 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
| 10525 |
+
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
| 10526 |
+
requires indirectly_swappable<iterator_t<Base>>;
|
| 10527 |
+
};
|
| 10528 |
+
}
|
| 10529 |
+
```
|
| 10530 |
+
|
| 10531 |
+
``` cpp
|
| 10532 |
+
constexpr explicit iterator(iterator_t<Base> current);
|
| 10533 |
+
```
|
| 10534 |
+
|
| 10535 |
+
*Effects:* Initializes *current\_* with `std::move(current)`.
|
| 10536 |
+
|
| 10537 |
+
``` cpp
|
| 10538 |
+
constexpr iterator(iterator<!Const> i)
|
| 10539 |
+
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
|
| 10540 |
+
```
|
| 10541 |
+
|
| 10542 |
+
*Effects:* Initializes *current\_* with `std::move(i.`*`current_`*`)`.
|
| 10543 |
+
|
| 10544 |
+
``` cpp
|
| 10545 |
+
constexpr iterator_t<Base> base() &&;
|
| 10546 |
+
```
|
| 10547 |
+
|
| 10548 |
+
*Returns:* `std::move(`*`current_`*`)`.
|
| 10549 |
+
|
| 10550 |
+
``` cpp
|
| 10551 |
+
constexpr const iterator_t<Base>& base() const & noexcept;
|
| 10552 |
+
```
|
| 10553 |
+
|
| 10554 |
+
*Returns:* *current\_*.
|
| 10555 |
+
|
| 10556 |
+
``` cpp
|
| 10557 |
+
constexpr iterator& operator++();
|
| 10558 |
+
```
|
| 10559 |
+
|
| 10560 |
+
*Effects:* Equivalent to:
|
| 10561 |
+
|
| 10562 |
+
``` cpp
|
| 10563 |
+
++current_;
|
| 10564 |
+
return *this;
|
| 10565 |
+
```
|
| 10566 |
+
|
| 10567 |
+
``` cpp
|
| 10568 |
+
constexpr void operator++(int);
|
| 10569 |
+
```
|
| 10570 |
+
|
| 10571 |
+
*Effects:* Equivalent to: `++*this;`
|
| 10572 |
+
|
| 10573 |
+
``` cpp
|
| 10574 |
+
friend constexpr bool operator==(const iterator& x, const sentinel_t<Base>& y);
|
| 10575 |
+
```
|
| 10576 |
+
|
| 10577 |
+
*Returns:* `x.`*`current_`*` == y`.
|
| 10578 |
+
|
| 10579 |
+
``` cpp
|
| 10580 |
+
friend constexpr difference_type operator-(const sentinel_t<Base>& y, const iterator& x)
|
| 10581 |
+
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
|
| 10582 |
+
```
|
| 10583 |
+
|
| 10584 |
+
*Returns:* `y - x.`*`current_`*.
|
| 10585 |
+
|
| 10586 |
+
``` cpp
|
| 10587 |
+
friend constexpr difference_type operator-(const iterator& x, const sentinel_t<Base>& y)
|
| 10588 |
+
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
|
| 10589 |
+
```
|
| 10590 |
+
|
| 10591 |
+
*Returns:* `x.`*`current_`*` - y`.
|
| 10592 |
+
|
| 10593 |
+
``` cpp
|
| 10594 |
+
friend constexpr range_rvalue_reference_t<Base> iter_move(const iterator& i)
|
| 10595 |
+
noexcept(noexcept(ranges::iter_move(i.current_)));
|
| 10596 |
+
```
|
| 10597 |
+
|
| 10598 |
+
*Effects:* Equivalent to: `return ranges::iter_move(i.`*`current_`*`);`
|
| 10599 |
+
|
| 10600 |
+
``` cpp
|
| 10601 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
| 10602 |
+
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
| 10603 |
+
requires indirectly_swappable<iterator_t<Base>>;
|
| 10604 |
+
```
|
| 10605 |
+
|
| 10606 |
+
*Effects:* Equivalent to:
|
| 10607 |
+
`ranges::iter_swap(x.`*`current_`*`, y.`*`current_`*`);`
|
| 10608 |
+
|