std::reverse_copy(3)
π std::reverse_copy(3) β C++ Standard Library, bestie edition β¨
okay so real talk, this is a page from the C++ Standard Library manual, section 3, and it's about std::reverse_copy. yes the name is literally the whole vibe: it copies stuff backwards. icon behavior honestly π
β¨ NAME β¨
std::reverse_copy β literally std::reverse_copy. that's it, that's the name, no notes π
πΈ SYNOPSIS πΈ
so it lives in the header <algorithm> (go say hi to it):
template< class BidirIt, class OutputIt >
OutputIt reverse_copy( BidirIt first, BidirIt last, (1)
(constexpr since C++20)
OutputIt d_first );
template< class ExecutionPolicy, class BidirIt, class
ForwardIt >
ForwardIt reverse_copy( ExecutionPolicy&& policy, (2) (since
C++17)
BidirIt first, BidirIt last,
ForwardIt d_first );
two flavors, both iconic, pick your fighter π
π¦ DESCRIPTION π¦
1) so first things first, let N be std::distance(first, last) β that's your count, bestie. it copies the elements from the range [first, last) (the source range) into another range of N elements starting at d_first (the destination range), and the way it does it means the destination ends up in reverse order. π₯
it behaves as if it ran the assignment *(d_first + N - 1 - i) = *(first + i) ^[1] once for every integer i in [0, N).
β οΈ if the source and destination ranges overlap, the behavior is undefined. not "kinda weird", not "probably fine" β undefined. do not do it. π
2) same as (1), but it runs according to policy. this overload only joins overload resolution if:
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)
π PARAMETERS π
first,lastβ the range of elements to copy. the source squad.d_firstβ the beginning of the destination range. where the backwards magic lands.
π§ TYPE REQUIREMENTS π§
BidirItmust meet the requirements of LegacyBidirectionalIterator.OutputItmust meet the requirements of LegacyOutputIterator.ForwardItmust meet the requirements of LegacyForwardIterator.
(no random-access shortcuts, no made-up iterator vibes, it's giving very specific π )
β RETURN VALUE β
an output iterator pointing to the element past the last element copied. classic past-the-end energy, we love to see it.
π COMPLEXITY π
exactly N assignments. no more, no less. it ate and left no crumbs.
π₯ EXCEPTIONS π₯
the overload with a template parameter named ExecutionPolicy reports errors like this:
- if execution of a function invoked as part of the algorithm throws an exception and
ExecutionPolicyis one of the standard policies,std::terminateis called. yeah. that's the dramatic part. π - for any other
ExecutionPolicy, the behavior is implementation-defined. - if the algorithm fails to allocate memory,
std::bad_allocis thrown.
π POSSIBLE IMPLEMENTATION π
also peep the implementations in libstdc++, libc++, and MSVC STL if you're nosy (affectionate).
template<class BidirIt, class OutputIt>
constexpr // since C++20
OutputIt reverse_copy(BidirIt first, BidirIt last, OutputIt d_first)
{
for (; first != last; ++d_first)
*d_first = *(--last);
return d_first;
}
like. look at it. decrementing last first, assigning, incrementing d_first. reverse copy in four lines. main character energy fr fr π«Ά
πΈ NOTES πΈ
implementations (e.g. MSVC STL) may enable vectorization when both iterator types satisfy LegacyContiguousIterator and have the same value type, and the value type is TriviallyCopyable. so that's the secret speedrun condition, iykyk.
π EXAMPLE π
// Run this code
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
auto print = [](const std::vector<int>& v)
{
for (const auto& value : v)
std::cout << value << ' ';
std::cout << '\n';
};
std::vector<int> v{1, 2, 3};
print(v);
std::vector<int> destination(3);
std::reverse_copy(std::begin(v), std::end(v),
std::begin(destination));
print(destination);
std::reverse_copy(std::rbegin(v), std::rend(v),
std::begin(destination));
print(destination);
}
β¨ Output β¨
1 2 3
3 2 1
1 2 3
first line: the original. second: reversed (forward iterators, reverse output). third: reversed again via rbegin/rend, so it flips back to normal. that third line is the plot twist and I'm obsessed π
π DEFECT REPORTS π
these are behavior-changing defect reports that got applied retroactively to previously published C++ standards. glow-ups, basically:
LWG 2074β applied to C++98. as published: for eachi, the assignment was*(d_first + N - i) = *(first + i)^[1]. corrected to:*(d_first + N - 1 - i) = *(first + i)^[1]. (they fixed the off-by-one, slay)LWG 2150β applied to C++98. as published: only one element was required to be assigned. corrected: the requirement. (vague before, now it's the requirement, periodt)
^1. ^1.0 ^1.1 ^1.2LegacyOutputIteratoris not required to support binary+and-. the usages of+and-here are exposition-only: the actual computation does not need to use them. so don't @ me about operators, they're just how we explain the math π§
π¦ SEE ALSO π¦
reverseβ reverses the order of elements in a range (function template)ranges::reverse_copy(C++20) β creates a copy of a range that is reversed (niebloid)
and that's the page!! π β¨ this gem came to you courtesy of cppreference.com, dated 2024.06.10 β go drink some water, then go reverse-copy something (but not into an overlapping range, bestie, I'm begging ππ).
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms