1. Introduction
This paper proposes a new range factory, 
2. Changelog
2.1. R1
Elaborate on only having a single factory.
Add the missing Motivation contents.
Drop a bunch of the comparison operators of the iterator type in favor of just having 
As a result of SG-9’s review of this paper, the constructor overload set of 
- 
     removing the constructors from a repeat_view views :: take views :: drop 
- 
     replacing the two in_place_t piecewise_construct_t 
Various fixes of issues found after publishing an R0:
- 
     typos ( iterator_catetogy 
- 
     size const 
- 
     the definition of the view was using movable - box copyable - box 
- 
     removed the spurious constraint from the default constructor of the iterator type; 
- 
     replaced & foo addressof ( foo ) 
- 
     made the specification of views :: take views :: drop 
- 
     added a deduction guide; 
- 
     added a constraint that the value type of the range must be an unqualified object type. 
2.2. R0
Initial revision.
3. Motivation
Similarly to 
4. Design
This paper proposes the following additions to the Ranges library:
- 
     A new view type, repeat_view iota_view 
- 
     A new customization point object, views :: repeat repeat_view views :: iota 
- 
     An extension for the semantics of views :: take views :: drop repeat_view repeat_view 
[P2214R1] suggests that 
This paper proposes to only have a single factory, 
4.1. repeat_view 
   
4.2. views :: repeat 
   
4.3. Move-only types and borrowed range
Currently, there is no support for move-only types to be stored inside views; as is, this impacts 
This paper also proposes that iterators to 
This, however, means that 
4.4. Category
4.5. Other properties
4.6. views :: take views :: drop 
   
For 
5. Implementation experience
Range-v3 implements both the bounded and the unbounded variants of 
6. Wording
6.1. Addition to < ranges > 
   Add the following to 24.2 [range.syn], Header 
namespace std :: ranges { // ... namespace views { inline constexpr unspecified iota = unspecified ; } // [range.repeat], repeat view template < copy_constructible W , semiregular Bound = unreachable_sentinel_t > requires ( is_object_v < W > && same_as < W , remove_cv_t < W >> && ( is - integer - like < Bound > || same_as < Bound , unreachable_sentinel_t > )) class repeat_view ; namespace views { inline constexpr unspecified repeat = unspecified ; } // [range.istream], istream view // ... } 
6.2. Repeat view [range.repeat]
Add a new section, Repeat view [range.repeat], after Iota view [range.iota].
6.2.1. Overview [range.repeat.overview]
- 
     repeat_view 
- 
     The name views :: repeat E F views :: repeat ( E ) views :: repeat ( E , F ) repeat_view ( E ) repeat_view ( E , F ) 
- 
     [ Example: 
 -- end example ]for ( int i : views :: repeat ( 17 , 4 )) cout << i << ' ' ; // prints: 17 17 17 17 
6.2.2. Class template repeat_view 
namespace std :: ranges { template < copy_constructible W , semiregular Bound = unreachable_sentinel_t > requires ( is_object_v < W > && same_as < W , remove_cv_t < W >> && ( is - integer - like < Bound > || same_as < Bound , unreachable_sentinel_t > )) class repeat_view : public view_interface < repeat_view < W , Bound >> { private : // [range.repeat.iterator], class range_view::iterator struct iterator ; copyable - box < W > value_ = W (); // exposition only, see [range.copy.wrap] Bound bound_ = Bound (); // exposition only public : repeat_view () requires default_initializable < W > = default ; constexpr explicit repeat_view ( const W & value , Bound bound = Bound ()); constexpr explicit repeat_view ( W && value , Bound bound = Bound ()); template < class ... WArgs , class ... BoundArgs > requires constructible_from < W , WArgs ... > && constructible_from < Bound , BoundArgs ... > constexpr explicit repeat_view ( piecewise_construct_t , tuple < Wargs ... > value_args , tuple < BoundArgs ... > bound_args = tuple <> {}); constexpr iterator begin () const ; constexpr iterator end () const requires ( ! same_as < Bound , unreachable_sentinel_t > ); constexpr unreachable_sentinel_t end () const ; constexpr auto size () const requires ( ! same_as < Bound , unreachable_sentinel_t > ); }; template < class W , class Bound > repeat_view ( W , Bound ) -> repeat_view < W , Bound > ; } 
constexpr explicit repeat_view ( const W & value , Bound bound = Bound ()); 
- 
     Effects: Initializes value_ value bound_ bound 
constexpr explicit repeat_view ( W && value , Bound bound = Bound ()); 
- 
     Effects: Initializes value_ std :: move ( value ) bound_ bound 
template < class ... WArgs , class ... BoundArgs > requires constructible_from < W , WArgs ... > && constructible_from < Bound , BoundArgs ... > constexpr explicit repeat_view ( piecewise_construct_t , tuple value_args , tuple bound_args = tuple <> {}); 
- 
     Effects: Initializes value_ WArgs ... value_args bound_ BoundArgs ... bound_args x U std :: forward < U > ( x ) 
constexpr iterator begin () const ; 
- 
     Effects: Equivalent to return iterator { addressof ( * value_ )}; 
constexpr iterator end () const requires ( ! same_as < Bound , unreachable_sentinel_t > ); 
- 
     Effects: Equivalent to return iterator { addressof ( * value ), bound_ }; 
constexpr unreachable_sentinel_t end () const ; 
- 
     Effects: Equivalent to return unreachable_sentinel ; 
constexpr auto size () const requires ( ! same_as < Bound , unreachable_sentinel_t > ); 
- 
     Effects: Equivalent to return to - unsigned - like ( bound_ ); 
6.2.3. Class template repeat_view :: iterator 
namespace std :: ranges { template < copy_constructible W , semiregular Bound = unreachable_sentinel_t > requires is - integer - like < Bound > || same_as < Bound , unreachable_sentinel_t > class repeat_view < W , Bound >:: iterator { private : using index_type = // exposition only conditional_t < same_as < Bound , unreachable_sentinel_t > , ptrdiff_t , Bound > ; const W * value_ ; // exposition only index_type current_ = index_type (); // exposition only public : using iterator_concept = random_access_iterator_tag ; using iterator_category = random_access_iterator_tag ; using value_type = W ; using reference = const W & ; using difference = see below ; iterator () = default ; constexpr explicit iterator ( const W * value , index_type b = index_type ()); constexpr const W & operator * () const noexcept ; constexpr iterator & operator ++ (); constexpr iterator operator ++ ( int ); constexpr iterator & operator -- (); constexpr iterator operator -- ( int ); constexpr iterator & operator += ( difference_type n ); constexpr iterator & operator -= ( difference_type n ); constexpr const W & operator []( difference_type n ) const noexcept ; friend constexpr bool operator == ( const iterator & x , const iterator & y ); friend constexpr auto operator <=> ( const iterator & x , const iterator & y ); friend constexpr iterator operator + ( iterator i , difference_type n ); friend constexpr iterator operator + ( difference_type n , iterator i ); friend constexpr iterator operator - ( iterator i , difference_type n ); friend constexpr difference_type operator - ( const iterator & x , const iterator & y ); }; } 
constexpr explicit iterator ( const W * value , index_type b = index_type ()); 
- 
     Effects: Initializes value_ value bound_ b 
constexpr const W & operator * () const noexcept ; 
- 
     Effects: Equivalent to return * value_ ; 
constexpr iterator & operator ++ (); 
- 
     Effects: Equivalent to: 
++ current_ ; return * this ; 
constexpr iterator operator ++ ( int ); 
- 
     Effects: Equivalent to: 
auto tmp = * this ; ++* this ; return tmp ; 
constexpr iterator & operator -- (); 
- 
     Effects: Equivalent to: 
-- current_ ; return * this ; 
constexpr iterator operator -- ( int ); 
- 
     Effects: Equivalent to: 
auto tmp = * this ; --* this ; return tmp ; 
constexpr iterator & operator += ( difference_type n ); 
- 
     Effects: Equivalent to: 
current_ += n ; return * this ; 
constexpr iterator & operator -= ( difference_type n ); 
- 
     Effects: Equivalent to: 
current_ -= n ; return * this ; 
constexpr const W & operator []( difference_type n ) const noexcept ; 
- 
     Effects: Equivalent to return * value_ ; 
friend constexpr bool operator == ( const iterator & x , const iterator & y ); 
- 
     Effects: Equivalent to x . current_ == y . current_ ; 
friend constexpr auto operator <=> ( const iterator & x , const iterator & y ); 
- 
     Effects: Equivalent to x . current <=> y . current_ ; 
friend constexpr iterator operator + ( iterator i , difference_type n ); friend constexpr iterator operator + ( difference_type n , iterator i ); 
- 
     Effects: Equivalent to return iterator { i . value_ , i . current_ + n }; 
friend constexpr iterator operator - ( iterator i , difference_type n ); 
- 
     Effects: Equivalent to return iterator { i . value_ , i . current_ - n }; 
friend constexpr difference_type operator - ( const iterator & x , const iterator & y ); 
- 
     Effects: Equivalent to return x . current_ - y . current_ ; 
6.3. Take view [range.take]
6.3.1. Overview [range.take.overview]
Modify Overview [range.take.overview] paragraph 2 as follows:
2. The name 
- 
     If T ranges :: empty_view (( void ) F , decay - copy ( E )) E F 
- 
     Otherwise, if T random_access_range sized_range span basic_string_view ranges :: subrange U ( ranges :: begin ( E ), ranges :: begin ( E ) + std :: min < D > ( ranges :: distance ( E ), F )) E U - 
       if T span U span < typename T :: element_type > 
- 
       otherwise, if T basic_string_view U T 
- 
       otherwise, T ranges :: subrange U ranges :: subrange < iterator_t < T >> 
 
- 
       
- 
     Otherwise, if T ranges :: iota_view random_access_range sized_range ranges :: iota_view ( * ranges :: begin ( E ), * ( ranges :: begin ( E ) + std :: min < D > ( ranges :: distance ( E ), F ))) E 
- 
      Otherwise, if T ranges :: repeat_view - 
        if T sized_range ranges :: repeat_view < range_value_t < T > , D > ( * E . value_ , std :: min < D > ( ranges :: distance ( E ), F )) E 
- 
        otherwise, ranges :: repeat_view < range_value_t < T > , D > ( E , F ) 
 
- 
        
- 
     Otherwise, ranges :: take_view ( E , F ) 
6.4. Drop view [range.drop]
6.4.1. Overview [range.drop.overview]
Modify Overview [range.drop.overview] paragraph 2 as follows:
2. The name 
- 
     If T ranges :: empty_view (( void ) F , decay - copy ( E )) E F 
- 
     Otherwise, if T random_access_range sized_range - 
       a specialization of span 
- 
       a specialization of basic_string_view 
- 
       a specialization of ranges :: iota_view 
- 
       a specialization of ranges :: subrange T :: StoreSize false,
 then U ( ranges :: begin ( E ) + std :: min < D > ( ranges :: distance ( E ), F ), ranges :: end ( E )) E U span < typename T :: element_type > T span T 
- 
       
- 
     Otherwise, if T ranges :: subrange random_access_range sized_range T ( ranges :: begin ( E ) + std :: min < D > ( ranges :: distance ( E ), F ), ranges :: end ( E ), to - unsigned - like ( ranges :: distance ( E ) - std :: min < D > ( ranges :: distance ( E ), F ))) E F 
- 
      Otherwise, if T ranges :: repeat_view - 
        if T sized_range ranges :: repeat_view < range_value_t < T > , D > ( * E . value_ , ranges :: distance ( E ) - std :: min < D > ( ranges :: distance ( E ), F )) 
- 
        otherwise, (( void ) F , decay - copy ( E )) E F 
 
- 
        
- 
     Otherwise, ranges :: drop_view ( E , F ) 
6.5. Feature-test macro
    Add the following macro definition to Header 
    
#define __cpp_lib_ranges_repeat 20XXXXL // also in <ranges>