Files
2025-10-25 03:02:53 +03:00

9.8 KiB
Raw Permalink Blame History

[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]

1

#

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.

2

#

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]

3

#

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)>; };

4

#

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)); }); };

5

#

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.6Other range refinements[range.refinements]") R, class... Args> requires (![view](range.view#concept:view "25.4.5Views[range.view]")<C>) constexpr C to(R&& r, Args&&... args);

1

#

Mandates: C is a cv-unqualified class type.

2

#

Returns: An object of type C constructed from the elements of r in the following manner:

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.

  • (2.2)

    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)...);

  • (2.3)

    Otherwise, the program is ill-formed.

🔗

template<template<class...> class C, [input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R, class... Args> constexpr auto to(R&& r, Args&&... args);

3

#

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]

4

#

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.

5

#

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 (![view](range.view#concept:view "25.4.5Views[range.view]")<C>) constexpr auto to(Args&&... args); template<template<class...> class C, class... Args> constexpr auto to(Args&&... args);

1

#

Mandates: For the first overload,C is a cv-unqualified class type.

2

#

Returns: A range adaptor closure object ([range.adaptor.object]) f that is a perfect forwarding call wrapper ([func.require]) with the following properties:

  • (2.1)

    It has no target object.

  • (2.2)

    Its bound argument entities bound_args consist of objects of types decay_t... direct-non-list-initialized with std::forward(args)..., respectively.

  • (2.3)

    Its call pattern is to(r, bound_args...), where r is the argument used in a function call expression of f.