9.8 KiB
[range.utility.conv]
25 Ranges library [ranges]
25.5 Range utilities [range.utility]
25.5.7 Range conversions [range.utility.conv]
25.5.7.1 General [range.utility.conv.general]
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.
ranges::to is applied recursively, allowing the conversion of a range of ranges.
[Example 1: string_view str = "the quick brown fox";auto words = views::split(str, ' ') | to<vector>();// words is vector{"the", "quick", "brown", "fox"} â end example]
Let reservable-container be defined as follows:templateconstexpr bool reservable-container = // exposition onlysized_range &&requires(Container& c, range_size_t n) { c.reserve(n); { c.capacity() } -> same_as<decltype(n)>; { c.max_size() } -> same_as<decltype(n)>; };
Let container-appendable be defined as follows:template<class Container, class Ref>constexpr bool container-appendable = // exposition onlyrequires(Container& c, Ref&& ref) {requires (requires { c.emplace_back(std::forward(ref)); } ||requires { c.push_back(std::forward(ref)); } ||requires { c.emplace(c.end(), std::forward(ref)); } ||requires { c.insert(c.end(), std::forward(ref)); }); };
Let container-append be defined as follows:templateconstexpr auto container-append(Container& c) { // exposition onlyreturn [&c](Ref&& ref) {if constexpr (requires { c.emplace_back(declval()); }) c.emplace_back(std::forward(ref)); else if constexpr (requires { c.push_back(declval()); }) c.push_back(std::forward(ref)); else if constexpr (requires { c.emplace(c.end(), declval()); }) c.emplace(c.end(), std::forward(ref)); else c.insert(c.end(), std::forward(ref)); };}
25.5.7.2 ranges::to [range.utility.conv.to]
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);
Mandates: C is a cv-unqualified class type.
Returns: An object of type C constructed from the elements of r in the following manner:
-
If C does not satisfy input_range orconvertible_to<range_reference_t, range_value_t> is true:
If constructible_from<C, R, Args...> is true:C(std::forward(r), std::forward(args)...)
Otherwise, ifconstructible_from<C, from_range_t, R, Args...> is true:C(from_range, std::forward(r), std::forward(args)...)
Otherwise, if + (2.1.3.1) common_range is true,
+
[(2.1.3.2)](#to-2.1.3.2)
the qualified-iditerator_traits<iterator_t>::iterator_category is valid and denotes a type that modelsderived_from<input_iterator_tag>, and
+
[(2.1.3.3)](#to-2.1.3.3)
constructible_from<C, iterator_t, sentinel_t, Args...> is true:
C(ranges::begin(r), ranges::end(r), std::forward(args)...)
Otherwise, if + (2.1.4.1) constructible_from<C, Args...> is true, and
+
[(2.1.4.2)](#to-2.1.4.2)
container-appendable<C, range_reference_t> is true:
C c(std::forward(args)...);if constexpr (approximately_sized_range && reservable-container) c.reserve(static_cast<range_size_t>(ranges::reserve_hint(r))); ranges::for_each(r, container-append(c));
Otherwise, the program is ill-formed.
-
Otherwise, if input_range<range_reference_t> is true:to(ref_view(r) | views::transform([](auto&& elem) {return to<range_value_t>(std::forward<decltype(elem)>(elem));}), std::forward(args)...);
-
Otherwise, the program is ill-formed.
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);
Let input-iterator be an exposition-only type:struct input-iterator { // exposition onlyusing iterator_category = input_iterator_tag; using value_type = range_value_t; using difference_type = ptrdiff_t; using pointer = add_pointer_t<range_reference_t>; using reference = range_reference_t; reference operator*() const; pointer operator->() const; input-iterator& operator++(); input-iterator operator++(int); bool operator==(const input-iterator&) const;};
[Note 1:
input-iterator meets the syntactic requirements of Cpp17InputIterator.
â end note]
Let DEDUCE_EXPR be defined as follows:
C(declval(), declval()...) if that is a valid expression,
otherwise, C(from_range, declval(), declval()...) if that is a valid expression,
otherwise,C(declval<input-iterator>(), declval<input-iterator>(), declval()...) if that is a valid expression,
otherwise, the program is ill-formed.
Returns: to<decltype(DEDUCE_EXPR)>(std::forward(r), std::forward(args)...).
25.5.7.3 ranges::to adaptors [range.utility.conv.adaptors]
template<class C, class... Args> requires (<C>) constexpr auto to(Args&&... args); template<template<class...> class C, class... Args> constexpr auto to(Args&&... args);
Mandates: For the first overload,C is a cv-unqualified class type.
Returns: A range adaptor closure object ([range.adaptor.object]) f that is a perfect forwarding call wrapper ([func.require]) with the following properties: