namespace std::ranges {
  template<input_range V>
    requires view<V> && input_range<range_reference_t<V>>
  class join_view : public view_interface<join_view<V>> {
  private:
    using InnerRng = range_reference_t<V>;                  
    
    template<bool Const>
      struct iterator;                                      
    
    template<bool Const>
      struct sentinel;                                      
    V base_ = V();                                          
    non-propagating-cache<iterator_t<V>> outer_;            
                                                            
    non-propagating-cache<remove_cv_t<InnerRng>> inner_;    
                                                            
  public:
    join_view() requires default_initializable<V> = default;
    constexpr explicit join_view(V base);
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
    constexpr auto begin() {
      if constexpr (forward_range<V>) {
        constexpr bool use_const = simple-view<V> &&
                                   is_reference_v<InnerRng>;
        return iterator<use_const>{*this, ranges::begin(base_)};
      } else {
        outer_ = ranges::begin(base_);
        return iterator<false>{*this};
      }
    }
    constexpr auto begin() const
      requires forward_range<const V> &&
               is_reference_v<range_reference_t<const V>> &&
               input_range<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>>{*this, ranges::end(base_)};
      else
        return sentinel<simple-view<V>>{*this};
    }
    constexpr auto end() const
      requires forward_range<const V> &&
               is_reference_v<range_reference_t<const V>> &&
               input_range<range_reference_t<const V>> {
      if constexpr (forward_range<range_reference_t<const V>> &&
                    common_range<const V> &&
                    common_range<range_reference_t<const V>>)
        return iterator<true>{*this, ranges::end(base_)};
      else
        return sentinel<true>{*this};
    }
  };
  template<class R>
    explicit join_view(R&&) -> join_view<views::all_t<R>>;
}
 constexpr explicit join_view(V base);
Effects: Initializes 
base_ with 
std::move(base).