Difference between revisions of "cpp/algorithm/ranges/reverse"
From cppreference.com
D41D8CD98F (Talk | contribs) m (→Return value: technically the result is `ranges::next(first, last)` ([algorithms.requirements]/13)) |
Andreas Krug (Talk | contribs) m (fmt) |
||
(5 intermediate revisions by 2 users not shown) | |||
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::bidirectional_iterator I, std::sentinel_for<I> S> | + | template< std::bidirectional_iterator I, std::sentinel_for<I> S > |
− | + | requires std::permutable<I> | |
− | + | constexpr I | |
− | + | reverse( I first, S last ); | |
}} | }} | ||
− | {{dcl | num=2 | since=c++20 |1= | + | {{dcl|num=2|since=c++20|1= |
− | template<ranges::bidirectional_range R> | + | template< ranges::bidirectional_range R > |
− | + | requires std::permutable<ranges::iterator_t<R>> | |
− | + | constexpr ranges::borrowed_iterator_t<R> | |
− | + | reverse( R&& r ); | |
}} | }} | ||
{{dcl end}} | {{dcl end}} | ||
− | @1@ Reverses the order of the elements in the range {{ | + | @1@ Reverses the order of the elements in the range {{range|first|last}}. |
− | @@ Behaves as if applying {{lc|ranges::iter_swap}} to every pair of iterators {{ | + | @@ Behaves as if applying {{lc|ranges::iter_swap}} to every pair of iterators {{c|first + i, last - i - 1}} for each integer {{tt|i}}, where {{c|1=0 ≤ i < (last - first) / 2}}. |
− | @2@ Same as {{v|1}}, but uses {{ | + | @2@ Same as {{v|1}}, but uses {{c|r}} as the range, as if using {{c|ranges::begin(r)}} as {{c|first}} and {{c|ranges::end(r)}} as {{c|last}}. |
{{cpp/ranges/niebloid}} | {{cpp/ranges/niebloid}} | ||
Line 27: | Line 27: | ||
===Parameters=== | ===Parameters=== | ||
{{par begin}} | {{par begin}} | ||
− | {{par | first, last | the range of elements to reverse}} | + | {{par|first, last|the range of elements to reverse}} |
− | {{par | r | the range of elements to reverse}} | + | {{par|r|the range of elements to reverse}} |
{{par end}} | {{par end}} | ||
===Return value=== | ===Return value=== | ||
− | An iterator equal to {{ | + | An iterator equal to {{c|last}}. |
===Complexity=== | ===Complexity=== | ||
− | Exactly {{ | + | Exactly {{c|(last - first) / 2}} swaps. |
− | + | ||
+ | ===Notes=== | ||
+ | {{cpp/algorithm/notes swap vectorization}} | ||
===Possible implementation=== | ===Possible implementation=== | ||
− | + | See also implementations in [https://github.com/gcc-mirror/gcc/blob/14d8a5ae472ca5743016f37da2dd4770d83dea21/libstdc%2B%2B-v3/include/bits/ranges_algo.h#L1278-L1325 libstdc++] and [https://github.com/microsoft/STL/blob/472161105d596192194d4715ccad307c6c163b4a/stl/inc/algorithm#L4154-L4180 MSVC STL]. | |
− | {{eq fun | 1= | + | {{eq fun|1= |
− | struct reverse_fn { | + | struct reverse_fn |
− | + | { | |
+ | template<std::bidirectional_iterator I, std::sentinel_for<I> S> | ||
requires std::permutable<I> | requires std::permutable<I> | ||
− | + | constexpr I operator()(I first, S last) const | |
− | + | { | |
− | + | auto last2 {ranges::next(first, last)}; | |
− | + | for (auto tail {last2}; !(first == tail or first == --tail); ++first) | |
− | + | ranges::iter_swap(first, tail); | |
− | + | return last2; | |
− | + | } | |
− | + | template<ranges::bidirectional_range R> | |
requires std::permutable<ranges::iterator_t<R>> | requires std::permutable<ranges::iterator_t<R>> | ||
− | + | constexpr ranges::borrowed_iterator_t<R> | |
− | operator()( R&& r ) const { | + | operator()(R&& r) const |
− | + | { | |
− | + | return (*this)(ranges::begin(r), ranges::end(r)); | |
+ | } | ||
}; | }; | ||
− | inline constexpr reverse_fn reverse{}; | + | inline constexpr reverse_fn reverse {}; |
}} | }} | ||
===Example=== | ===Example=== | ||
{{example | {{example | ||
− | + | |code= | |
#include <algorithm> | #include <algorithm> | ||
#include <array> | #include <array> | ||
Line 73: | Line 77: | ||
int main() | int main() | ||
{ | { | ||
− | std::string s{"ABCDEF"}; | + | std::string s {"ABCDEF"}; |
std::cout << s << " → "; | std::cout << s << " → "; | ||
std::ranges::reverse(s.begin(), s.end()); | std::ranges::reverse(s.begin(), s.end()); | ||
Line 80: | Line 84: | ||
std::cout << s << " │ "; | std::cout << s << " │ "; | ||
− | std::array a{1, 2, 3, 4, 5}; | + | std::array a {1, 2, 3, 4, 5}; |
− | for(auto e : a) | + | for (auto e : a) |
+ | std::cout << e << ' '; | ||
std::cout << "→ "; | std::cout << "→ "; | ||
std::ranges::reverse(a); | std::ranges::reverse(a); | ||
− | for(auto e : a) | + | for (auto e : a) |
+ | std::cout << e << ' '; | ||
std::cout << '\n'; | std::cout << '\n'; | ||
} | } | ||
− | + | |output= | |
ABCDEF → FEDCBA → ABCDEF │ 1 2 3 4 5 → 5 4 3 2 1 | ABCDEF → FEDCBA → ABCDEF │ 1 2 3 4 5 → 5 4 3 2 1 | ||
}} | }} | ||
Line 93: | Line 99: | ||
===See also=== | ===See also=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc inc | cpp/algorithm/ranges/dsc reverse_copy}} | + | {{dsc inc|cpp/algorithm/ranges/dsc reverse_copy}} |
− | {{dsc inc | cpp/algorithm/dsc reverse}} | + | {{dsc inc|cpp/ranges/dsc reverse_view}} |
+ | {{dsc inc|cpp/algorithm/dsc reverse}} | ||
{{dsc end}} | {{dsc end}} | ||
{{langlinks|de|es|fr|it|ja|pt|ru|zh}} | {{langlinks|de|es|fr|it|ja|pt|ru|zh}} |
Latest revision as of 04:02, 16 April 2023
Defined in header <algorithm>
|
||
Call signature |
||
template< std::bidirectional_iterator I, std::sentinel_for<I> S > requires std::permutable<I> |
(1) | (since C++20) |
template< ranges::bidirectional_range R > requires std::permutable<ranges::iterator_t<R>> |
(2) | (since C++20) |
1) Reverses the order of the elements in the range
[
first,
last)
. Behaves as if applying ranges::iter_swap to every pair of iterators first + i, last - i - 1 for each integer
i
, where 0 ≤ i < (last - first) / 2.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:
- 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.
Contents |
[edit] Parameters
first, last | - | the range of elements to reverse |
r | - | the range of elements to reverse |
[edit] Return value
An iterator equal to last.
[edit] Complexity
Exactly (last - first) / 2 swaps.
[edit] Notes
Implementations (e.g. MSVC STL) may enable vectorization when the iterator type models contiguous_iterator
and swapping its value type calls neither non-trivial special member function nor ADL-found swap
.
[edit] Possible implementation
See also implementations in libstdc++ and MSVC STL.
struct reverse_fn { template<std::bidirectional_iterator I, std::sentinel_for<I> S> requires std::permutable<I> constexpr I operator()(I first, S last) const { auto last2 {ranges::next(first, last)}; for (auto tail {last2}; !(first == tail or first == --tail); ++first) ranges::iter_swap(first, tail); return last2; } template<ranges::bidirectional_range R> requires std::permutable<ranges::iterator_t<R>> constexpr ranges::borrowed_iterator_t<R> operator()(R&& r) const { return (*this)(ranges::begin(r), ranges::end(r)); } }; inline constexpr reverse_fn reverse {}; |
[edit] Example
Run this code
#include <algorithm> #include <array> #include <iostream> #include <string> int main() { std::string s {"ABCDEF"}; std::cout << s << " → "; std::ranges::reverse(s.begin(), s.end()); std::cout << s << " → "; std::ranges::reverse(s); std::cout << s << " │ "; std::array a {1, 2, 3, 4, 5}; for (auto e : a) std::cout << e << ' '; std::cout << "→ "; std::ranges::reverse(a); for (auto e : a) std::cout << e << ' '; std::cout << '\n'; }
Output:
ABCDEF → FEDCBA → ABCDEF │ 1 2 3 4 5 → 5 4 3 2 1
[edit] See also
(C++20) |
creates a copy of a range that is reversed (niebloid) |
a view that iterates over the elements of another bidirectional view in reverse order(class template) (range adaptor object) | |
reverses the order of elements in a range (function template) |