[range.concat.view] # 25 Ranges library [[ranges]](./#ranges) ## 25.7 Range adaptors [[range.adaptors]](range.adaptors#range.concat.view) ### 25.7.18 Concat view [[range.concat]](range.concat#view) #### 25.7.18.2 Class template concat_view [range.concat.view] [🔗](#lib:concat_view) namespace std::ranges {templateusing *concat-reference-t* = common_reference_t...>; // *exposition only*templateusing *concat-value-t* = common_type_t...>; // *exposition only*templateusing *concat-rvalue-reference-t* = // *exposition only* common_reference_t...>; templateconcept [*concat-indirectly-readable*](#concept:concat-indirectly-readable "25.7.18.2 Class template concat_­view [range.concat.view]") = *see below*; // *exposition only*templateconcept [*concatable*](#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]") = *see below*; // *exposition only*templateconcept [*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_­view [range.concat.view]") = *see below*; // *exposition only*templateconcept [*concat-is-bidirectional*](#concept:concat-is-bidirectional "25.7.18.2 Class template concat_­view [range.concat.view]") = *see below*; // *exposition only*template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")... Views>requires ([view](range.view#concept:view "25.4.5 Views [range.view]") && ...) && (sizeof...(Views) > 0) &&[*concatable*](#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]")class concat_view : public view_interface> { tuple *views_*; // *exposition only*// [[range.concat.iterator]](range.concat.iterator "25.7.18.3 Class concat_­view​::​iterator"), class template concat_view​::​*iterator*template class *iterator*; // *exposition only*public:constexpr concat_view() = default; constexpr explicit concat_view(Views... views); constexpr *iterator* begin() requires (!([*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]") && ...)); constexpr *iterator* begin() constrequires ([range](range.range#concept:range "25.4.2 Ranges [range.range]") && ...) && [*concatable*](#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]"); constexpr auto end() requires (!([*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]") && ...)); constexpr auto end() constrequires ([range](range.range#concept:range "25.4.2 Ranges [range.range]") && ...) && [*concatable*](#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]"); constexpr auto size() requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") && ...); constexpr auto size() const requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") && ...); }; template concat_view(R&&...) -> concat_view...>;} [🔗](#concept:concat-indirectly-readable) `template concept [concat-indirectly-readable](#concept:concat-indirectly-readable "25.7.18.2 Class template concat_­view [range.concat.view]") = see below; // exposition only ` [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8780) The exposition-only [*concat-indirectly-readable*](#concept:concat-indirectly-readable "25.7.18.2 Class template concat_­view [range.concat.view]") concept is equivalent to:templateconcept [*concat-indirectly-readable-impl*](#concept:concat-indirectly-readable-impl "25.7.18.2 Class template concat_­view [range.concat.view]") = // *exposition only*requires (const It it) {{ *it } -> [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]"); { ranges::iter_move(it) } -> [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]"); }; templateconcept [*concat-indirectly-readable*](#concept:concat-indirectly-readable "25.7.18.2 Class template concat_­view [range.concat.view]") = // *exposition only*[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_­reference_­with [concept.commonref]")<*concat-reference-t*&&, *concat-value-t*&> &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_­reference_­with [concept.commonref]")<*concat-reference-t*&&, *concat-rvalue-reference-t*&&> &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_­reference_­with [concept.commonref]")<*concat-rvalue-reference-t*&&, *concat-value-t* const&> &&([*concat-indirectly-readable-impl*](#concept:concat-indirectly-readable-impl "25.7.18.2 Class template concat_­view [range.concat.view]")<*concat-reference-t*, *concat-rvalue-reference-t*, iterator_t> && ...); [🔗](#concept:concatable) `template concept [concatable](#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]") = see below; // exposition only ` [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8811) The exposition-only [*concatable*](#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]") concept is equivalent to:templateconcept [*concatable*](#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]") = requires { // *exposition only*typename *concat-reference-t*; typename *concat-value-t*; typename *concat-rvalue-reference-t*; } && [*concat-indirectly-readable*](#concept:concat-indirectly-readable "25.7.18.2 Class template concat_­view [range.concat.view]"); [🔗](#concept:concat-is-random-access) `template concept [concat-is-random-access](#concept:concat-is-random-access "25.7.18.2 Class template concat_­view [range.concat.view]") = see below; // exposition only ` [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8829) Let Fs be the pack that consists of all elements of Rs except the last element, then *concat-is-random-access* is equivalent to:templateconcept [*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_­view [range.concat.view]") = // *exposition only*[*all-random-access*](range.adaptor.helpers#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]") &&([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*> && ...); [🔗](#concept:concat-is-bidirectional) `template concept [concat-is-bidirectional](#concept:concat-is-bidirectional "25.7.18.2 Class template concat_­view [range.concat.view]") = see below; // exposition only ` [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8848) Let Fs be the pack that consists of all elements of Rs except the last element, then *concat-is-bidirectional* is equivalent to:templateconcept [*concat-is-bidirectional*](#concept:concat-is-bidirectional "25.7.18.2 Class template concat_­view [range.concat.view]") = // *exposition only*[*all-bidirectional*](range.adaptor.helpers#concept:all-bidirectional "25.7.5 Range adaptor helpers [range.adaptor.helpers]") &&([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*> && ...); [🔗](#lib:concat_view,constructor) `constexpr explicit concat_view(Views... views); ` [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8867) *Effects*: Initializes *views_* with std​::​move(views)...[.](#5.sentence-1) [🔗](#lib:begin,concat_view) `constexpr iterator begin() requires (!([simple-view](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]") && ...)); constexpr iterator begin() const requires ([range](range.range#concept:range "25.4.2 Ranges [range.range]") && ...) && [concatable](#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]"); ` [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8880) *Effects*: Let *is-const* betrue for the const-qualified overload, andfalse otherwise[.](#6.sentence-1) Equivalent to:*iterator*<*is-const*> it(this, in_place_index<0>, ranges::begin(std::get<0>(*views_*))); it.template *satisfy*<0>();return it; [🔗](#lib:end,concat_view) `constexpr auto end() requires (!([simple-view](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]") && ...)); constexpr auto end() const requires ([range](range.range#concept:range "25.4.2 Ranges [range.range]") && ...) && [concatable](#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]"); ` [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8901) *Effects*: Let *is-const* betrue for the const-qualified overload, andfalse otherwise[.](#7.sentence-1) Equivalent to:constexpr auto N = sizeof...(Views);if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<*is-const*, Views...[N - 1]>>) {return *iterator*<*is-const*>(this, in_place_index, ranges::end(std::get(*views_*)));} else {return default_sentinel;} [🔗](#lib:size,concat_view) `constexpr auto size() requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") && ...); constexpr auto size() const requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") && ...); ` [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8925) *Effects*: Equivalent to:return apply([](auto... sizes) {using CT = *make-unsigned-like-t*>; return (CT(sizes) + ...); }, *tuple-transform*(ranges::size, *views_*));