Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/ranges/iota view"

From cppreference.com
< cpp‎ | ranges
m (Synopsis: + "since C++20")
(Added anchors to data members.)
 
(31 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{cpp/ranges/view title | iota}}
+
{{cpp/ranges/view title|iota}}
 
{{cpp/ranges/iota_view/navbar}}
 
{{cpp/ranges/iota_view/navbar}}
 
 
{{dcl begin}}
 
{{dcl begin}}
{{dcl header | ranges}}
+
{{dcl header|ranges}}
{{dcl | num=1 | since=c++20 | 1=
+
{{dcl|num=1|since=c++20|1=
 
template< std::weakly_incrementable W,
 
template< std::weakly_incrementable W,
 
           std::semiregular Bound = std::unreachable_sentinel_t >
 
           std::semiregular Bound = std::unreachable_sentinel_t >
     requires __WeaklyEqualityComparableWith<W, Bound> && std::copyable<W>
+
     requires /*weakly-equality-comparable-with*/<W, Bound> && std::copyable<W>
class iota_view : public ranges::view_interface<iota_view<W, Bound>>
+
class iota_view
 +
    : public ranges::view_interface<iota_view<W, Bound>>
 
}}
 
}}
{{dcl | num=2 | since=c++20 | 1=
+
{{dcl|num=2|since=c++20|1=
 
namespace views {
 
namespace views {
     inline constexpr /*unspecified*/ iota = /*unspecified*/;
+
     inline constexpr /* unspecified */ iota = /* unspecified */;
 
}
 
}
 
}}
 
}}
 
{{dcl h|Call signature}}
 
{{dcl h|Call signature}}
{{dcl | since=c++20 |1=
+
{{dcl|since=c++20|1=
 
template< class W >
 
template< class W >
 
     requires /* see below */
 
     requires /* see below */
constexpr /*see below*/ iota( W&& value );
+
constexpr /* see below */ iota( W&& value );
 
}}
 
}}
{{dcl | since=c++20 |1=
+
{{dcl|since=c++20|1=
 
template< class W, class Bound >
 
template< class W, class Bound >
 
     requires /* see below */
 
     requires /* see below */
constexpr /*see below*/ iota( W&& value, Bound&& bound );
+
constexpr /* see below */ iota( W&& value, Bound&& bound );
 
}}
 
}}
 
{{dcl end}}
 
{{dcl end}}
  
 
@1@ A range factory that generates a sequence of elements by repeatedly incrementing an initial value. Can be either bounded or unbounded (infinite).
 
@1@ A range factory that generates a sequence of elements by repeatedly incrementing an initial value. Can be either bounded or unbounded (infinite).
@2@ {{c|views::iota(e)}} and {{c|views::iota(e, f)}} are ''expression-equivalent'' to (has the same effect as) {{c|iota_view(e)}} and {{c|iota_view(e, f)}} respectively for any suitable subexpressions {{c|e}} and {{c|f}}.<!-- LWG 3524 -->
+
@2@ {{c|views::iota(e)}} and {{c|views::iota(e, f)}} are [[cpp/language/expressions#Expression-equivalence|expression-equivalent]] to {{c|iota_view<std::decay_t<decltype((e))>>(e)}} and {{c|iota_view(e, f)}} respectively for any suitable subexpressions {{c|e}} and {{c|f}}.
  
{{cpp/expr-eq}}
 
 
{{cpp/ranges/cpo|views|iota}}
 
{{cpp/ranges/cpo|views|iota}}
  
 
===Data members===
 
===Data members===
Typical implementation of {{tt|iota_view}} holds two non-static data members: the beginning value {{tt|value_}} of type {{tt|W}} and the sentinel value {{tt|bound_}} of type {{tt|Bound}}. The names shown here are exposition-only.
+
{{dsc begin}}
 +
{{dsc hitem|Member|Definition}}
 +
{{dsc expos mem obj|spec={{tt|W}}|value_|id=value|the beginning value}}
 +
{{dsc expos mem obj|spec={{tt|Bound}}|bound_|id=bound|the sentinel value, may be unreachable}}
 +
{{dsc end}}
  
 
===Member functions===
 
===Member functions===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc mem ctor | notes={{mark c++20}} | nolink=true | creates a {{tt|iota_view}} }}
+
{{dsc mem ctor|cpp/ranges/iota_view/iota_view|creates an {{tt|iota_view}}}}
{{dsc mem fun | notes={{mark c++20}} | begin | nolink=true | obtains the beginning iterator of an {{tt|iota_view}} }}
+
{{dsc mem fun|cpp/ranges/iota_view/begin|obtains the beginning iterator of an {{tt|iota_view}}}}
{{dsc mem fun | notes={{mark c++20}} | end | nolink=true | obtains the sentinel denoting the end of an {{tt|iota_view}} }}
+
{{dsc mem fun|cpp/ranges/iota_view/end|obtains the sentinel denoting the end of an {{tt|iota_view}}}}
{{dsc mem fun | notes={{mark c++20}} | size | nolink=true | obtains the size of an {{tt|iota_view}} if it is sized}}
+
{{dsc mem fun|cpp/ranges/iota_view/empty|tests whether the {{tt|iota_view}} is empty (i.e. the iterator and the sentinel compare equal)}}
 +
{{dsc mem fun|cpp/ranges/iota_view/size|notes={{mark optional}}|obtains the size of an {{tt|iota_view}} (only provided if it is bounded)}}
  
{{cpp/ranges/view_interface/inherit|embedded=yes|data=invalid|size=yes}}
+
{{cpp/ranges/view_interface/inherit|embedded=yes|data=invalid|empty=invalid|size=yes}}
 
{{dsc end}}
 
{{dsc end}}
  
{{member | {{small|std::ranges::iota_view::}}iota_view | 2=
+
==={{rl|deduction guides|Deduction guides}}===
{{dcl begin}}
+
{{dcl | num=1 | since=c++20 |1=
+
iota_view() requires std::default_initializable<W> = default;<!-- P2325R3 -->
+
}}
+
{{dcl | num=2 | since=c++20 |
+
constexpr explicit iota_view( W value );
+
}}
+
{{dcl | num=3 | since=c++20 |
+
constexpr iota_view( std::type_identity_t<W> value,
+
                    std::type_identity_t<Bound> bound );
+
}}
+
{{dcl | num=4 | since=c++20 |
+
constexpr iota_view( /*iterator*/ first, /*see below*/ last );
+
}}
+
{{dcl end}}
+
 
+
@1@ Value-initializes {{tt|value_}} and {{tt|bound_}} via their default member initializers ({{c|1== W()}} and {{c|1== Bound()}}).
+
 
+
@2@ Initializes {{tt|value_}} with {{c|value}} and value-initializes {{tt|bound_}}. This constructor is used to create unbounded {{tt|iota_view}}s, e.g. {{c|iota(0)}} yields numbers 0,1,2..., infinitely.
+
 
+
@3@ Initializes {{tt|value_}} with {{c|value}} and {{tt|bound_}} with {{c|bound}}. The behavior is undefined if {{c|std::totally_ordered_with<W, Bound>}} is modeled and {{c|1=bool(value <= bound)}} is {{c|false}}. This constructor is used to create bounded iota views, e.g. {{c|iota(10, 20)}} yields numbers from 10 to 19.
+
 
+
@4@ Same as {{v|3}}, except that {{tt|value_}} is initialized with the {{tt|W}} value stored in {{tt|first}}, and
+
* if {{tt|W}} and {{tt|Bound}} are the same type, then the type of {{tt|last}} is {{c|/*iterator*/}} and {{tt|bound_}} initialized with the {{tt|W}} value stored in {{tt|last}},
+
* otherwise, if the {{tt|iota_view}} is unbounded (i.e. {{tt|Bound}} is {{lc|std::unreachable_sentinel_t}}), then the type of {{tt|last}} is {{lc|std::unreachable_sentinel_t}} and {{tt|bound_}} initialized with {{lc|std::unreachable_sentinel}}.
+
* otherwise, the type of {{tt|last}} is {{c|/*sentinel*/}} and {{tt|bound_}} initialized with the {{tt|Bound}} value stored in {{tt|last}}.
+
In any case, the type of {{tt|last}} is same as {{c|decltype(end())}}.
+
 
+
For {{v|2}}, {{v|3}}, and {{v|4}}, the behavior is undefined if the {{tt|iota_view}} is bounded (i.e. {{tt|Bound}} is not {{lc|std::unreachable_sentinel_t}}) and {{tt|bound_}} is initialized to a value unreachable from {{tt|value_}}.
+
 
+
===Parameters===
+
{{par begin}}
+
{{par | value | the starting value }}
+
{{par | bound | the bound }}
+
{{par | first | the iterator denoting the starting value }}
+
{{par | last | the iterator or sentinel denoting the bound }}
+
{{par end}}
+
}}
+
 
+
{{member | {{small|std::ranges::iota_view::}}begin| 2=
+
{{ddcl|since=c++20|
+
constexpr /*iterator*/ begin() const;
+
}}
+
 
+
Returns an {{rl|iterator}} initialized with {{c|value_}}.
+
}}
+
 
+
{{member | {{small|std::ranges::iota_view::}}end| 2=
+
{{dcl begin}}
+
{{dcl|num=1|since=c++20|
+
constexpr auto end() const;
+
}}
+
{{dcl|num=2|since=c++20|
+
constexpr /*iterator*/ end() const requires std::same_as<W, Bound>;
+
}}
+
{{dcl end}}
+
@1@ Returns a {{rl|sentinel}} of a specific type (shown as {{c|/*sentinel/}} here) initialized with {{c|bound_}} if this view is bounded, or {{lc|std::unreachable_sentinel}} if this view is unbounded.
+
@2@ Returns an {{rl|iterator}} initialized with {{c|bound_}}.
+
}}
+
 
+
{{member | {{small|std::ranges::iota_view::}}size| 2=
+
{{ddcl | since=c++20 |
+
constexpr auto size() const
+
  requires (std::same_as<W, Bound> && /*advanceable*/<W>) {{!!}}
+
          (std::integral<W> && std::integral<Bound>) {{!!}}
+
            std::sized_sentinel_for<Bound, W>
+
{
+
  if constexpr (/*is-integer-like*/<W> && /*is-integer-like*/<Bound>)
+
    return (value_ < 0)
+
      ? ((bound_ < 0)
+
        ? /*to-unsigned-like*/(-value_) - /*to-unsigned-like*/(-bound_)
+
        : /*to-unsigned-like*/(bound_) + /*to-unsigned-like*/(-value_))
+
      : /*to-unsigned-like*/(bound_) - /*to-unsigned-like*/(value_);
+
  else
+
    return /*to-unsigned-like*/(bound_ - value_);
+
}
+
}}
+
 
+
Returns the size of the view if the view is bounded.
+
 
+
The exposition-only concept {{tt|''advanceable''}} is described in {{rl|iterator|this page}}.
+
 
+
The exposition-only function template {{tt|''to-unsigned-like''}} converts its argument (which must be [[cpp/iterator/weakly_incrementable#Integer-like types|integer-like]]) to the corresponding unsigned version of the argument type.
+
}}
+
 
+
===Deduction guides===
+
{{dcl begin}}
+
{{dcl|since=c++20|1=
+
template<class W, class Bound>
+
    requires (!/*is-integer-like*/<W> {{!!}} !/*is-integer-like*/<Bound> {{!!}}
+
              /*is-signed-integer-like*/<W> == /*is-signed-integer-like*/<Bound>)
+
  iota_view(W, Bound) -> iota_view<W, Bound>;
+
}}
+
{{dcl end}}
+
 
+
For any type {{tt|T}}, {{c|/*is-integer-like*/<T>}} is {{c|true}} if and only if {{tt|T}} is [[cpp/iterator/weakly_incrementable#Integer-like types|integer-like]], and {{c|/*is-signed-integer-like*/<T>}} is {{c|true}} if and only if {{tt|T}} is integer-like and capable of representing negative values.
+
 
+
Note that the guide protects itself against signed/unsigned mismatch bugs, like {{c|views::iota(0, v.size())}}, where {{c|0}} is a (signed) {{c|int}} and {{c|v.size()}} is an (unsigned) {{lc|std::size_t}}.
+
  
 
===Nested classes===
 
===Nested classes===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc expos mem class| cpp/ranges/iota_view/iterator | notes={{mark c++20}} | the iterator type}}
+
{{dsc expos mem class|cpp/ranges/iota_view/iterator|the iterator type}}
{{dsc expos mem class| cpp/ranges/iota_view/sentinel | notes={{mark c++20}} | the sentinel type used when the {{tt|iota_view}} is bounded and {{tt|Bound}} and {{tt|W}} are not the same type}}
+
{{dsc expos mem class|cpp/ranges/iota_view/sentinel|the sentinel type used when the {{tt|iota_view}} is bounded and {{tt|Bound}} and {{tt|W}} are not the same type}}
 
{{dsc end}}
 
{{dsc end}}
  
 
===Helper templates===
 
===Helper templates===
 
{{ddcl|since=c++20|1=
 
{{ddcl|since=c++20|1=
template<std::weakly_incrementable W, std::semiregular Bound>
+
template< std::weakly_incrementable W, std::semiregular Bound >
inline constexpr bool enable_borrowed_range<ranges::iota_view<W, Bound>> = true;
+
constexpr bool ranges::enable_borrowed_range<ranges::iota_view<W, Bound>> = true;
 
}}
 
}}
This specialization of {{ltt|cpp/ranges/borrowed_range|std::ranges::enable_borrowed_range}} makes {{tt|iota_view}} satisfy {{lconcept|borrowed_range}}.
+
This specialization of {{c/core|ranges::enable_borrowed_range}} makes {{tt|iota_view}} satisfy {{lconcept|borrowed_range}}.
  
=== Example ===
+
===Example===
{{example|code=
+
{{example
#include <ranges>
+
|code=
 +
#include <algorithm>
 
#include <iostream>
 
#include <iostream>
 +
#include <ranges>
 +
   
 +
struct Bound
 +
{
 +
    int bound;
 +
    bool operator==(int x) const { return x == bound; }
 +
};
  
 
int main()
 
int main()
Line 170: Line 84:
 
         std::cout << i << ' ';
 
         std::cout << i << ' ';
 
     std::cout << '\n';
 
     std::cout << '\n';
 
+
   
 
     for (int i : std::views::iota(1, 10))
 
     for (int i : std::views::iota(1, 10))
 
         std::cout << i << ' ';
 
         std::cout << i << ' ';
 
     std::cout << '\n';
 
     std::cout << '\n';
 
+
   
 +
    for (int i : std::views::iota(1, Bound{10}))
 +
        std::cout << i << ' ';
 +
    std::cout << '\n';
 +
   
 
     for (int i : std::views::iota(1) {{!}} std::views::take(9))
 
     for (int i : std::views::iota(1) {{!}} std::views::take(9))
 
         std::cout << i << ' ';
 
         std::cout << i << ' ';
 +
    std::cout << '\n';
 +
   
 +
    std::ranges::for_each(std::views::iota(1, 10),
 +
                          [](int i){ std::cout << i << ' '; });
 
     std::cout << '\n';
 
     std::cout << '\n';
 
}
 
}
 
|output=
 
|output=
 +
1 2 3 4 5 6 7 8 9
 +
1 2 3 4 5 6 7 8 9
 
1 2 3 4 5 6 7 8 9
 
1 2 3 4 5 6 7 8 9
 
1 2 3 4 5 6 7 8 9
 
1 2 3 4 5 6 7 8 9
Line 187: Line 111:
 
===Defect reports===
 
===Defect reports===
 
{{dr list begin}}
 
{{dr list begin}}
{{dr list item|wg=lwg|dr=3523|std=C++20|before=iterator-sentinel pair constructor might use wrong sentinel type|after=corrected}}
+
{{dr list item|wg=lwg|dr=4096|std=C++20|before={{tt|views::iota}} could copy an {{tt|iota_view}} as-is|after=forbidden}}
 
{{dr list item|paper=P2325R3|std=C++20|before={{tt|iota_view}} required that {{tt|W}} is {{lconcept|semiregular}}<br>as {{lconcept|view}} required {{lconcept|default_initializable}}|after=only requires that {{tt|W}} is {{lconcept|copyable}}}}
 
{{dr list item|paper=P2325R3|std=C++20|before={{tt|iota_view}} required that {{tt|W}} is {{lconcept|semiregular}}<br>as {{lconcept|view}} required {{lconcept|default_initializable}}|after=only requires that {{tt|W}} is {{lconcept|copyable}}}}
 
{{dr list end}}
 
{{dr list end}}
Line 193: Line 117:
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc inc | cpp/algorithm/dsc iota}}
+
{{dsc inc|cpp/algorithm/dsc iota}}
 +
{{dsc inc|cpp/algorithm/ranges/dsc iota}}
 +
{{dsc inc|cpp/ranges/dsc repeat_view}}
 
{{dsc end}}
 
{{dsc end}}
  
 
{{langlinks|es|ja|ru|zh}}
 
{{langlinks|es|ja|ru|zh}}

Latest revision as of 19:02, 7 October 2024

 
 
Ranges library
Range adaptors
 
 
Defined in header <ranges>
template< std::weakly_incrementable W,

          std::semiregular Bound = std::unreachable_sentinel_t >
    requires /*weakly-equality-comparable-with*/<W, Bound> && std::copyable<W>
class iota_view

    : public ranges::view_interface<iota_view<W, Bound>>
(1) (since C++20)
namespace views {

    inline constexpr /* unspecified */ iota = /* unspecified */;

}
(2) (since C++20)
Call signature
template< class W >

    requires /* see below */

constexpr /* see below */ iota( W&& value );
(since C++20)
template< class W, class Bound >

    requires /* see below */

constexpr /* see below */ iota( W&& value, Bound&& bound );
(since C++20)
1) A range factory that generates a sequence of elements by repeatedly incrementing an initial value. Can be either bounded or unbounded (infinite).
2) views::iota(e) and views::iota(e, f) are expression-equivalent to iota_view<std::decay_t<decltype((e))>>(e) and iota_view(e, f) respectively for any suitable subexpressions e and f.

Contents

Customization point objects

The name views::iota denotes a customization point object, which is a const function object of a literal semiregular class type. For exposition purposes, the cv-unqualified version of its type is denoted as __iota_fn.

All instances of __iota_fn are equal. The effects of invoking different instances of type __iota_fn on the same arguments are equivalent, regardless of whether the expression denoting the instance is an lvalue or rvalue, and is const-qualified or not (however, a volatile-qualified instance is not required to be invocable). Thus, views::iota can be copied freely and its copies can be used interchangeably.

Given a set of types Args..., if std::declval<Args>()... meet the requirements for arguments to views::iota above, __iota_fn models

Otherwise, no function call operator of __iota_fn participates in overload resolution.

[edit] Data members

Member Definition
W value_ the beginning value
(exposition-only member object*)
Bound bound_ the sentinel value, may be unreachable
(exposition-only member object*)

[edit] Member functions

creates an iota_view
(public member function)
obtains the beginning iterator of an iota_view
(public member function)
obtains the sentinel denoting the end of an iota_view
(public member function)
tests whether the iota_view is empty (i.e. the iterator and the sentinel compare equal)
(public member function)
(optional)
obtains the size of an iota_view (only provided if it is bounded)
(public member function)
Inherited from std::ranges::view_interface
(C++23)
returns a constant iterator to the beginning of the range.
(public member function of std::ranges::view_interface<D>) [edit]
(C++23)
returns a sentinel for the constant iterator of the range.
(public member function of std::ranges::view_interface<D>) [edit]
returns whether the derived view is not empty. Provided if ranges::empty is applicable to it.
(public member function of std::ranges::view_interface<D>) [edit]
returns the first element in the derived view. Provided if it satisfies forward_range.
(public member function of std::ranges::view_interface<D>) [edit]
returns the last element in the derived view. Provided if it satisfies bidirectional_range and common_range.
(public member function of std::ranges::view_interface<D>) [edit]
returns the nth element in the derived view. Provided if it satisfies random_access_range.
(public member function of std::ranges::view_interface<D>) [edit]

[edit] Deduction guides

[edit] Nested classes

the iterator type
(exposition-only member class*)
the sentinel type used when the iota_view is bounded and Bound and W are not the same type
(exposition-only member class*)

[edit] Helper templates

template< std::weakly_incrementable W, std::semiregular Bound >
constexpr bool ranges::enable_borrowed_range<ranges::iota_view<W, Bound>> = true;
(since C++20)

This specialization of ranges::enable_borrowed_range makes iota_view satisfy borrowed_range.

[edit] Example

#include <algorithm>
#include <iostream>
#include <ranges>
 
struct Bound
{
    int bound;
    bool operator==(int x) const { return x == bound; }
};
 
int main()
{
    for (int i : std::ranges::iota_view{1, 10})
        std::cout << i << ' ';
    std::cout << '\n';
 
    for (int i : std::views::iota(1, 10))
        std::cout << i << ' ';
    std::cout << '\n';
 
    for (int i : std::views::iota(1, Bound{10}))
        std::cout << i << ' ';
    std::cout << '\n';
 
    for (int i : std::views::iota(1) | std::views::take(9))
        std::cout << i << ' ';
    std::cout << '\n';
 
    std::ranges::for_each(std::views::iota(1, 10),
                          [](int i){ std::cout << i << ' '; });
    std::cout << '\n';
}

Output:

1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 4096 C++20 views::iota could copy an iota_view as-is forbidden
P2325R3 C++20 iota_view required that W is semiregular
as view required default_initializable
only requires that W is copyable

[edit] See also

(C++11)
fills a range with successive increments of the starting value
(function template) [edit]
fills a range with successive increments of the starting value
(niebloid)[edit]
a view consisting of a generated sequence by repeatedly producing the same value
(class template) (customization point object)[edit]