Difference between revisions of "cpp/algorithm/ranges/generate"
From cppreference.com
m (→Top: fmt) |
m (fmt) |
||
Line 2: | Line 2: | ||
{{cpp/algorithm/ranges/navbar}} | {{cpp/algorithm/ranges/navbar}} | ||
{{dcl begin}} | {{dcl begin}} | ||
− | {{dcl header | algorithm}} | + | {{dcl header|algorithm}} |
− | {{dcl h | Call signature}} | + | {{dcl h|Call signature}} |
− | {{dcl | num=1 | since=c++20 |1= | + | {{dcl|num=1|since=c++20|1= |
template< std::input_or_output_iterator O, std::sentinel_for<O> S, | template< std::input_or_output_iterator O, std::sentinel_for<O> S, | ||
std::copy_constructible F > | std::copy_constructible F > | ||
Line 11: | Line 11: | ||
generate( O first, S last, F gen ); | generate( O first, S last, F gen ); | ||
}} | }} | ||
− | {{dcl | num=2 | since=c++20 |1= | + | {{dcl|num=2|since=c++20|1= |
template< class R, std::copy_constructible F > | template< class R, std::copy_constructible F > | ||
requires std::invocable<F&> && ranges::output_range<R, std::invoke_result_t<F&>> | requires std::invocable<F&> && ranges::output_range<R, std::invoke_result_t<F&>> | ||
Line 27: | Line 27: | ||
===Parameters=== | ===Parameters=== | ||
{{par begin}} | {{par begin}} | ||
− | {{par | first, last | the range of elements to modify}} | + | {{par|first, last|the range of elements to modify}} |
− | {{par | r | the range of elements to modify}} | + | {{par|r|the range of elements to modify}} |
− | {{par | gen | the generator function object}} | + | {{par|gen|the generator function object}} |
{{par end}} | {{par end}} | ||
Line 39: | Line 39: | ||
===Possible implementation=== | ===Possible implementation=== | ||
− | {{eq fun | 1= | + | {{eq fun|1= |
− | struct generate_fn { | + | struct generate_fn |
− | + | { | |
− | + | template<std::input_or_output_iterator O, std::sentinel_for<O> S, | |
+ | std::copy_constructible F> | ||
requires std::invocable<F&> && std::indirectly_writable<O, std::invoke_result_t<F&>> | requires std::invocable<F&> && std::indirectly_writable<O, std::invoke_result_t<F&>> | ||
− | + | constexpr O operator()( O first, S last, F gen ) const | |
− | for (; first != last; *first = std::invoke(gen), ++first) | + | { |
+ | for (; first != last; *first = std::invoke(gen), ++first) | ||
+ | {} | ||
return first; | return first; | ||
− | + | } | |
− | + | ||
+ | template<class R, std::copy_constructible F> | ||
requires std::invocable<F&> && ranges::output_range<R, std::invoke_result_t<F&>> | requires std::invocable<F&> && ranges::output_range<R, std::invoke_result_t<F&>> | ||
− | + | constexpr ranges::borrowed_iterator_t<R> operator()( R&& r, F gen ) const | |
+ | { | ||
return (*this)(ranges::begin(r), ranges::end(r), std::move(gen)); | return (*this)(ranges::begin(r), ranges::end(r), std::move(gen)); | ||
− | + | } | |
}; | }; | ||
Line 59: | Line 64: | ||
===Example=== | ===Example=== | ||
− | {{example| code= | + | {{example|code= |
#include <algorithm> | #include <algorithm> | ||
#include <array> | #include <array> | ||
Line 66: | Line 71: | ||
#include <string_view> | #include <string_view> | ||
− | auto dice() { | + | auto dice() |
+ | { | ||
static std::uniform_int_distribution<int> distr{1, 6}; | static std::uniform_int_distribution<int> distr{1, 6}; | ||
static std::random_device device; | static std::random_device device; | ||
Line 73: | Line 79: | ||
} | } | ||
− | void iota(auto& v, int n) { | + | void iota(auto& v, int n) |
− | std::ranges::generate(v, [&n] () mutable { return n++; }); | + | { |
+ | std::ranges::generate(v, [&n]() mutable { return n++; }); | ||
} | } | ||
− | void print(std::string_view comment, const auto& v) { | + | void print(std::string_view comment, const auto& v) |
− | for (std::cout << comment; int i : v) | + | { |
+ | for (std::cout << comment; int i : v) | ||
+ | std::cout << i << ' '; | ||
std::cout << '\n'; | std::cout << '\n'; | ||
} | } | ||
Line 94: | Line 103: | ||
print("iota: ", v); | print("iota: ", v); | ||
} | } | ||
− | + | |p=true | |
− | + | |output= | |
− | dice: 4 3 1 6 6 4 5 5 | + | dice: 4 3 1 6 6 4 5 5 |
− | dice: 4 2 5 3 6 2 6 2 | + | dice: 4 2 5 3 6 2 6 2 |
− | iota: 1 2 3 4 5 6 7 8 | + | iota: 1 2 3 4 5 6 7 8 |
}} | }} | ||
===See also=== | ===See also=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc inc | cpp/algorithm/ranges/dsc generate_n}} | + | {{dsc inc|cpp/algorithm/ranges/dsc generate_n}} |
− | {{dsc inc | cpp/algorithm/ranges/dsc fill}} | + | {{dsc inc|cpp/algorithm/ranges/dsc fill}} |
− | {{dsc inc | cpp/algorithm/ranges/dsc fill_n}} | + | {{dsc inc|cpp/algorithm/ranges/dsc fill_n}} |
− | {{dsc inc | cpp/algorithm/ranges/dsc transform}} | + | {{dsc inc|cpp/algorithm/ranges/dsc transform}} |
− | {{dsc inc | cpp/algorithm/dsc generate}} | + | {{dsc inc|cpp/algorithm/dsc generate}} |
{{dsc end}} | {{dsc end}} | ||
{{langlinks|de|es|fr|it|ja|pt|ru|zh}} | {{langlinks|de|es|fr|it|ja|pt|ru|zh}} |
Revision as of 10:12, 18 January 2023
Defined in header <algorithm>
|
||
Call signature |
||
template< std::input_or_output_iterator O, std::sentinel_for<O> S, std::copy_constructible F > |
(1) | (since C++20) |
template< class R, std::copy_constructible F > requires std::invocable<F&> && ranges::output_range<R, std::invoke_result_t<F&>> |
(2) | (since C++20) |
1) Assigns the result of successive invocations of the function object
gen
to each element in the range [first, last)
.2) Same as (1), but uses
r
as the range, as if using ranges::begin(r) as first
and ranges::end(r) as last
.The function-like entities described on this page are niebloids, that is:
- Explicit template argument lists cannot be specified when calling any of them.
- None of them are visible to argument-dependent lookup.
- When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.
In practice, they may be implemented as function objects, or with special compiler extensions.
Contents |
Parameters
first, last | - | the range of elements to modify |
r | - | the range of elements to modify |
gen | - | the generator function object |
Return value
An output iterator that compares equal to last
.
Complexity
Exactly ranges::distance(first, last) invocations of gen()
and assignments.
Possible implementation
struct generate_fn { template<std::input_or_output_iterator O, std::sentinel_for<O> S, std::copy_constructible F> requires std::invocable<F&> && std::indirectly_writable<O, std::invoke_result_t<F&>> constexpr O operator()( O first, S last, F gen ) const { for (; first != last; *first = std::invoke(gen), ++first) {} return first; } template<class R, std::copy_constructible F> requires std::invocable<F&> && ranges::output_range<R, std::invoke_result_t<F&>> constexpr ranges::borrowed_iterator_t<R> operator()( R&& r, F gen ) const { return (*this)(ranges::begin(r), ranges::end(r), std::move(gen)); } }; inline constexpr generate_fn generate{}; |
Example
Run this code
#include <algorithm> #include <array> #include <iostream> #include <random> #include <string_view> auto dice() { static std::uniform_int_distribution<int> distr{1, 6}; static std::random_device device; static std::mt19937 engine{device()}; return distr(engine); } void iota(auto& v, int n) { std::ranges::generate(v, [&n]() mutable { return n++; }); } void print(std::string_view comment, const auto& v) { for (std::cout << comment; int i : v) std::cout << i << ' '; std::cout << '\n'; } int main() { std::array<int, 8> v; std::ranges::generate(v.begin(), v.end(), dice); print("dice: ", v); std::ranges::generate(v, dice); print("dice: ", v); iota(v, 1); print("iota: ", v); }
Possible output:
dice: 4 3 1 6 6 4 5 5 dice: 4 2 5 3 6 2 6 2 iota: 1 2 3 4 5 6 7 8
See also
(C++20) |
saves the result of N applications of a function (niebloid) |
(C++20) |
assigns a range of elements a certain value (niebloid) |
(C++20) |
assigns a value to a number of elements (niebloid) |
(C++20) |
applies a function to a range of elements (niebloid) |
assigns the results of successive function calls to every element in a range (function template) |