tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
shift_right.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2022 Tobias Hienzsch
3
4#ifndef TETL_ALGORITHM_SHIFT_RIGHT_HPP
5#define TETL_ALGORITHM_SHIFT_RIGHT_HPP
6
7#include <etl/_algorithm/move.hpp>
8#include <etl/_concepts/emulation.hpp>
9#include <etl/_iterator/distance.hpp>
10#include <etl/_iterator/iterator_traits.hpp>
11#include <etl/_iterator/next.hpp>
12#include <etl/_iterator/prev.hpp>
13
14namespace etl {
15
16/// \brief Shifts the elements in the range [first, last) by n positions.
17///
18/// \details Shifts the elements towards the end of the range.
19/// If n <= 0 or n >= last - first, there are no effects. Otherwise, for
20/// every integer i in [0, last - first - n), moves the element originally
21/// at position first + i to position first + n + i.
22///
23/// https://en.cppreference.com/w/cpp/algorithm/shift
24///
25/// \note The standard specifies that this algorithm should also work with
26/// legacy forward iterators. I don't know how to implement that without
27/// dynamic memory, so forward iterators are not supported.
28///
29/// \ingroup algorithm
30template <typename BidiIt>
31constexpr auto shift_right(BidiIt first, BidiIt last, typename etl::iterator_traits<BidiIt>::difference_type n)
32 -> BidiIt
33{
34 // The standard only checks for n == 0. n < 0 would be undefined behavior.
35 // This implementation does nothing if n < 0.
36 if (n <= 0 or n >= etl::distance(first, last)) {
37 return last;
38 }
39
40 auto dest = etl::prev(last);
41 auto src = etl::prev(dest, n);
42 for (; src != first; --dest, (void)--src) {
43 *dest = etl::move(*src);
44 }
45
46 // Elements outside the new range should be left in a valid but unspecified state.
47 // If the value type has a default constructor we do a little cleanup.
48 using value_type = typename etl::iterator_traits<BidiIt>::value_type;
49 if constexpr (is_default_constructible_v<value_type>) {
50 for (; dest != first; --dest) {
51 *dest = value_type{};
52 }
53 }
54
55 return etl::next(first, n);
56}
57
58} // namespace etl
59
60#endif // TETL_ALGORITHM_SHIFT_RIGHT_HPP
constexpr auto shift_right(BidiIt first, BidiIt last, typename etl::iterator_traits< BidiIt >::difference_type n) -> BidiIt
Shifts the elements in the range [first, last) by n positions.
Definition shift_right.hpp:31
Definition adjacent_find.hpp:9
iterator_traits is the type trait class that provides uniform interface to the properties of LegacyIt...
Definition iterator_traits.hpp:48