26 Ranges library [ranges]

26.7 Range adaptors [range.adaptors]

26.7.15 Join with view [range.join.with]

26.7.15.2 Class template join_­with_­view [range.join.with.view]

namespace std::ranges { template<class R, class P> concept compatible-joinable-ranges = // exposition only common_­with<range_value_t<R>, range_value_t<P>> && common_­reference_­with<range_reference_t<R>, range_reference_t<P>> && common_­reference_­with<range_rvalue_reference_t<R>, range_rvalue_reference_t<P>>; template<class R> concept bidirectional-common = bidirectional_­range<R> && common_­range<R>; // exposition only template<input_­range V, forward_­range Pattern> requires view<V> && input_­range<range_reference_t<V>> && view<Pattern> && compatible-joinable-ranges<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<remove_cv_t<InnerRng>> inner_; // exposition only, present only // when !is_­reference_­v<InnerRng> Pattern pattern_ = Pattern(); // exposition only // [range.join.with.iterator], class template join_­with_­view​::​iterator template<bool Const> struct iterator; // exposition only // [range.join.with.sentinel], class template join_­with_­view​::​sentinel template<bool Const> struct sentinel; // exposition only public: join_with_view() requires default_­initializable<V> && default_­initializable<Pattern> = default; constexpr join_with_view(V base, Pattern pattern); template<input_­range R> requires constructible_­from<V, views::all_t<R>> && constructible_­from<Pattern, single_view<range_value_t<InnerRng>>> constexpr join_with_view(R&& r, range_value_t<InnerRng> e); constexpr V base() const & requires copy_­constructible<V> { return base_; } constexpr V base() && { return std::move(base_); } constexpr auto begin() { constexpr bool use_const = simple-view<V> && is_reference_v<InnerRng> && simple-view<Pattern>; return iterator<use_const>{*this, ranges::begin(base_)}; } constexpr auto begin() const requires input_­range<const V> && forward_­range<const Pattern> && is_reference_v<range_reference_t<const V>> { return iterator<true>{*this, ranges::begin(base_)}; } constexpr auto end() { if constexpr (forward_­range<V> && is_reference_v<InnerRng> && forward_­range<InnerRng> && common_­range<V> && common_­range<InnerRng>) return iterator<simple-view<V> && simple-view<Pattern>>{*this, ranges::end(base_)}; else return sentinel<simple-view<V> && simple-view<Pattern>>{*this}; } constexpr auto end() const requires input_­range<const V> && forward_­range<const Pattern> && is_reference_v<range_reference_t<const V>> { using InnerConstRng = range_reference_t<const V>; if constexpr (forward_­range<const V> && forward_­range<InnerConstRng> && common_­range<const V> && common_­range<InnerConstRng>) return iterator<true>{*this, ranges::end(base_)}; else return 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 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>>>>; }
constexpr join_with_view(V base, Pattern pattern);
Effects: Initializes base_­ with std​::​move(base) and pattern_­ with std​::​move(pattern).
template<input_­range R> requires constructible_­from<V, views::all_t<R>> && constructible_­from<Pattern, single_view<range_value_t<InnerRng>>> constexpr join_with_view(R&& r, range_value_t<InnerRng> e);
Effects: Initializes base_­ with views​::​all(std​::​forward<R>(r)) and pattern_­ with views​::​single(std​::​move(e)).