En C ++ 20, el <algorithm>encabezado gana dos nuevos algoritmos: shift_left()yshift_right() . Ambos aceptan cualquier LegacyForwardIterator. Para shift_left(), se especifica que "los movimientos se realizan en orden creciente a ipartir de 0"; para shift_right(), se especifica que "si ForwardItcumple con los requisitos de LegacyBidirectionalIterator, los movimientos se realizan en orden decreciente a ipartir de last - first - n - 1".
Puedo pensar en una forma razonablemente fácil de implementar shift_left():
template <typename ForwardIt>
constexpr inline ForwardIt shift_left(ForwardIt first, ForwardIt last, typename std::iterator_traits<ForwardIt>::difference_type n) {
if (n <= 0) return last;
ForwardIt it = first;
for (; n > 0; --n, ++it) {
if (it == last) return first;
}
return std::move(it, last, first);
}
Si ForwardItcumple con los requisitos de LegacyBidirectionalIterator, puedo ver que shift_right()se puede implementar de una manera muy similar a shift_left(). Sin embargo, no está claro en absoluto cómo se podría implementar shift_right()para iteradores directos no bidireccionales.
He descubierto un algoritmo que utiliza el espacio [first, first+n)como espacio de memoria virtual para el intercambio de elementos, pero parece un poco más derrochador que el algoritmo shift_left()anterior:
template <typename ForwardIt>
constexpr inline ForwardIt shift_right(ForwardIt first, ForwardIt last, typename std::iterator_traits<ForwardIt>::difference_type n) {
if (n <= 0) return first;
ForwardIt it = first;
for (; n > 0; --n, ++it) {
if (it == last) return last;
}
ForwardIt ret = it;
ForwardIt ret_it = first;
for (; it != last; ++it) {
std::iter_swap(ret_it, it);
ret_it++;
if (ret_it == ret) ret_it = first;
}
return ret;
}
¿Habría una forma mejor o "prevista" de implementación shift_right()?
fuente

std::movelugar destd::copy...Respuestas:
Esta es la implementación de muestra para turnos: https://github.com/danra/shift_proposal/blob/master/shift_proposal.h
Del documento de propuesta: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0769r0.pdf
fuente
void(++trail)...