Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/algorithm/ranges/generate"

From cppreference.com
< cpp‎ | algorithm‎ | ranges
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>
+
    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 {
+
    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>
+
 
 +
    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 {
+
    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) { std::cout << i << ' '; }
+
{
 +
     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
+
|p=true
| output=
+
|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

 
 
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy, ranges::sort, ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
(C++11)                (C++11)(C++11)

Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17)(C++11)
(C++20)(C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
(C++11)
(C++17)
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
 
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
       
       
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
       
       
Permutation operations
Fold operations
Numeric operations
(C++23)            
Operations on uninitialized storage
Return types
 
Defined in header <algorithm>
Call signature
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

          generate( O first, S last, F gen );
(1) (since C++20)
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>

          generate( R&& r, F gen );
(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:

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

#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

saves the result of N applications of a function
(niebloid)[edit]
assigns a range of elements a certain value
(niebloid)[edit]
assigns a value to a number of elements
(niebloid)[edit]
applies a function to a range of elements
(niebloid)[edit]
assigns the results of successive function calls to every element in a range
(function template) [edit]