[range.join.with.view]

# 25 Ranges library [[ranges]](./#ranges)

## 25.7 Range adaptors [[range.adaptors]](range.adaptors#range.join.with.view)

### 25.7.15 Join with view [[range.join.with]](range.join.with#view)

#### 25.7.15.2 Class template join_with_view [range.join.with.view]

[ð](#lib:join_with_view)

namespace std::ranges {template<class R>concept [*bidirectional-common*](#concept:bidirectional-common "25.7.15.2 Class template join_­with_­view [range.join.with.view]") = [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<R> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<R>; // *exposition only*template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<V>>&& [view](range.view#concept:view "25.4.5 Views [range.view]")<Pattern>&& [*concatable*](range.concat.view#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]")<range_reference_t<V>, Pattern>class join_with_view : public view_interface<join_with_view<V, Pattern>> {using *InnerRng* = range_reference_t<V>; // *exposition only* V *base_* = V(); // *exposition only**non-propagating-cache*<iterator_t<V>> *outer_it_*; // *exposition only*, present only// when ![forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V>*non-propagating-cache*<remove_cv_t<*InnerRng*>> *inner_*; // *exposition only*, present only// if is_reference_v<*InnerRng*> is false Pattern *pattern_* = Pattern(); // *exposition only*// [[range.join.with.iterator]](range.join.with.iterator "25.7.15.3 Class template join_­with_­view​::​iterator"), class template join_with_view​::​*iterator*template<bool Const> struct *iterator*; // *exposition only*// [[range.join.with.sentinel]](range.join.with.sentinel "25.7.15.4 Class template join_­with_­view​::​sentinel"), class template join_with_view​::​*sentinel*template<bool Const> struct *sentinel*; // *exposition only*public: join_with_view()requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_­initializable [concept.default.init]")<V> && [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_­initializable [concept.default.init]")<Pattern> = default; constexpr explicit join_with_view(V base, Pattern pattern); template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_­from [concept.constructible]")<V, views::all_t<R>> &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_­from [concept.constructible]")<Pattern, single_view<range_value_t<*InnerRng*>>>constexpr explicit join_with_view(R&& r, range_value_t<*InnerRng*> e); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_­constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V>) {constexpr bool use_const =[*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && is_reference_v<*InnerRng*> && [*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Pattern>; return *iterator*<use_const>{*this, ranges::begin(*base_*)}; }else {*outer_it_* = ranges::begin(*base_*); return *iterator*<false>{*this}; }}constexpr auto begin() constrequires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const V> &&[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const Pattern> && is_reference_v<range_reference_t<const V>> &&[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<const V>> &&[*concatable*](range.concat.view#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]")<range_reference_t<const V>, const Pattern> {return *iterator*<true>{*this, ranges::begin(*base_*)}; }constexpr auto end() {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> && is_reference_v<*InnerRng*> && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*InnerRng*> &&[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<*InnerRng*>)return *iterator*<[*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && [*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Pattern>>{*this, ranges::end(*base_*)}; elsereturn *sentinel*<[*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && [*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Pattern>>{*this}; }constexpr auto end() constrequires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const V> && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const Pattern> && is_reference_v<range_reference_t<const V>> &&[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<const V>> &&[*concatable*](range.concat.view#concept:concatable "25.7.18.2 Class template concat_­view [range.concat.view]")<range_reference_t<const V>, const Pattern> {using InnerConstRng = range_reference_t<const V>; if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<InnerConstRng> &&[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<InnerConstRng>)return *iterator*<true>{*this, ranges::end(*base_*)}; elsereturn *sentinel*<true>{*this}; }}; template<class R, class P> join_with_view(R&&, P&&) -> join_with_view<views::all_t<R>, views::all_t<P>>; template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R> join_with_view(R&&, range_value_t<range_reference_t<R>>)-> join_with_view<views::all_t<R>, single_view<range_value_t<range_reference_t<R>>>>;}

[ð](#lib:join_with_view,constructor)

`constexpr explicit join_with_view(V base, Pattern pattern);
`

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7311)

*Effects*: Initializes *base_* with std​::​move(base) and*pattern_* with std​::​move(pattern)[.](#1.sentence-1)

[ð](#lib:join_with_view,constructor_)

`template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R>
  requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_­from [concept.constructible]")<V, views::all_t<R>> &&
           [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_­from [concept.constructible]")<Pattern, single_view<range_value_t<InnerRng>>>
constexpr explicit join_with_view(R&& r, range_value_t<InnerRng> e);
`

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7326)

*Effects*: Initializes *base_* with views​::​all(std​::​forward<R>(r)) and*pattern_* with views​::​single(std​::​move(e))[.](#2.sentence-1)
