Skip to main content

std::ranges::generate() algorithm

// (1)
constexpr O generate( O first, S last, F gen );

// (2)
constexpr ranges::borrowed_iterator_t<R> generate( R&& r, F gen );

The type of arguments are generic and have following constraints:

  • O - std::input_or_output_iterator
  • S - std::sentinel_for<O>
  • R - (none)
  • F - std::copy_constructible

Additionally, each overload has the following constraints:

  • (1) - invocable<F&> && indirectly_writable<O, invoke_result_t<F&>>
  • (1) - invocable<F&> && ranges::output_range<R, invoke_result_t<F&>>

(The std:: namespace was ommitted here for readability)

  • (1) Assigns the result of successive invocations of the function object gen to each element in the range [first; last).

  • (2) Same as (2), but uses r as the first source 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.

Parameters

first
last

The range of the elements to modify.

r

The range of the 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.

Exceptions

(none)

Possible implementation

generate(1) and generate(2)
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 {};

Examples

Main.cpp
#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);
}
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
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::ranges::generate() algorithm

// (1)
constexpr O generate( O first, S last, F gen );

// (2)
constexpr ranges::borrowed_iterator_t<R> generate( R&& r, F gen );

The type of arguments are generic and have following constraints:

  • O - std::input_or_output_iterator
  • S - std::sentinel_for<O>
  • R - (none)
  • F - std::copy_constructible

Additionally, each overload has the following constraints:

  • (1) - invocable<F&> && indirectly_writable<O, invoke_result_t<F&>>
  • (1) - invocable<F&> && ranges::output_range<R, invoke_result_t<F&>>

(The std:: namespace was ommitted here for readability)

  • (1) Assigns the result of successive invocations of the function object gen to each element in the range [first; last).

  • (2) Same as (2), but uses r as the first source 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.

Parameters

first
last

The range of the elements to modify.

r

The range of the 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.

Exceptions

(none)

Possible implementation

generate(1) and generate(2)
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 {};

Examples

Main.cpp
#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);
}
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
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.