concat_view
presents a view
factory that takes an arbitrary number of ranges as an argument list, and provides a view that starts at the first element of the first range, ends at the last element of the last range, with all range elements sequenced in between respectively in the order given in the arguments, effectively concatenating, or chaining together the argument ranges.
The class template with a template parameter that is a non-empty pack of
view
s
each of which models at least
input_range
and is
concatable
(7)
.
2)views::concat
is a customization point object.
Given a pack of subexpressions exprs, the expression views::concat(exprs...) is expression-equivalent to
input_range
,The
iterator::value_type
that additionally respects the underlying rangesâ
value_type
to support the cases when the underlying ranges have proxy iterators.
5) The rvalue reference that also correctly supports the cases where underlying iterators customize iter_move
.
Defines the
indirectly-readable
concept for the
iterator
so that
concat_view
can model
input_range
.
Equivalent to:
template< class... Rs > concept /*concat-indirectly-readable*/ = // exposition only std::common_reference_with</*concat-reference-t*/<Rs...>&&, /*concat-value-t*/<Rs...>&> && std::common_reference_with</*concat-reference-t*/<Rs...>&&, /*concat-rvalue-reference-t*/<Rs...>&&> && std::common_reference_with</*concat-rvalue-reference-t*/<Rs...>&&, /*concat-value-t*/<Rs...> const&> && (/*concat-indirectly-readable-impl*/</*concat-reference-t*/<Rs...>, /*concat-rvalue-reference-t*/<Rs...>, ranges::iterator_t<Rs>> && ...);
where exposition-only concept
/*concat-indirectly-readable-impl*/is
7)Determines whether any two or more different ranges can be adapted into a sequence that itself models a range. Equivalent to:
template< class... Rs > concept /*concatable*/ = requires { // exposition only typename /*concat-reference-t*/<Rs...>; typename /*concat-value-t*/<Rs...>; typename /*concat-rvalue-reference-t*/<Rs...>; } && /*concat-indirectly-readable*/<Rs...>;
concat_view
always models input_range
, and models forward_range
, bidirectional_range
, random_access_range
, or sized_range
if each adapted view
type models the corresponding concept.
concat_view
can be common_range
if the last underlying range models common_range
.
The name views::concat
denotes a customization point object, which is a const function object of a literal semiregular
class type. See CustomizationPointObject for details.
views_
all adapted view objects
concat_view
sized_range
sized_range
or forward_range
std::ranges::view_interface<D>
) [edit] returns a constant iterator to the beginning of the range
std::ranges::view_interface<D>
) [edit] returns a sentinel for the constant iterator of the range
std::ranges::view_interface<D>
) [edit] returns whether the derived view is not empty, provided only if ranges::empty is applicable to it
std::ranges::view_interface<D>
) [edit] returns the first element in the derived view, provided if it satisfies forward_range
std::ranges::view_interface<D>
) [edit] returns the last element in the derived view, provided only if it satisfies bidirectional_range
and common_range
std::ranges::view_interface<D>
) [edit] returns the n
th element in the derived view, provided only if it satisfies random_access_range
std::ranges::view_interface<D>
) [edit] [edit] Deduction guides [edit] Nested classes Class name Definition the iterator type
There is no specialization of ranges::enable_borrowed_range for concat_view
, because this would require the iterator implementation to contain a copy of all iterators and sentinels of all underlying ranges at all times.
No argument views::concat() is ill-formed, because there is no reasonable way to determine an element type T
. Single argument views::concat(r) is expression equivalent to views::all(r).
The preliminary version can be checked out on Compiler Explorer.
#include <cassert> #include <list> #include <print> #include <ranges> #include <vector> int main() { std::vector<int> v0{1, 2, 3}, v1{4, 5}; int a[]{6, 7}; int i{8}; auto ie{std::views::single(i)}; auto con = std::views::concat(v0, v1, a, ie); assert(con.size() == v0.size() + v1.size() + std::size(a) + ie.size()); std::println("con.size(): {}", con.size()); std::println("con: {}", con); con[6] = 42; // con is random_access_range, operator[] returns a reference assert(a[1] == 42); // a[1] was modified via con[6] std::println("con: {}", con); std::list<int> l{7, 8}; // list is bidirectional range auto cat = std::views::concat(v0, l); std::println("cat: {}", cat); // cat[0] = 13; // compile-time error: cat is bidirectional => no operator[] }
Output:
con.size(): 8 con: [1, 2, 3, 4, 5, 6, 7, 8] con: [1, 2, 3, 4, 5, 6, 42, 8] cat: [1, 2, 3, 7, 8][edit] References
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4