25 Ranges library [ranges]

25.7 Range adaptors [range.adaptors]

25.7.18 Concat view [range.concat]

25.7.18.2 Class template concat_view [range.concat.view]

namespace std::ranges { template<class... Rs> using concat-reference-t = common_reference_t<range_reference_t<Rs>...>; // exposition only template<class... Rs> using concat-value-t = common_type_t<range_value_t<Rs>...>; // exposition only template<class... Rs> using concat-rvalue-reference-t = // exposition only common_reference_t<range_rvalue_reference_t<Rs>...>; template<class... Rs> concept concat-indirectly-readable = see below; // exposition only template<class... Rs> concept concatable = see below; // exposition only template<bool Const, class... Rs> concept concat-is-random-access = see below; // exposition only template<bool Const, class... Rs> concept concat-is-bidirectional = see below; // exposition only template<input_range... Views> requires (view<Views> && ...) && (sizeof...(Views) > 0) && concatable<Views...> class concat_view : public view_interface<concat_view<Views...>> { tuple<Views...> views_; // exposition only // [range.concat.iterator], class template concat_view​::​iterator template<bool> class iterator; // exposition only public: constexpr concat_view() = default; constexpr explicit concat_view(Views... views); constexpr iterator<false> begin() requires (!(simple-view<Views> && ...)); constexpr iterator<true> begin() const requires (range<const Views> && ...) && concatable<const Views...>; constexpr auto end() requires (!(simple-view<Views> && ...)); constexpr auto end() const requires (range<const Views> && ...) && concatable<const Views...>; constexpr auto size() requires (sized_range<Views> && ...); constexpr auto size() const requires (sized_range<const Views> && ...); }; template<class... R> concat_view(R&&...) -> concat_view<views::all_t<R>...>; }
template<class... Rs> concept concat-indirectly-readable = see below; // exposition only
The exposition-only concat-indirectly-readable concept is equivalent to: template<class Ref, class RRef, class It> concept concat-indirectly-readable-impl = // exposition only requires (const It it) { { *it } -> convertible_to<Ref>; { ranges::iter_move(it) } -> convertible_to<RRef>; }; template<class... Rs> concept concat-indirectly-readable = // exposition only common_reference_with<concat-reference-t<Rs...>&&, concat-value-t<Rs...>&> && common_reference_with<concat-reference-t<Rs...>&&, concat-rvalue-reference-t<Rs...>&&> && 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...>, iterator_t<Rs>> && ...);
template<class... Rs> concept concatable = see below; // exposition only
The exposition-only concatable concept is 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...>;
template<bool Const, class... Rs> concept concat-is-random-access = see below; // exposition only
Let Fs be the pack that consists of all elements of Rs except the last element, then concat-is-random-access is equivalent to: template<bool Const, class... Rs> concept concat-is-random-access = // exposition only all-random-access<Const, Rs...> && (common_range<maybe-const<Const, Fs>> && ...);
template<bool Const, class... Rs> concept concat-is-bidirectional = see below; // exposition only
Let Fs be the pack that consists of all elements of Rs except the last element, then concat-is-bidirectional is equivalent to: template<bool Const, class... Rs> concept concat-is-bidirectional = // exposition only all-bidirectional<Const, Rs...> && (common_range<maybe-const<Const, Fs>> && ...);
constexpr explicit concat_view(Views... views);
Effects: Initializes views_ with std​::​move(views)....
constexpr iterator<false> begin() requires (!(simple-view<Views> && ...)); constexpr iterator<true> begin() const requires (range<const Views> && ...) && concatable<const Views...>;
Effects: Let is-const be true for the const-qualified overload, and false otherwise.
Equivalent to: iterator<is-const> it(this, in_place_index<0>, ranges::begin(std::get<0>(views_))); it.template satisfy<0>(); return it;
constexpr auto end() requires (!(simple-view<Views> && ...)); constexpr auto end() const requires (range<const Views> && ...) && concatable<const Views...>;
Effects: Let is-const be true for the const-qualified overload, and false otherwise.
Equivalent to: constexpr auto N = sizeof...(Views); if constexpr (common_range<maybe-const<is-const, Views...[N - 1]>>) { return iterator<is-const>(this, in_place_index<N - 1>, ranges::end(std::get<N - 1>(views_))); } else { return default_sentinel; }
constexpr auto size() requires (sized_range<Views> && ...); constexpr auto size() const requires (sized_range<const Views> && ...);
Effects: Equivalent to: return apply( [](auto... sizes) { using CT = make-unsigned-like-t<common_type_t<decltype(sizes)...>>; return (CT(sizes) + ...); }, tuple-transform(ranges::size, views_));