std::ranges...ward_result(3)
π std::ranges::move_backward, std::ranges::move_backward_result π
okay so bestie, we're in the C++ Standard Libary manual, page std::ranges...ward_result(3) β¨ and this is the whole glow-up on std::ranges::move_backward plus its helper std::ranges::move_backward_result π.
β¨ NAME β¨
std::ranges::move_backward,std::ranges::move_backward_result β literally the page for std::ranges::move_backward and std::ranges::move_backward_result, no cap. π
πΈ Synopsis πΈ
Defined in header <algorithm>
Call signature
template< std::bidirectional_iterator I1, std::sentinel_for<I1> S1,
std::bidirectional_iterator I2 >
(since
requires std::indirectly_movable<I1, I2>
(1) C++20)
constexpr move_backward_result<I1, I2>
move_backward( I1 first, S1 last, I2 result );
template< ranges::bidirectional_range R, std::bidirectional_iterator
I >
requires std::indirectly_movable<ranges::iterator_t<R>, I>
(2) (since
constexpr move_backward_result<ranges::borrowed_iterator_t<R>, I>
C++20)
move_backward( R&& r, I result );
π Helper types π
template< class I, class O >
(3) (since
using move_backward_result = ranges::in_out_result<I, O>;
C++20)
so like, (1) is the iterator-pair version, (2) is the range version, and (3) is the helper alias move_backward_result β all of them are living that since C++20 life π
.
- Moves the elements in the range, defined by
[first, last), to another range[result - N, result), whereN = ranges::distance(first, last). The elements are moved in reverse order (the last element is moved first), but their relative order is preserved. The behavior is undefined ifresultis within(first, last]. In such a case,ranges::movemay be used instead.
β οΈ real talk: the behavior is undefined ifresultis within(first, last]. In such a case,ranges::movemay be used instead. do not play with UB bestie π
- Same as (1), but uses
ras the source range, as if usingranges::begin(r)asfirst, andranges::end(r)aslast.
The elements in the moved-from range will still contain valid values of the appropriate type, but not necessarily the same values as before the move, as if using *(result - n) = ranges::iter_move(last - n) for each integer n, where 0 β€ n < N.
The function-like entities described on this page are niebloids, that is:
- Explicit template argument lists cannot be specified when calling any of them.
- None of them are visible to argument-dependent lookup.
- When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.
In practice, they may be implemented as function objects, or with special compiler extensions.
π«Ά Parameters π«Ά
firstβ the beginning of the range of elements to move.lastβ the end of the range of elements to move.rβ the range of the elements to move.resultβ the end of the destination range.
π Return value π
{last, result - N}. that's the whole return vibe π
.
π₯ Complexity π₯
- Exactly
Nmove assignments. - Exactly
ranges::distance(r)move assignments.
π¦ Notes π¦
When moving overlapping ranges, ranges::move is appropriate when moving to the left (beginning of the destination range is outside the source range) while ranges::move_backward is appropriate when moving to the right (end of the destination range is outside the source range).
π Possible implementation π
struct move_backward_fn
{
template<std::bidirectional_iterator I1, std::sentinel_for<I1>
S1,
std::bidirectional_iterator I2>
requires std::indirectly_movable<I1, I2>
constexpr ranges::move_backward_result<I1, I2>
operator()(I1 first, S1 last, I2 result) const
{
auto i {last};
for (; i != first; *--result = ranges::iter_move(--i))
{}
return {std::move(last), std::move(result)};
}
template<ranges::bidirectional_range R,
std::bidirectional_iterator I>
requires std::indirectly_movable<ranges::iterator_t<R>, I>
constexpr
ranges::move_backward_result<ranges::borrowed_iterator_t<R>, I>
operator()(R&& r, I result) const
{
return (*this)(ranges::begin(r), ranges::end(r),
std::move(result));
}
};
inline constexpr move_backward_fn move_backward {};
π Example π
// Run this code
#include <algorithm>
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
using Vec = std::vector<std::string>;
void print(std::string_view rem, Vec const& vec)
{
std::cout << rem << "[" << vec.size() << "]: ";
for (const std::string& s : vec)
std::cout << (s.size() ? s : std::string{"Β·"}) << ' ';
std::cout << '\n';
}
int main()
{
Vec a{"β", "β", "β", "β", "β
", "β", "β", "β"};
Vec b(a.size());
print("Before move:\n" "a", a);
print("b", b);
std::ranges::move_backward(a, b.end());
print("\n" "Move a >> b:\n" "a", a);
print("b", b);
std::ranges::move_backward(b.begin(), b.end(), a.end());
print("\n" "Move b >> a:\n" "a", a);
print("b", b);
std::ranges::move_backward(a.begin(), a.begin()+3, a.end());
print("\n" "Overlapping move a[0, 3) >> a[5, 8):\n" "a", a);
}
β Possible output β
Before move:
a[8]: β β β β β
β β β
b[8]: Β· Β· Β· Β· Β· Β· Β· Β·
Move a >> b:
a[8]: Β· Β· Β· Β· Β· Β· Β· Β·
b[8]: β β β β β
β β β
Move b >> a:
a[8]: β β β β β
β β β
b[8]: Β· Β· Β· Β· Β· Β· Β· Β·
Overlapping move a[0, 3) >> a[5, 8):
a[8]: Β· Β· Β· β β
β β β
π See also π
ranges::moveβ moves a range of elements to a new location (C++20) (niebloid)ranges::copy,ranges::copy_ifβ copies a range of elements to a new location (C++20) (niebloid) (C++20)ranges::copy_backwardβ copies a range of elements in backwards order (C++20) (niebloid)moveβ moves a range of elements to a new location (C++11) (function template)moveβ obtains an rvalue reference (C++11) (function template)
sending u a kiss π β source http://cppreference.com, version/date 2024.06.10, page std::ranges...ward_result(3). byeee bestie πβ¨
π¦ 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