Skip to main content

std::ranges::reverse_copy() algorithm

// (1)
constexpr reverse_copy_result<I, O>
reverse_copy( I first, S last, O result );

// (2)
constexpr reverse_copy_result<ranges::borrowed_iterator_t<R>, O>
reverse_copy( R&& r, O result );

The type of arguments are generic and have following constraints:

  • I - std::bidirectional_iterator
  • S - std::sentinel_for<I>
  • R - ranges::bidirectional_range
  • O - std::weakly_incrementable

Additionally, each overload has the following constraints:

  • (1) - std::indirectly_copyable<I, O>
  • (2) - std::indirectly_copyable<ranges::iterator_t<R>, O>

With the helper types defined as follows:

template< class I, class O >
using reverse_copy_result = ranges::in_out_result<I, O>;
  • (1) Given N as ranges::distance(first, last):

    Copies the elements from the source range [first; last) to the destination range [result; result + N), in such a way that the elements in the new range are in reverse order.

    Behaves as if by executing the assignment *(result + N - 1 - i) = *(first + i) once for each integer i in [0; N).

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

Undefined Behaviour

The behavior is undefined

if the source and destination ranges overlap.

The function-like entities described on this page are niebloids.

Parameters

first
last

The range of elements to copy.

r

The range of elements to copy.

result

The beginning of the destination range.

Return value

A value of type ranges::reverse_copy_result initialized as follows:

{
last,
result + N
}

Where N is ranges::distance(first, last).

Complexity

Exactly ranges::distance(first, last) assignments.

Exceptions

(none)

Possible implementation

reverse_copy(1)
struct reverse_copy_fn
{
template<std::bidirectional_iterator I, std::sentinel_for<I> S,
std::weakly_incrementable O>
requires std::indirectly_copyable<I, O>
constexpr ranges::reverse_copy_result<I, O>
operator()(I first, S last, O result) const
{
auto ret = ranges::next(first, last);
for (; last != first; *result = *--last, ++result);
return {std::move(ret), std::move(result)};
}

template<ranges::bidirectional_range R, std::weakly_incrementable O>
requires std::indirectly_copyable<ranges::iterator_t<R>, O>
constexpr ranges::reverse_copy_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(result));
}
};

inline constexpr reverse_copy_fn reverse_copy {};

Notes

Implementations (e.g. MSVC STL) may enable vectorization when the both iterator types satisfy LegacyContiguousIterator and have the same value type, and the value type is TriviallyCopyable.

Examples

Main.cpp
#include <algorithm>
#include <iostream>
#include <string>

int main()
{
std::string x {"12345"}, y(x.size(), ' ');
std::cout << x << " → ";
std::ranges::reverse_copy(x.begin(), x.end(), y.begin());
std::cout << y << " → ";
std::ranges::reverse_copy(y, x.begin());
std::cout << x << '\n';
}
Output
12345 → 54321 → 12345
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::reverse_copy() algorithm

// (1)
constexpr reverse_copy_result<I, O>
reverse_copy( I first, S last, O result );

// (2)
constexpr reverse_copy_result<ranges::borrowed_iterator_t<R>, O>
reverse_copy( R&& r, O result );

The type of arguments are generic and have following constraints:

  • I - std::bidirectional_iterator
  • S - std::sentinel_for<I>
  • R - ranges::bidirectional_range
  • O - std::weakly_incrementable

Additionally, each overload has the following constraints:

  • (1) - std::indirectly_copyable<I, O>
  • (2) - std::indirectly_copyable<ranges::iterator_t<R>, O>

With the helper types defined as follows:

template< class I, class O >
using reverse_copy_result = ranges::in_out_result<I, O>;
  • (1) Given N as ranges::distance(first, last):

    Copies the elements from the source range [first; last) to the destination range [result; result + N), in such a way that the elements in the new range are in reverse order.

    Behaves as if by executing the assignment *(result + N - 1 - i) = *(first + i) once for each integer i in [0; N).

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

Undefined Behaviour

The behavior is undefined

if the source and destination ranges overlap.

The function-like entities described on this page are niebloids.

Parameters

first
last

The range of elements to copy.

r

The range of elements to copy.

result

The beginning of the destination range.

Return value

A value of type ranges::reverse_copy_result initialized as follows:

{
last,
result + N
}

Where N is ranges::distance(first, last).

Complexity

Exactly ranges::distance(first, last) assignments.

Exceptions

(none)

Possible implementation

reverse_copy(1)
struct reverse_copy_fn
{
template<std::bidirectional_iterator I, std::sentinel_for<I> S,
std::weakly_incrementable O>
requires std::indirectly_copyable<I, O>
constexpr ranges::reverse_copy_result<I, O>
operator()(I first, S last, O result) const
{
auto ret = ranges::next(first, last);
for (; last != first; *result = *--last, ++result);
return {std::move(ret), std::move(result)};
}

template<ranges::bidirectional_range R, std::weakly_incrementable O>
requires std::indirectly_copyable<ranges::iterator_t<R>, O>
constexpr ranges::reverse_copy_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(result));
}
};

inline constexpr reverse_copy_fn reverse_copy {};

Notes

Implementations (e.g. MSVC STL) may enable vectorization when the both iterator types satisfy LegacyContiguousIterator and have the same value type, and the value type is TriviallyCopyable.

Examples

Main.cpp
#include <algorithm>
#include <iostream>
#include <string>

int main()
{
std::string x {"12345"}, y(x.size(), ' ');
std::cout << x << " → ";
std::ranges::reverse_copy(x.begin(), x.end(), y.begin());
std::cout << y << " → ";
std::ranges::reverse_copy(y, x.begin());
std::cout << x << '\n';
}
Output
12345 → 54321 → 12345
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.