599 lines
41 KiB
Markdown
599 lines
41 KiB
Markdown
[range.utility]
|
||
|
||
# 25 Ranges library [[ranges]](./#ranges)
|
||
|
||
## 25.5 Range utilities [range.utility]
|
||
|
||
### [25.5.1](#general) General [[range.utility.general]](range.utility.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1742)
|
||
|
||
The components in [range.utility] are general utilities for representing and
|
||
manipulating ranges[.](#general-1.sentence-1)
|
||
|
||
### [25.5.2](#helpers) Helper concepts [[range.utility.helpers]](range.utility.helpers)
|
||
|
||
[1](#helpers-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1748)
|
||
|
||
Many of the types in [range.utility] are specified in terms of
|
||
the following exposition-only concepts:template<class R>concept [*simple-view*](#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]") = // *exposition only*[view](range.view#concept:view "25.4.5 Views [range.view]")<R> && [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const R> &&[same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<iterator_t<R>, iterator_t<const R>> &&[same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<sentinel_t<R>, sentinel_t<const R>>;
|
||
|
||
template<class I>concept [*has-arrow*](#concept:has-arrow "25.5.2 Helper concepts [range.utility.helpers]") = // *exposition only*[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_iterator [iterator.concept.input]")<I> && (is_pointer_v<I> || requires(const I i) { i.operator->(); });
|
||
|
||
template<class T, class U>concept [*different-from*](#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]") = // *exposition only*<remove_cvref_t<T>, remove_cvref_t<U>>;
|
||
|
||
template<class R>concept [*range-with-movable-references*](#concept:range-with-movable-references "25.5.2 Helper concepts [range.utility.helpers]") = // *exposition only*[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<R> && [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]")<range_reference_t<R>> &&[move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]")<range_rvalue_reference_t<R>>;
|
||
|
||
### [25.5.3](#view.interface) View interface [[view.interface]](view.interface)
|
||
|
||
#### [25.5.3.1](#view.interface.general) General [[view.interface.general]](view.interface.general)
|
||
|
||
[1](#view.interface.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1776)
|
||
|
||
The class template view_interface is a helper for defining
|
||
view-like types that offer a container-like interface[.](#view.interface.general-1.sentence-1)
|
||
|
||
It is
|
||
parameterized with the type that is derived from it[.](#view.interface.general-1.sentence-2)
|
||
|
||
[ð](#lib:view_interface)
|
||
|
||
namespace std::ranges {template<class D>requires is_class_v<D> && [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<D, remove_cv_t<D>>class view_interface {private:constexpr D& *derived*() noexcept { // *exposition only*return static_cast<D&>(*this); }constexpr const D& *derived*() const noexcept { // *exposition only*return static_cast<const D&>(*this); }public:constexpr bool empty() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<D> || [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<D> {if constexpr ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<D>)return ranges::size(*derived*()) == 0; elsereturn ranges::begin(*derived*()) == ranges::end(*derived*()); }constexpr bool empty() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const D> || [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const D> {if constexpr ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const D>)return ranges::size(*derived*()) == 0; elsereturn ranges::begin(*derived*()) == ranges::end(*derived*()); }constexpr auto cbegin() requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<D> {return ranges::cbegin(*derived*()); }constexpr auto cbegin() const requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<const D> {return ranges::cbegin(*derived*()); }constexpr auto cend() requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<D> {return ranges::cend(*derived*()); }constexpr auto cend() const requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<const D> {return ranges::cend(*derived*()); }constexpr explicit operator bool()requires requires { ranges::empty(*derived*()); } {return !ranges::empty(*derived*()); }constexpr explicit operator bool() constrequires requires { ranges::empty(*derived*()); } {return !ranges::empty(*derived*()); }constexpr auto data() requires [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14 Concept contiguous_iterator [iterator.concept.contiguous]")<iterator_t<D>> {return to_address(ranges::begin(*derived*())); }constexpr auto data() constrequires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const D> && [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14 Concept contiguous_iterator [iterator.concept.contiguous]")<iterator_t<const D>> {return to_address(ranges::begin(*derived*())); }constexpr auto size() requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<D> &&[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<D>, iterator_t<D>> {return *to-unsigned-like*(ranges::end(*derived*()) - ranges::begin(*derived*())); }constexpr auto size() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const D> &&[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<const D>, iterator_t<const D>> {return *to-unsigned-like*(ranges::end(*derived*()) - ranges::begin(*derived*())); }constexpr decltype(auto) front() requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<D>; constexpr decltype(auto) front() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const D>; constexpr decltype(auto) back() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<D> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<D>; constexpr decltype(auto) back() constrequires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<const D> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const D>; template<[random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]") R = D>constexpr decltype(auto) operator[](range_difference_t<R> n) {return ranges::begin(*derived*())[n]; }template<[random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]") R = const D>constexpr decltype(auto) operator[](range_difference_t<R> n) const {return ranges::begin(*derived*())[n]; }};}
|
||
|
||
[2](#view.interface.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1867)
|
||
|
||
The template parameter D for view_interface may be an
|
||
incomplete type[.](#view.interface.general-2.sentence-1)
|
||
|
||
Before any member of the resulting specialization ofview_interface other than special member functions
|
||
is referenced, D shall be complete, and
|
||
model both [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<view_interface<D>> and [view](range.view#concept:view "25.4.5 Views [range.view]")[.](#view.interface.general-2.sentence-2)
|
||
|
||
#### [25.5.3.2](#view.interface.members) Members [[view.interface.members]](view.interface.members)
|
||
|
||
[ð](#lib:front,view_interface)
|
||
|
||
`constexpr decltype(auto) front() requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<D>;
|
||
constexpr decltype(auto) front() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const D>;
|
||
`
|
||
|
||
[1](#view.interface.members-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1883)
|
||
|
||
*Hardened preconditions*: !empty() is true[.](#view.interface.members-1.sentence-1)
|
||
|
||
[2](#view.interface.members-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1887)
|
||
|
||
*Effects*: Equivalent to: return *ranges::begin(*derived*());
|
||
|
||
[ð](#lib:back,view_interface)
|
||
|
||
`constexpr decltype(auto) back() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<D> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<D>;
|
||
constexpr decltype(auto) back() const
|
||
requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<const D> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const D>;
|
||
`
|
||
|
||
[3](#view.interface.members-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1900)
|
||
|
||
*Hardened preconditions*: !empty() is true[.](#view.interface.members-3.sentence-1)
|
||
|
||
[4](#view.interface.members-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1904)
|
||
|
||
*Effects*: Equivalent to: return *ranges::prev(ranges::end(*derived*()));
|
||
|
||
### [25.5.4](#range.subrange) Sub-ranges [[range.subrange]](range.subrange)
|
||
|
||
#### [25.5.4.1](#range.subrange.general) General [[range.subrange.general]](range.subrange.general)
|
||
|
||
[1](#range.subrange.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1913)
|
||
|
||
The subrange class template combines together an
|
||
iterator and a sentinel into a single object that models the[view](range.view#concept:view "25.4.5 Views [range.view]") concept[.](#range.subrange.general-1.sentence-1)
|
||
|
||
Additionally, it models the[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") concept when the final template parameter issubrange_kind::sized[.](#range.subrange.general-1.sentence-2)
|
||
|
||
[ð](#lib:subrange)
|
||
|
||
namespace std::ranges {template<class From, class To>concept [*uses-nonqualification-pointer-conversion*](#concept:uses-nonqualification-pointer-conversion "25.5.4.1 General [range.subrange.general]") = // *exposition only* is_pointer_v<From> && is_pointer_v<To> &&<remove_pointer_t<From>(*)[], remove_pointer_t<To>(*)[]>; template<class From, class To>concept [*convertible-to-non-slicing*](#concept:convertible-to-non-slicing "25.5.4.1 General [range.subrange.general]") = // *exposition only*[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<From, To> &&<decay_t<From>, decay_t<To>>; template<class T, class U, class V>concept [*pair-like-convertible-from*](#concept:pair-like-convertible-from "25.5.4.1 General [range.subrange.general]") = // *exposition only*<T> && !is_reference_v<T> && [*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]")<T> &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<T, U, V> &&[*convertible-to-non-slicing*](#concept:convertible-to-non-slicing "25.5.4.1 General [range.subrange.general]")<U, tuple_element_t<0, T>> &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<V, tuple_element_t<1, T>>; template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6 Concept input_or_output_iterator [iterator.concept.iterator]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I> S = I, subrange_kind K =[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<S, I> ? subrange_kind::sized : subrange_kind::unsized>requires (K == subrange_kind::sized || <S, I>)class subrange : public view_interface<subrange<I, S, K>> {private:static constexpr bool *StoreSize* = // *exposition only* K == subrange_kind::sized && <S, I>;
|
||
I *begin_* = I(); // *exposition only* S *end_* = S(); // *exposition only**make-unsigned-like-t*<iter_difference_t<I>> *size_* = 0; // *exposition only*; present only// if *StoreSize* is truepublic: subrange() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<I> = default; constexpr subrange([*convertible-to-non-slicing*](#concept:convertible-to-non-slicing "25.5.4.1 General [range.subrange.general]")<I> auto i, S s) requires (!*StoreSize*); constexpr subrange([*convertible-to-non-slicing*](#concept:convertible-to-non-slicing "25.5.4.1 General [range.subrange.general]")<I> auto i, S s, *make-unsigned-like-t*<iter_difference_t<I>> n)requires (K == subrange_kind::sized); template<[*different-from*](#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]")<subrange> R>requires [borrowed_range](range.range#concept:borrowed_range "25.4.2 Ranges [range.range]")<R> &&[*convertible-to-non-slicing*](#concept:convertible-to-non-slicing "25.5.4.1 General [range.subrange.general]")<iterator_t<R>, I> &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<R>, S>constexpr subrange(R&& r) requires (!*StoreSize* || [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<R>); template<[borrowed_range](range.range#concept:borrowed_range "25.4.2 Ranges [range.range]") R>requires [*convertible-to-non-slicing*](#concept:convertible-to-non-slicing "25.5.4.1 General [range.subrange.general]")<iterator_t<R>, I> &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<R>, S>constexpr subrange(R&& r, *make-unsigned-like-t*<iter_difference_t<I>> n)requires (K == subrange_kind::sized): subrange{ranges::begin(r), ranges::end(r), n} {}template<[*different-from*](#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]")<subrange> PairLike>requires [*pair-like-convertible-from*](#concept:pair-like-convertible-from "25.5.4.1 General [range.subrange.general]")<PairLike, const I&, const S&>constexpr operator PairLike() const; constexpr I begin() const requires [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<I>; constexpr I begin() requires (<I>); constexpr S end() const; constexpr bool empty() const; constexpr *make-unsigned-like-t*<iter_difference_t<I>> size() constrequires (K == subrange_kind::sized); constexpr subrange next(iter_difference_t<I> n = 1) const &requires [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]")<I>; constexpr subrange next(iter_difference_t<I> n = 1) &&; constexpr subrange prev(iter_difference_t<I> n = 1) constrequires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12 Concept bidirectional_iterator [iterator.concept.bidir]")<I>; constexpr subrange& advance(iter_difference_t<I> n); }; template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6 Concept input_or_output_iterator [iterator.concept.iterator]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I> S> subrange(I, S) -> subrange<I, S>; template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6 Concept input_or_output_iterator [iterator.concept.iterator]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I> S> subrange(I, S, *make-unsigned-like-t*<iter_difference_t<I>>) -> subrange<I, S, subrange_kind::sized>; template<[borrowed_range](range.range#concept:borrowed_range "25.4.2 Ranges [range.range]") R> subrange(R&&) -> subrange<iterator_t<R>, sentinel_t<R>, ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<R> || [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<R>, iterator_t<R>>)? subrange_kind::sized : subrange_kind::unsized>; template<[borrowed_range](range.range#concept:borrowed_range "25.4.2 Ranges [range.range]") R> subrange(R&&, *make-unsigned-like-t*<range_difference_t<R>>) -> subrange<iterator_t<R>, sentinel_t<R>, subrange_kind::sized>;}
|
||
|
||
#### [25.5.4.2](#range.subrange.ctor) Constructors and conversions [[range.subrange.ctor]](range.subrange.ctor)
|
||
|
||
[ð](#lib:subrange,constructor)
|
||
|
||
`constexpr subrange([convertible-to-non-slicing](#concept:convertible-to-non-slicing "25.5.4.1 General [range.subrange.general]")<I> auto i, S s) requires (!StoreSize);
|
||
`
|
||
|
||
[1](#range.subrange.ctor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2020)
|
||
|
||
*Preconditions*: [i, s) is a valid range[.](#range.subrange.ctor-1.sentence-1)
|
||
|
||
[2](#range.subrange.ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2024)
|
||
|
||
*Effects*: Initializes *begin_* with std::move(i) and *end_* withs[.](#range.subrange.ctor-2.sentence-1)
|
||
|
||
[ð](#lib:subrange,constructor_)
|
||
|
||
`constexpr subrange([convertible-to-non-slicing](#concept:convertible-to-non-slicing "25.5.4.1 General [range.subrange.general]")<I> auto i, S s,
|
||
make-unsigned-like-t<iter_difference_t<I>> n)
|
||
requires (K == subrange_kind::sized);
|
||
`
|
||
|
||
[3](#range.subrange.ctor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2038)
|
||
|
||
*Preconditions*: [i, s) is a valid range, andn == *to-unsigned-like*(ranges::distance(i, s)) is true[.](#range.subrange.ctor-3.sentence-1)
|
||
|
||
[4](#range.subrange.ctor-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2044)
|
||
|
||
*Effects*: Initializes *begin_* with std::move(i) and *end_* withs[.](#range.subrange.ctor-4.sentence-1)
|
||
|
||
If *StoreSize* is true, initializes *size_* withn[.](#range.subrange.ctor-4.sentence-2)
|
||
|
||
[5](#range.subrange.ctor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2050)
|
||
|
||
[*Note [1](#range.subrange.ctor-note-1)*:
|
||
|
||
Accepting the length of the range and storing it to later return fromsize() enables subrange to model [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") even
|
||
when it stores an iterator and sentinel that do not model[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")[.](#range.subrange.ctor-5.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:subrange,constructor__)
|
||
|
||
`template<[different-from](#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]")<subrange> R>
|
||
requires [borrowed_range](range.range#concept:borrowed_range "25.4.2 Ranges [range.range]")<R> &&
|
||
[convertible-to-non-slicing](#concept:convertible-to-non-slicing "25.5.4.1 General [range.subrange.general]")<iterator_t<R>, I> &&
|
||
[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<R>, S>
|
||
constexpr subrange(R&& r) requires (!StoreSize || [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<R>);
|
||
`
|
||
|
||
[6](#range.subrange.ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2069)
|
||
|
||
*Effects*: Equivalent to:
|
||
|
||
- [(6.1)](#range.subrange.ctor-6.1)
|
||
|
||
If *StoreSize* is true,subrange(r, static_cast<decltype(*size_*)>(ranges::size(r)))[.](#range.subrange.ctor-6.1.sentence-1)
|
||
|
||
- [(6.2)](#range.subrange.ctor-6.2)
|
||
|
||
Otherwise, subrange(ranges::begin(r), ranges::end(r))[.](#range.subrange.ctor-6.2.sentence-1)
|
||
|
||
[ð](#lib:operator_PairLike,subrange)
|
||
|
||
`template<[different-from](#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]")<subrange> PairLike>
|
||
requires [pair-like-convertible-from](#concept:pair-like-convertible-from "25.5.4.1 General [range.subrange.general]")<PairLike, const I&, const S&>
|
||
constexpr operator PairLike() const;
|
||
`
|
||
|
||
[7](#range.subrange.ctor-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2087)
|
||
|
||
*Effects*: Equivalent to: return PairLike(*begin_*, *end_*);
|
||
|
||
#### [25.5.4.3](#range.subrange.access) Accessors [[range.subrange.access]](range.subrange.access)
|
||
|
||
[ð](#lib:begin,subrange)
|
||
|
||
`constexpr I begin() const requires [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<I>;
|
||
`
|
||
|
||
[1](#range.subrange.access-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2100)
|
||
|
||
*Effects*: Equivalent to: return *begin_*;
|
||
|
||
[ð](#lib:begin,subrange_)
|
||
|
||
`constexpr I begin() requires (<I>);
|
||
`
|
||
|
||
[2](#range.subrange.access-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2111)
|
||
|
||
*Effects*: Equivalent to: return std::move(*begin_*);
|
||
|
||
[ð](#lib:end,subrange)
|
||
|
||
`constexpr S end() const;
|
||
`
|
||
|
||
[3](#range.subrange.access-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2122)
|
||
|
||
*Effects*: Equivalent to: return *end_*;
|
||
|
||
[ð](#lib:empty,subrange)
|
||
|
||
`constexpr bool empty() const;
|
||
`
|
||
|
||
[4](#range.subrange.access-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2133)
|
||
|
||
*Effects*: Equivalent to: return *begin_* == *end_*;
|
||
|
||
[ð](#lib:size,subrange)
|
||
|
||
`constexpr make-unsigned-like-t<iter_difference_t<I>> size() const
|
||
requires (K == subrange_kind::sized);
|
||
`
|
||
|
||
[5](#range.subrange.access-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2145)
|
||
|
||
*Effects*:
|
||
|
||
- [(5.1)](#range.subrange.access-5.1)
|
||
|
||
If *StoreSize* is true, equivalent to: return *size_*;
|
||
|
||
- [(5.2)](#range.subrange.access-5.2)
|
||
|
||
Otherwise, equivalent to: return *to-unsigned-like*(*end_* - *begin_*);
|
||
|
||
[ð](#lib:next,subrange)
|
||
|
||
`constexpr subrange next(iter_difference_t<I> n = 1) const &
|
||
requires [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]")<I>;
|
||
`
|
||
|
||
[6](#range.subrange.access-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2160)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;
|
||
tmp.advance(n);return tmp;
|
||
|
||
[ð](#lib:next,subrange_)
|
||
|
||
`constexpr subrange next(iter_difference_t<I> n = 1) &&;
|
||
`
|
||
|
||
[7](#range.subrange.access-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2176)
|
||
|
||
*Effects*: Equivalent to:advance(n);return std::move(*this);
|
||
|
||
[ð](#lib:prev,subrange)
|
||
|
||
`constexpr subrange prev(iter_difference_t<I> n = 1) const
|
||
requires [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12 Concept bidirectional_iterator [iterator.concept.bidir]")<I>;
|
||
`
|
||
|
||
[8](#range.subrange.access-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2192)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;
|
||
tmp.advance(-n);return tmp;
|
||
|
||
[ð](#lib:advance,subrange)
|
||
|
||
`constexpr subrange& advance(iter_difference_t<I> n);
|
||
`
|
||
|
||
[9](#range.subrange.access-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2208)
|
||
|
||
*Effects*: Equivalent to:if constexpr ([bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12 Concept bidirectional_iterator [iterator.concept.bidir]")<I>) {if (n < 0) { ranges::advance(*begin_*, n); if constexpr (*StoreSize*)*size_* += *to-unsigned-like*(-n); return *this; }}auto d = n - ranges::advance(*begin_*, n, *end_*);if constexpr (*StoreSize*)*size_* -= *to-unsigned-like*(d);return *this;
|
||
|
||
[ð](#lib:get,subrange)
|
||
|
||
`template<size_t N, class I, class S, subrange_kind K>
|
||
requires ((N == 0 && [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<I>) || N == 1)
|
||
constexpr auto get(const subrange<I, S, K>& r);
|
||
template<size_t N, class I, class S, subrange_kind K>
|
||
requires (N < 2)
|
||
constexpr auto get(subrange<I, S, K>&& r);
|
||
`
|
||
|
||
[10](#range.subrange.access-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2239)
|
||
|
||
*Effects*: Equivalent to:if constexpr (N == 0)return r.begin();elsereturn r.end();
|
||
|
||
### [25.5.5](#range.dangling) Dangling iterator handling [[range.dangling]](range.dangling)
|
||
|
||
[1](#range.dangling-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2252)
|
||
|
||
The type dangling is used together with the template aliasesborrowed_iterator_t and borrowed_subrange_t[.](#range.dangling-1.sentence-1)
|
||
|
||
When an algorithm
|
||
that typically returns an iterator into, or a subrange of, a range argument
|
||
is called with an rvalue range argument
|
||
that does not model [borrowed_range](range.range#concept:borrowed_range "25.4.2 Ranges [range.range]") ([[range.range]](range.range "25.4.2 Ranges")),
|
||
the return value possibly refers to a range whose lifetime has ended[.](#range.dangling-1.sentence-2)
|
||
|
||
In such cases,
|
||
the type dangling is returned instead of an iterator or subrange[.](#range.dangling-1.sentence-3)
|
||
|
||
[ð](#lib:dangling)
|
||
|
||
namespace std::ranges {struct dangling {constexpr dangling() noexcept = default; constexpr dangling(auto&&...) noexcept {}};}
|
||
|
||
[2](#range.dangling-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2272)
|
||
|
||
[*Example [1](#range.dangling-example-1)*: vector<int> f();auto result1 = ranges::find(f(), 42); // #1static_assert([same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<decltype(result1), ranges::dangling>);auto vec = f();auto result2 = ranges::find(vec, 42); // #2static_assert([same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<decltype(result2), vector<int>::iterator>);auto result3 = ranges::find(ranges::subrange{vec}, 42); // #3static_assert([same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<decltype(result3), vector<int>::iterator>);
|
||
|
||
The call to ranges::find at #1 returns ranges::dangling since f() is an rvalue vector;
|
||
it is possible for the vector to be destroyed
|
||
before a returned iterator is dereferenced[.](#range.dangling-2.sentence-1)
|
||
|
||
However, the calls at #2 and #3 both return iterators
|
||
since the lvalue vec and specializations of subrange model [borrowed_range](range.range#concept:borrowed_range "25.4.2 Ranges [range.range]")[.](#range.dangling-2.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[3](#range.dangling-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2293)
|
||
|
||
For a type R that models [range](range.range#concept:range "25.4.2 Ranges [range.range]"):
|
||
|
||
- [(3.1)](#range.dangling-3.1)
|
||
|
||
if R models [borrowed_range](range.range#concept:borrowed_range "25.4.2 Ranges [range.range]"), thenborrowed_iterator_t<R> denotes iterator_t<R>, andborrowed_subrange_t<R> denotes subrange<iterator_t<R>>;
|
||
|
||
- [(3.2)](#range.dangling-3.2)
|
||
|
||
otherwise,
|
||
both borrowed_iterator_t<R> and borrowed_subrange_t<R> denote dangling[.](#range.dangling-3.sentence-1)
|
||
|
||
### [25.5.6](#range.elementsof) Class template elements_of [[range.elementsof]](range.elementsof)
|
||
|
||
Specializations of elements_of encapsulate a range and
|
||
act as a tag in overload sets to disambiguate
|
||
when a range should be treated as a sequence
|
||
rather than a single value[.](#range.elementsof-sentence-1)
|
||
|
||
[*Example [1](#range.elementsof-example-1)*: template<bool YieldElements> generator<any> f(ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") auto&& r) {if constexpr (YieldElements)co_yield ranges::elements_of(r); // yield each element of relseco_yield r; // yield r as a single value} â *end example*]
|
||
|
||
namespace std::ranges {template<[range](range.range#concept:range "25.4.2 Ranges [range.range]") R, class Allocator = allocator<byte>>struct elements_of {[[no_unique_address]] R range; [[no_unique_address]] Allocator allocator = Allocator(); }; template<class R, class Allocator = allocator<byte>> elements_of(R&&, Allocator = Allocator()) -> elements_of<R&&, Allocator>;}
|
||
|
||
### [25.5.7](#conv) Range conversions [[range.utility.conv]](range.utility.conv)
|
||
|
||
#### [25.5.7.1](#conv.general) General [[range.utility.conv.general]](range.utility.conv.general)
|
||
|
||
[1](#conv.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2342)
|
||
|
||
The range conversion functions construct
|
||
an object (usually a container) from a range,
|
||
by using a constructor taking a range,
|
||
a from_range_t tagged constructor, or
|
||
a constructor taking a pair of iterators, or
|
||
by inserting each element of the range into the default-constructed object[.](#conv.general-1.sentence-1)
|
||
|
||
[2](#conv.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2350)
|
||
|
||
ranges::to is applied recursively,
|
||
allowing the conversion of a range of ranges[.](#conv.general-2.sentence-1)
|
||
|
||
[*Example [1](#conv.general-example-1)*: string_view str = "the quick brown fox";auto words = views::split(str, ' ') | to<vector<string>>();// words is vector<string>{"the", "quick", "brown", "fox"} â *end example*]
|
||
|
||
[3](#conv.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2362)
|
||
|
||
Let *reservable-container* be defined as follows:template<class Container>constexpr bool *reservable-container* = // *exposition only*[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<Container> &&requires(Container& c, range_size_t<Container> n) { c.reserve(n); { c.capacity() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<decltype(n)>; { c.max_size() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<decltype(n)>; };
|
||
|
||
[4](#conv.general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2375)
|
||
|
||
Let *container-appendable* be defined as follows:template<class Container, class Ref>constexpr bool *container-appendable* = // *exposition only*requires(Container& c, Ref&& ref) {requires (requires { c.emplace_back(std::forward<Ref>(ref)); } ||requires { c.push_back(std::forward<Ref>(ref)); } ||requires { c.emplace(c.end(), std::forward<Ref>(ref)); } ||requires { c.insert(c.end(), std::forward<Ref>(ref)); }); };
|
||
|
||
[5](#conv.general-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2388)
|
||
|
||
Let *container-append* be defined as follows:template<class Container>constexpr auto *container-append*(Container& c) { // *exposition only*return [&c]<class Ref>(Ref&& ref) {if constexpr (requires { c.emplace_back(declval<Ref>()); }) c.emplace_back(std::forward<Ref>(ref)); else if constexpr (requires { c.push_back(declval<Ref>()); }) c.push_back(std::forward<Ref>(ref)); else if constexpr (requires { c.emplace(c.end(), declval<Ref>()); }) c.emplace(c.end(), std::forward<Ref>(ref)); else c.insert(c.end(), std::forward<Ref>(ref)); };}
|
||
|
||
#### [25.5.7.2](#conv.to) ranges::to [[range.utility.conv.to]](range.utility.conv.to)
|
||
|
||
[ð](#lib:to,ranges)
|
||
|
||
`template<class C, [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class... Args> requires (<C>)
|
||
constexpr C to(R&& r, Args&&... args);
|
||
`
|
||
|
||
[1](#conv.to-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2415)
|
||
|
||
*Mandates*: C is a cv-unqualified class type[.](#conv.to-1.sentence-1)
|
||
|
||
[2](#conv.to-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2419)
|
||
|
||
*Returns*: An object of type C constructed from the elements of r in the following manner:
|
||
|
||
- [(2.1)](#conv.to-2.1)
|
||
|
||
If C does not satisfy [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") or[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<range_reference_t<R>, range_value_t<C>> is true:
|
||
* [(2.1.1)](#conv.to-2.1.1)
|
||
|
||
If [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<C, R, Args...> is true:C(std::forward<R>(r), std::forward<Args>(args)...)
|
||
|
||
* [(2.1.2)](#conv.to-2.1.2)
|
||
|
||
Otherwise, if[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<C, from_range_t, R, Args...> is true:C(from_range, std::forward<R>(r), std::forward<Args>(args)...)
|
||
|
||
* [(2.1.3)](#conv.to-2.1.3)
|
||
|
||
Otherwise, if
|
||
+
|
||
[(2.1.3.1)](#conv.to-2.1.3.1)
|
||
[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<R> is true,
|
||
|
||
+
|
||
[(2.1.3.2)](#conv.to-2.1.3.2)
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]")iterator_traits<iterator_t<R>>::iterator_category is valid and denotes a type that models[derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<input_iterator_tag>, and
|
||
|
||
+
|
||
[(2.1.3.3)](#conv.to-2.1.3.3)
|
||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<C, iterator_t<R>, sentinel_t<R>, Args...> is true:
|
||
|
||
C(ranges::begin(r), ranges::end(r), std::forward<Args>(args)...)
|
||
|
||
* [(2.1.4)](#conv.to-2.1.4)
|
||
|
||
Otherwise, if
|
||
+
|
||
[(2.1.4.1)](#conv.to-2.1.4.1)
|
||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<C, Args...> is true, and
|
||
|
||
+
|
||
[(2.1.4.2)](#conv.to-2.1.4.2)
|
||
*container-appendable*<C, range_reference_t<R>> is true:
|
||
|
||
C c(std::forward<Args>(args)...);if constexpr ([approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<R> && *reservable-container*<C>) c.reserve(static_cast<range_size_t<C>>(ranges::reserve_hint(r)));
|
||
ranges::for_each(r, *container-append*(c));
|
||
|
||
* [(2.1.5)](#conv.to-2.1.5)
|
||
|
||
Otherwise, the program is ill-formed[.](#conv.to-2.1.sentence-1)
|
||
|
||
- [(2.2)](#conv.to-2.2)
|
||
|
||
Otherwise,
|
||
if [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<R>> is true:to<C>(ref_view(r) | views::transform([](auto&& elem) {return to<range_value_t<C>>(std::forward<decltype(elem)>(elem));}), std::forward<Args>(args)...);
|
||
|
||
- [(2.3)](#conv.to-2.3)
|
||
|
||
Otherwise, the program is ill-formed[.](#conv.to-2.3.sentence-1)
|
||
|
||
[ð](#lib:to,ranges_)
|
||
|
||
`template<template<class...> class C, [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class... Args>
|
||
constexpr auto to(R&& r, Args&&... args);
|
||
`
|
||
|
||
[3](#conv.to-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2497)
|
||
|
||
Let *input-iterator* be an exposition-only type:struct *input-iterator* { // *exposition only*using iterator_category = input_iterator_tag; using value_type = range_value_t<R>; using difference_type = ptrdiff_t; using pointer = add_pointer_t<range_reference_t<R>>; using reference = range_reference_t<R>;
|
||
reference operator*() const;
|
||
pointer operator->() const; *input-iterator*& operator++(); *input-iterator* operator++(int); bool operator==(const *input-iterator*&) const;};
|
||
|
||
[*Note [1](#conv.to-note-1)*:
|
||
|
||
*input-iterator* meets
|
||
the syntactic requirements of *Cpp17InputIterator*[.](#conv.to-3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[4](#conv.to-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2518)
|
||
|
||
Let *DEDUCE_EXPR* be defined as follows:
|
||
|
||
- [(4.1)](#conv.to-4.1)
|
||
|
||
C(declval<R>(), declval<Args>()...) if that is a valid expression,
|
||
|
||
- [(4.2)](#conv.to-4.2)
|
||
|
||
otherwise, C(from_range, declval<R>(), declval<Args>()...) if that is a valid expression,
|
||
|
||
- [(4.3)](#conv.to-4.3)
|
||
|
||
otherwise,C(declval<*input-iterator*>(), declval<*input-iterator*>(), declval<Args>()...) if that is a valid expression,
|
||
|
||
- [(4.4)](#conv.to-4.4)
|
||
|
||
otherwise, the program is ill-formed[.](#conv.to-4.sentence-1)
|
||
|
||
[5](#conv.to-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2536)
|
||
|
||
*Returns*: to<decltype(*DEDUCE_EXPR*)>(std::forward<R>(r), std::forward<Args>(args)...)[.](#conv.to-5.sentence-1)
|
||
|
||
#### [25.5.7.3](#conv.adaptors) ranges::to adaptors [[range.utility.conv.adaptors]](range.utility.conv.adaptors)
|
||
|
||
[ð](#lib:to,ranges__)
|
||
|
||
`template<class C, class... Args> requires (<C>)
|
||
constexpr auto to(Args&&... args);
|
||
template<template<class...> class C, class... Args>
|
||
constexpr auto to(Args&&... args);
|
||
`
|
||
|
||
[1](#conv.adaptors-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2552)
|
||
|
||
*Mandates*: For the first overload,C is a cv-unqualified class type[.](#conv.adaptors-1.sentence-1)
|
||
|
||
[2](#conv.adaptors-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L2557)
|
||
|
||
*Returns*: A range adaptor closure object ([[range.adaptor.object]](range.adaptor.object "25.7.2 Range adaptor objects")) f that is a perfect forwarding call wrapper ([[func.require]](func.require#term.perfect.forwarding.call.wrapper "22.10.4 Requirements"))
|
||
with the following properties:
|
||
|
||
- [(2.1)](#conv.adaptors-2.1)
|
||
|
||
It has no target object[.](#conv.adaptors-2.1.sentence-1)
|
||
|
||
- [(2.2)](#conv.adaptors-2.2)
|
||
|
||
Its bound argument entities bound_args consist of
|
||
objects of types decay_t<Args>... direct-non-list-initialized with std::forward<Args>(args)...,
|
||
respectively[.](#conv.adaptors-2.2.sentence-1)
|
||
|
||
- [(2.3)](#conv.adaptors-2.3)
|
||
|
||
Its call pattern is to<C>(r, bound_args...),
|
||
where r is the argument used in a function call expression of f[.](#conv.adaptors-2.3.sentence-1)
|