Namespaces
Variants
Views
Actions

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

From cppreference.com
< cpp‎ | ranges
m (Data members: {{dsc expos...}})
(Added anchors to data members.)
 
(16 intermediate revisions by 4 users not shown)
Line 6: Line 6:
 
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
 
class iota_view
 
     : public ranges::view_interface<iota_view<W, Bound>>
 
     : public ranges::view_interface<iota_view<W, Bound>>
Line 29: Line 29:
  
 
@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 [[cpp/language/expressions#Expression-equivalence|expression-equivalent]] to {{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/ranges/cpo|views|iota}}
 
{{cpp/ranges/cpo|views|iota}}
Line 35: Line 35:
 
===Data members===
 
===Data members===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc hitem|Member name|Definition}}
+
{{dsc hitem|Member|Definition}}
{{dsc expos mem obj|value_|private=yes|The beginning value of type {{tt|W}}.}}
+
{{dsc expos mem obj|spec={{tt|W}}|value_|id=value|the beginning value}}
{{dsc expos mem obj|bound_|private=yes|The sentinel value of type {{tt|Bound}}.}}
+
{{dsc expos mem obj|spec={{tt|Bound}}|bound_|id=bound|the sentinel value, may be unreachable}}
 
{{dsc end}}
 
{{dsc end}}
  
 
===Member functions===
 
===Member functions===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc mem ctor|notes={{mark c++20}}|{{PAGENAME}}#ctor|creates an {{ttt|iota_view}}}}
+
{{dsc mem ctor|cpp/ranges/iota_view/iota_view|creates an {{tt|iota_view}}}}
{{dsc mem fun|notes={{mark c++20}}|{{PAGENAME}}#begin|title=begin|obtains the beginning iterator of an {{ttt|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}}|{{PAGENAME}}#end|title=end|obtains the sentinel denoting the end of an {{ttt|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}}|{{PAGENAME}}#size|title=size|obtains the size of an {{ttt|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}}
  
{{anchor|ctor}}
+
==={{rl|deduction guides|Deduction guides}}===
{{member|{{small|std::ranges::iota_view::}}iota_view|2=
+
{{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 explicit iota_view( std::type_identity_t<W> value,
+
                              std::type_identity_t<Bound> bound );
+
}}
+
{{dcl|num=4|since=c++20|
+
constexpr explicit iota_view( /* iterator */ first, /* see below */ last );
+
}}
+
{{dcl end}}
+
 
+
@1@ Value-initializes {{c|value_}} and {{c|bound_}} via their default member initializers ({{c|1== W()}} and {{c|1== Bound()}}).
+
 
+
@2@ Initializes {{c|value_}} with {{c|value}} and value-initializes {{c|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 {{c|value_}} with {{c|value}} and {{c|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 {{c|value_}} is initialized with the {{tt|W}} value stored in {{c|first}}, and
+
* if {{tt|W}} and {{tt|Bound}} are the same type, then the type of {{c|last}} is {{c|/* iterator */}} and {{tt|bound_}} initialized with the {{tt|W}} value stored in {{c|last}},
+
* otherwise, if the {{tt|iota_view}} is unbounded (i.e. {{tt|Bound}} is {{lc|std::unreachable_sentinel_t}}), then the type of {{c|last}} is {{lc|std::unreachable_sentinel_t}} and {{c|bound_}} initialized with {{lc|std::unreachable_sentinel}}.
+
* otherwise, the type of {{c|last}} is {{c|/* sentinel */}} and {{c|bound_}} initialized with the {{tt|Bound}} value stored in {{c|last}}.
+
In any case, the type of {{c|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 {{c|bound_}} is initialized to a value unreachable from {{c|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}}
+
}}
+
 
+
{{anchor|begin}}
+
{{member|{{small|std::ranges::iota_view::}}begin|2=
+
{{ddcl|since=c++20|
+
constexpr /* iterator */ begin() const;
+
}}
+
 
+
Returns an {{rl|iterator}} initialized with {{c|value_}}.
+
}}
+
 
+
{{anchor|end}}
+
{{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/core|/* 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_}}.
+
}}
+
 
+
{{anchor|size}}
+
{{member|{{small|std::ranges::iota_view::}}size|2=
+
{{ddcl|since=c++20|
+
constexpr auto size() const
+
    requires (std::same_as<W, Bound> && /* advanceable */<W>)
+
        {{!!}} (/* is-integer-like */<W> && /* is-integer-like */<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 {{tti|advanceable}} is described in {{rl|iterator|this page}}.
+
 
+
The exposition-only function template {{tti|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/core|/* 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/core|/* 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 {{ttt|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}}
  
Line 167: Line 62:
 
{{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 {{rlpt|borrowed_range|std::ranges::enable_borrowed_range}} makes {{ttt|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===
Line 202: Line 97:
 
     std::cout << '\n';
 
     std::cout << '\n';
 
      
 
      
     std::ranges::for_each(std::views::iota(1, 10), [](int i)
+
     std::ranges::for_each(std::views::iota(1, 10),
    {
+
                          [](int i){ std::cout << i << ' '; });
        std::cout << i << ' ';
+
    });
+
 
     std::cout << '\n';
 
     std::cout << '\n';
 
}
 
}
Line 218: 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|wg=lwg|dr=3610|std=C++20|before={{tt|size}} might reject integer-class types|after=accept if possible}}
+
{{dr list item|wg=lwg|dr=3714|paper=P2711R1|std=C++20|before=the multi-parameter constructors were not explicit|after=made explicit}}
+
 
{{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}}

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]