<algorithm>
class std::ranges::in_fun_result (C++20)
template< class I, class F >
struct in_fun_result;
ranges::in_fun_result is a class template that provides a way to store an iterator and a function object as a single unit.
This class template has no base classes or declared members other than those shown below. Thus it is suitable for use with structured bindings.
| Member name |
Definition |
| in |
a value (that is supposed to be an iterator) of type I. |
| fun |
a value (that is supposed to be a function object) of type F. |
template<class I2, class F2>
requires std::converible_to<const I&, I2> && std::convertible_to<const F&, F2>
constexpr operator in_fun_result<I2, F2>() const &;
template<class I2, class F2>
requires std::convertible_to<I, I2> && std::convertible_to<F, F2>
constexpr operator in_fun_result<I2, F2>() &&;
| Algorithm functions |
Definition |
| ranges::for_each (c++20) |
applies a unary function object to elements from a range |
| ranges::for_each_n (c++20) |
applies a function object to the first N elements of a sequence |
namespace std::ranges
{
template<class I, class F>
struct in_fun_result
{
[[no_unique_address]] I in;
[[no_unique_address]] F fun;
template<class I2, class F2>
requires std::convertible_to<const I&, I2> && std::convertible_to<const F&, F2>
constexpr operator in_fun_result<I2, F2>() const &
{
return {in, fun};
}
template<class I2, class F2>
requires std::convertible_to<I, I2> && std::convertible_to<F, F2>
constexpr operator in_fun_result<I2, F2>() &&
{
return {std::move(in), std::move(fun)};
}
}
}
Each standard library algorithm that uses this family of return types declares a new alias type, e.g. using merge_result = in_in_out_result<I1, I2, O>;.
The names for such aliases are formed by adding the suffix “_result” to the algorithm’s name. So, the return type of std::ranges::merge can be named as std::ranges::merge_result.
Unlike std::pair and std::tuple, this class template has data members of meaningful names.
#include <algorithm>
#include <cassert>
#include <iostream>
#include <iterator>
#include <ranges>
int main()
{
int v[]{1, 2, 3};
const std::ranges::in_fun_result res1 = std::ranges::for_each_n(
v,
std::size(v),
[](int& x) {result x = -x;}
);
assert(res1.in == std::end(v));
const std::ranges::in_fun_result res2 = std::ranges::for_each(
std::begin(v),
res1.in,
[](int x) { std::cout << x << ' '; }
)
std::cout << "| ";
std::ranges::for_each(v, res1.fun);
std::ranges::for_each(v, res2.fun);
std::cout << "\n";
}
std::ranges::in_in_result (C++20)
template< class I1, class I2 >
struct in_in_result;
ranges::in_in_result is a class template that provides a way to store two iterators as a single unit.
This class template has no base classes or declared members other than those shown below. Thus it is suitable for use with structured bindings.
All special member functions of this class template are implicitly declared, which makes specializations be aggregate classes, and propagate triviality, potentially-throwing-ness, and constexpr-ness of corresponding operations on data members.
-
Template parameters
- I1, I2: the types of the iterators that the ranges::in_in_result stores.
-
Data members
| Member name |
Definition |
| in1 |
a value (that supposed to be an iterator) of type I1. |
| in2 |
a value (that supposed to be an iterator) of type I2. |
All these members are declared with attribute.
std::ranges::in_in_result::operator in_in_resuly<II2, II2>
template<class II1, class II2>
requires std::convertible_to<const I1&, II1> && std::convertible_to<const I2&, II2>
constexpr operator in_in_result<II1, II2>() const &;
template<class II1, class II2>
requires std::convertible_to<I1, II1> && std::convertible_to<I2, II2>
constexpr operator in_in_result<II1, II2>() &&;
*
| Algorithm functions |
Definition |
| ranges::mismatch (C++20) |
finds the first position where two ranges differ |
| ranges::swap_ranges (C++20) |
swaps two ranges of elements |
namespace std::ranges
{
template<class I1, class I2>
struct in_in_result
{
[[no_unique_address]] I1 in1;
[[no_unique_address]] I2 in2;
template<class II1, class II2>
requires std::convertible_to<const I1&, II1> && std::convertible_to<const I2&, II2>
constexpr operator in_in_result<II1, II2>() const &
{
return {in1, in2};
}
template<class II1, class II2>
requires std::convertible_to<I1, II1> && std::convertible_to<I2, II2>
constexpr operator in_in_result<II1, II2>() &&
{
return {std::move(in1), std::move(in2)};
}
};
}
Each standard library algorithm that uses this family of return types declares a new alias type, e.g. using merge_result = in_in_out_result<I1, I2, O>;.
The names for such aliases are formed by adding the suffix “_result” to the algorithm’s name. So, the return type of std::ranges::merge can be named as std::ranges::merge_result.
Unlike std::pair and std::tuple, this class template has data members of meaningful names.
#include <algorithm>
#include <iostream>
#include <ranges>
int main()
{
constexpr static auto in1 = {1, 2, 3, 4};
constexpr static auto in2 = {1, 2, 4, 5};
constexpr auto result {std::ranges::mismatch(in1, in2)};
static_assert(2 == std::ranges::distance(in1.begin(), result.in1));
static_assert(2 == std::ranges::distance(in2.begin(), result.in2));
}
std::ranges::in_out_result (C++20)
template< class I, class O >
struct in_out_result;
ranges::in_out_result is a class template that provides a way to store two iterators as a single unit.
This class template has no base classes or declared members other than those shown below. Thus it is suitable for use with structured bindings.
All special member functions of this class template are implicitly declared, which makes specializations be aggregate classes, and propagate triviality, potentially-throwing-ness, and constexpr-ness of corresponding operations on data members.
-
Template parameters
- I, O : the types of the objects that the ranges::in_out_result stores.
-
Data members
| Member name |
Definition |
| in |
a value (that is supposed to be an iterator) of type I. |
| out |
a value (that is supposed to be an iterator) of type O. |
template<class I2, class O2>
requires std::convertible_to<const I&, I2> && std::convertible_to<const O&, O2>
constexpr operator in_out_result<I2, O2>() const &;
template<class I2, class O2>
requires std::convertible_to<I, I2> && std::convertible_to<O, O2>
constexpr operator in_out_result<I2, O2>() &&;
| Algorithm functions |
Definition |
| ranges::copy/ranges::copy_if (C++20) |
copies a range of elements to a new location |
| ranges::copy_n (C++20) |
copies a number of elements to a new location |
| ranges::copy_backward (C++20) |
copies a range of elements in backwards order |
| ranges::move (C++20) |
moves a range of elements to a new location |
| ranges::move_backward (C++20) |
moves a range of elements to a new location in backwards order |
| ranges::transform (C++20) |
applies a function to a range of elements |
| ranges::replace_copy/ranges::replace_copy_if (C++20) |
copies a range, replacing elements satisfying specific criteria with another value |
| ranges::remove_copy/ranges::remove_copy_if (C++20) |
copies a range of elements omitting those that satisfy specific criteria |
| ranges::unique_copy (C++20) |
creates a copy of some range of elements that contains no consecutive duplicates |
| ranges::reverse_copy (C++20) |
creates a copy of a range that is reversed |
| ranges::rotate_copy (C++20) |
copies and rotate a range of elements |
| ranges::partial_sort_copy (C++20) |
copies and partially sorts a range of elements |
| ranges::set_difference (C++20) |
computes the difference between two sets |
| ranges::uninitialized_copy (C++20) |
copies a range of objects to an uninitialized area of memory |
| ranges::uninitialized_copy_n (C++20) |
copies a number of objects to an uninitialized area of memory |
| ranges::uninitialized_move (C++20) |
moves a range of objects to an uninitialized area of memory |
| ranges::uninitialized_move_n (C++20) |
moves a number of objects to an uninitialized area of memory |
namespace std::ranges
{
template<class I, class O>
struct in_out_result
{
[[no_unique_address]] I in;
[[no_unique_address]] O out;
template<class I2, class O2>
requires std::convertible_to<const I&, I2> && std::convertible_to<const O&, O2>
constexpr operator in_out_result<I2, O2>() const &
{
return {in, out};
}
template<class I2, class O2>
requires std::convertible_to<I, I2> && std::convertible_to<O, O2>
constexpr operator in_out_result<I2, O2>() &&
{
return {std::move(in), std::move(out)};
}
};
}
#include <algorithm>
#include <array>
#include <cctype>
#include <iostream>
#include <ranges>
int main()
{
constexpr char in[] = "transform" "\n";
std::array<char, sizeof(in)> out;
const auto result = std::ranges::transform(in, out.begin(), [](char c) { return std::toupper(c); });
auto print = [](char c) { std::cout << c; };
std::ranges::for_each(std::cbegin(in), result.in, print);
std::ranges::for_each(out.cbegin(), result.out, print);
}
std::ranges::in_in_out_result
template< class I1, class I2, class O >
struct in_in_out_result;
ranges::in_in_out_result is a class template that provides a way to store three iterators as a single unit.
This class template has no base classes or declared members other than those shown below. Thus it is suitable for use with structured bindings.
All special member functions of this class template are implicitly declared, which makes specializations be aggregate classes, and propagate triviality, potentially-throwing-ness, and constexpr-ness of corresponding operations on data members.
-
Template parameters
- I1, I2, O: the types of the iterators that the ranges::in_in_out_result stores.
-
Data members
| Member name |
Definition |
| in1 |
a value (that supported to be an iterator) of type I1. |
| in2 |
a value (that supported to be an iterator) of type I2. |
| out |
a value (that supported to be an iterator) of type O. |
template<class II1, class II2, class OO>
requires std::convertible_to<const I1&, II1> &&
std::convertible_to<const I2&, II2> &&
std::convertible_to<const O&, OO>
constexpr operator in_in_out_result<II1, II2, OO>() const &;
template<class II1, class II2, class OO>
requires std::convertible_to<I1, II1> &&
std::convertible_to<I2, II2> &&
std::convertible_to<O, OO>
constexpr operator in_in_out_result<II1, II2, OO>() &&;
| Function name |
Definition |
| ranges::transform (C++20) |
applies a function to a range of elements |
| ranges::merge (C++20) |
merges two sorted ranges |
| ranges::set_union (C++20) |
computes the union of two sets |
| ranges::set_intersection (C++20) |
computes the intersection of two sets |
| ranges::set_symmetric_difference (C++20) |
computes the symmetric difference between two sets |
namespace std::ranges
{
template<class I1, class I2, class O>
struct in_in_out_result
{
[[no_unique_address]] I1 in1;
[[no_unique_address]] I2 in2;
[[no_unique_address]] O out;
template<class II1, class II2, class OO>
requires std::convertible_to<const I1&, II1> &&
std::convertible_to<const I2&, II2> &&
std::convertible_to<const O&, OO>
constexpr operator in_in_out_result<II1, II2, OO>() const &
{
return {in1, in2, out};
}
template<class II1, class II2, class OO>
requires std::convertible_to<I1, II1> &&
std::convertible_to<I2, II2> &&
std::convertible_to<O, OO>
constexpr operator in_in_out_result<II1, II2, OO>() &&
{
return {std::move(in1), std::move(in2), std::move(out)};
}
};
}
Each standard library algorithm that uses this family of return types declares a new alias type, e.g. using merge_result = in_in_out_result<I1, I2, O>;.
The names for such aliases are formed by adding the suffix “_result” to the algorithm’s name. So, the return type of std::ranges::merge can be named as std::ranges::merge_result.
Unlike std::pair and std::tuple, this class template has data members of meaningful names.
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <ranges>
void print(auto rem, auto first, auto last)
{
for (std:: cout << rem << ": "; first != last; ++first)
std::cout << *first << " ";
std::cout << "\n";
}
int main()
{
constexpr static auto in1 = {1, 2, 3, 4, 5, 5};
constexpr static auto in2 = {3, 4, 5, 6, 7};
std::array<int, std::size(in1) + std::size(in2) > our;
const auto result = std::ranges::merge(in1, in2, out.begin());
print("in1", in1.begin(), result.in1);
print("in2", in2.begin(), result.in2);
print("out", out.begin(), result.out);
}
all_of, any_of, none_of (C++11)
template< class InputIt, class UnaryPred >
bool all_of( InputIt first, InputIt last, UnaryPred p );
template< class ExecutionPolicy, class ForwardIt, class UnaryPred >
bool all_of( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, UnaryPred p );
template< class InputIt, class UnaryPred >
bool any_of( InputIt first, InputIt last, UnaryPred p );
template< class ExecutionPolicy, class ForwardIt, class UnaryPred >
bool any_of( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, UnaryPred p );
template< class InputIt, class UnaryPred >
bool none_of( InputIt first, InputIt last, UnaryPred p );
template< class ExecutionPolicy, class ForwardIt, class UnaryPred >
bool none_of( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, UnaryPred p );
-
Parameters
- first, last: the pair of iterators defining the range of elements to examine
- policy: the execution policy to use
- p: unary predicate.
The expression p(v) must be convertible to bool for every argument v of type (possibly const) VT, where VT is the value type of InputIt, regardless of value category, and must not modify v. Thus, a parameter type of VT&is not allowed, nor is VT unless for VT a move is equivalent to a copy(since C++11).
-
Type requirements
- InputIt must meet the requirements of LegacyInputIterator.
- ForwardIt must meet the requirements of LegacyForwardIterator.
- UnaryPred must meet the requirements of Predicate.
-
Complexity
- 1-6) At most std::distance(first, last) applications of the predicate p.
-
Exceptions
The overloads with a template parameter named ExecutionPolicy report errors as follows:
- If execution of a function invoked as part of the algorithm throws an exception and ExecutionPolicy is one of the standard policies, std::terminate is called. For any other ExecutionPolicy, the behavior is implementation-defined.
- If the algorithm fails to allocate memory, std::bad_alloc is thrown.
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
int main() {
std::vector<int> v(10, 2);
std::partial_sum(v.cbegin(), v.cend(), v.begin());
std::cout << "Amount the numbers: ";
std::copy(v.cbegin(), v.cend(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
if (std::all_of(v.cbegin(), v.cend(), [](int i) { return i % 2 == 0; }))
std::cout << "All numbers are even\n";
if (std::none_of(v.cbegin(), v.cend(),
std::bind(std::modulus<>(), std::placeholders::_1, 2)))
std::cout << "None of them are odd\n";
struct DivisibleBy {
const int d;
DivisibleBy(int n) : d(n) {}
bool operator()(int n) const { return n % d == 0; }
};
if (std::any_of(v.cbegin(), v.cend(), DivisibleBy(7)))
std::cout << "At least one number is divisible by 7\n";
}
std::for_each
template< class InputIt, class UnaryFunc >
UnaryFunc for_each( InputIt first, InputIt last, UnaryFunc f );
template< class ExecutionPolicy, class ForwardIt, class UnaryFunc >
void for_each( ExecutionPolicy&&, policy, ForwardIt first, ForwardIt last, UnaryFunc f);
Applies the given unary function object f to the result of dereferencing every iterator in the range [first, last). If f returns a result, the result is ignored.
-
f is applied in order starting from first.
If UnaryFunc is not MoveConstructible, the behavior is undefined. (since C++11)
-
f might not be applied in order. The algorithm is executed according to policy.
This overload participates in overload resolution only if all following conditions are satisfied:
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> is true. (until C++20)
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> is true. (since C++20)
If the iterator type (InputIt/ForwardIt) is mutable, f may modify the elements of the range through the dereferenced iterator.
Unlike the rest of the parallel algorithms, for_each is not allowed to make copies of the elements in the sequence even if they are TriviallyCopyable.
-
Parameters
- first, last: the pair of iterators defining the range of elements to which the function object will be applied
- policy: the execution policy to use
- f: function object, to be applied to the result of dereferencing every iterator in the range [first, last)
-
Type requirements
- InputIt must meet the requirements of LegacyInputIterator.
- ForwardIt must meet the requirements of LegacyForwardIterator.
-
Return value
-
Complexity
Exactly std::distance(first, last) applications of f.
-
Exceptions
The overload with a template parameter named ExecutionPolicy reports errors as follows:
- If execution of a function invoked as part of the algorithm throws an exception and ExecutionPolicy is one of the standard policies, std::terminate is called. For any other ExecutionPolicy, the behavior is implementation-defined.
- If the algorithm fails to allocate memory, std::bad_alloc is thrown.
-
Possible implementation
template<class InputIt, class UnaryFunc>
constexpr UnaryFunc for_each(InputIt first, InputIt last, UnaryFunc f)
{
for (; first != last; ++first)
f(*first);
return f;
}
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v{3, -4, 2, -8, 15, 267};
auto print = [](const int& n) { std::cout << n << ' '; };
std::cout << "before:\t";
std::for_each(v.cbegin(), v.cend(), print);
std::cout << "\n";
std::for_each(v.begin(), v.end(), [](int &n) {n++;});
std::cout << "after:\t";
std::for_each(v.cbegin(), v.cend(), print);
std::cout << "\n";
struct Sum
{
void operator()(int n) { sum += n; }
int sum {0};
};
Sum s = std::for_each(v.cbegin(), v.cend(), Sum());
std::cout << "sum:\t" << s.sum << "\n";
}
std::for_each_n (C++17)
template< class InputIt, class Size, class UnaryFunc >
InputIt for_each_n( InputIt first, Size n, UnaryFunc f );
template< class ExecutionPolicy, class ForwardIt,
class Size, class UnaryFunc >
ForwardIt for_each_n( ExecutionPolicy&& policy, ForwardIt first, Size n, UnaryFunc f );
Applies the given function object f to the result of dereferencing every iterator in the range [first, first + n). If f returns a result, the result is ignored.
f is applied in order starting from first.
-
f might not be applied in order. The algorithm is executed according to policy.
This overload participates in overload resolution only if all following conditions are satisfied:
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> is true. (Until C++20)
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> is true. (since C++20)
If UnaryFunc is not CopyConstructible, the behavior is undefined.
If n >= 0 is not true, the behavior is undefined.
If the iterator type (InputIt/ForwardIt) is mutable, f may modify the elements of the range through the dereferenced iterator.
Unlike the rest of the parallel algorithms, for_each_n is not allowed to make copies of the elements in the sequence even if they are TriviallyCopyable.
-
Parameters
- first: the beginning of the range to apply the function to
- n: the number of elements to apply the function to
- policy: the execution policy to use
- f: function object, to be applied to the result of dereferencing every iterator in the range [first, first + n)
The signature of the function should be equivalent to the following:
void fun(const Type &a);
The type Type must be such that an object of type InputIt can be dereferenced and them implicitly converted to Type.
-
Type requirements
- InputIt must meet the requirements of LegacyInputIterator.
- ForwardIt must meet the requirements of LegacyForwardIterator.
- Size must be convertible to an intergral type.
-
Return value
An iterator equal to first + n, or more formally, to std::advance(first, n).
Exactly n applications of f;
template<class InputIt, class Size, class UnaryFunc>
InputIt for_each_n(InputIt first, Size n, UnaryFunc f)
{
for (Size i = 0; i < n; ++first, (void) ++i)
f(*first);
return first;
}
#include <algorithm>
#include <iostream>
#include <vector>
void println(auto const &v) {
for (auto count{v.size()}; const auto &e : v)
std::cout << e << (--count ? ", " : "\n");
}
int main() {
std::vector<int> vi{1, 2, 3, 4, 5};
println(vi);
std::for_each_n(vi.begin(), 3, [](auto &n) { n *= 2; });
println(vi);
}