1#ifndef NEFORCE_CORE_ALGORITHM_SHIFT_HPP__
2#define NEFORCE_CORE_ALGORITHM_SHIFT_HPP__
16NEFORCE_BEGIN_NAMESPACE__
44template <
typename Iterator1,
typename Iterator2>
46__copy_aux(Iterator1 first, Iterator1 last,
48 auto n = _NEFORCE
distance(first, last);
49 for (; n > 0; --n, ++first, ++result) {
66template <
typename Iterator1,
typename Iterator2>
68 Iterator2 result)
noexcept {
69 const auto n =
static_cast<size_t>(last - first);
90template <
typename Iterator1,
typename Iterator2>
91constexpr Iterator2
copy(Iterator1 first, Iterator1 last,
92 Iterator2 result)
noexcept(
noexcept(inner::__copy_aux(first, last, result))) {
94 "Iterators must be input_iterator");
98 return inner::__copy_aux(first, last, result);
113template <
typename Iterator1,
typename Iterator2>
116 Iterator1 last = first +
count;
129template <
typename Iterator1,
typename Iterator2>
132 for (;
count > 0; --
count, ++first, ++result) {
152template <
typename Iterator1,
typename Iterator2>
155 "Iterators must be input_iterator");
156 return inner::__copy_n_aux(first,
count, result);
172template <
typename Iterator1,
typename Iterator2,
typename Pred>
173constexpr Iterator2
copy_if(Iterator1 first, Iterator1 last, Iterator2 result, Pred pred) {
175 "Iterators must be input_iterator");
177 for (; first != last; ++first) {
199template <
typename Iterator1,
typename Iterator2>
201__copy_backward_aux(Iterator1 first, Iterator1 last,
221template <
typename Iterator1,
typename Iterator2>
223 Iterator2 result)
noexcept {
224 const auto n =
static_cast<size_t>(last - first);
244template <
typename Iterator1,
typename Iterator2>
247 Iterator2 result)
noexcept(
noexcept(inner::__copy_backward_aux(first, last, result))) {
249 "Iterators must be bidirectional_iterator");
254 return inner::__copy_backward_aux(first, last, result);
269template <
typename Iterator1,
typename Iterator2>
271__move_aux(Iterator1 first, Iterator1 last,
274 for (; n > 0; --n, ++first, ++result) {
275 *result = _NEFORCE
move(*first);
289template <
typename Iterator1,
typename Iterator2>
291 Iterator2 result)
noexcept {
292 const auto n =
static_cast<size_t>(last - first);
312template <
typename Iterator1,
typename Iterator2>
313constexpr Iterator2
move(Iterator1 first, Iterator1 last,
314 Iterator2 result)
noexcept(
noexcept(inner::__move_aux(first, last, result))) {
316 "Iterators must be input_iterator");
321 return inner::__move_aux(first, last, result);
336template <
typename Iterator1,
typename Iterator2>
339 for (
size_t n = _NEFORCE
distance(first, last); n > 0; --n) {
340 *--result = _NEFORCE
move(*--last);
354template <
typename Iterator1,
typename Iterator2>
356 Iterator2 result)
noexcept {
357 const auto n =
static_cast<size_t>(last - first);
376template <
typename Iterator1,
typename Iterator2>
377constexpr Iterator2
move_backward(Iterator1 first, Iterator1 last, Iterator2 result) {
379 "Iterators must be bidirectional_iterator");
383 return inner::__move_backward_aux(first, last, result);
397template <
typename Iterator,
typename T>
398constexpr void fill(Iterator first, Iterator last,
401 static_assert(
is_assignable_v<
decltype(*first), T>,
"Iterators must be assignable from T");
403 for (; first != last; ++first) {
417template <
typename Iterator,
typename T>
421 static_assert(
is_assignable_v<
decltype(*first), T>,
"Iterators must be assignable from T");
423 for (; n > 0; --n, ++first) {
439template <
typename Iterator1,
typename Iterator2>
440constexpr void iter_swap(Iterator1 a, Iterator2 b)
noexcept(
noexcept(_NEFORCE
swap(*a, *b))) {
442 "Iterators must be input_iterator");
443 _NEFORCE
swap(*a, *b);
457template <
typename Iterator1,
typename Iterator2>
458constexpr Iterator2
swap_ranges(Iterator1 first1, Iterator1 last1, Iterator2 first2) {
459 for (; first1 != last1; ++first1, ++first2) {
477template <
typename Iterator,
typename Function>
478constexpr Function
for_each(Iterator first, Iterator last, Function f) {
480 static_assert(
is_invocable_v<Function,
decltype(*first)>,
"Function must be invocable");
482 for (; first != last; ++first) {
497template <
typename Iterator,
typename Function>
500 static_assert(
is_invocable_v<Function,
decltype(*first)>,
"Function must be invocable");
502 for (
size_t i = 0; i < n; i++) {
520template <
typename Iterator,
typename Generator>
521constexpr void generate(Iterator first, Iterator last, Generator gen) {
525 "Generator must be assignable from invoke_result");
527 for (; first != last; ++first) {
541template <
typename Iterator,
typename Generator>
546 "Generator must be assignable from invoke_result");
548 for (; n > 0; --n, ++first) {
569template <
typename Iterator1,
typename Iterator2,
typename T>
570constexpr Iterator2
replace_copy(Iterator1 first, Iterator1 last, Iterator2 result,
const T& old_value,
571 const T& new_value) {
573 "Iterators must be forward_iterator");
574 static_assert(
is_assignable_v<
decltype(*result),
const T&>,
"*result must be assignable from const T");
576 for (; first != last; ++first, ++result) {
577 *result = *first == old_value ? new_value : *first;
597template <
typename Iterator1,
typename Iterator2,
typename Predicate,
typename T>
598constexpr Iterator2
replace_copy_if(Iterator1 first, Iterator1 last, Iterator2 result, Predicate pred,
599 const T& new_value) {
601 "Iterators must be forward_iterator");
602 static_assert(
is_invocable_v<Predicate,
decltype(*first)>,
"Predicate must be invocable");
603 static_assert(
is_assignable_v<
decltype(*result),
const T&>,
"*result must be assignable from const T");
605 for (; first != last; ++first, ++result) {
606 *result = pred(*first) ? new_value : *first;
622template <
typename Iterator,
typename T>
623constexpr void replace(Iterator first, Iterator last,
const T& old_value,
const T& new_value) {
625 static_assert(
is_assignable_v<
decltype(*first),
const T&>,
"*result must be assignable from const T");
627 for (; first != last; ++first) {
628 if (*first == old_value) {
646template <
typename Iterator,
typename Predicate,
typename T>
647constexpr void replace_if(Iterator first, Iterator last, Predicate pred,
const T& new_value) {
649 static_assert(
is_invocable_v<Predicate,
decltype(*first)>,
"Predicate must be invocable");
650 static_assert(
is_assignable_v<
decltype(*first),
const T&>,
"*result must be assignable from const T");
652 for (; first != last; ++first) {
659#ifndef NEFORCE_STANDARD_17
669template <
typename Iterator>
671 while (first < last) {
685template <
typename Iterator>
688 if (first == last || first == --last) {
710template <
typename Iterator>
711constexpr void reverse(Iterator first, Iterator last) {
714#ifdef NEFORCE_STANDARD_17
716 while (first < last) {
723 if (first == last || first == --last) {
732 inner::__reverse_aux(first, last);
739template <
typename Iterator>
742 for (Iterator i = middle;;) {
746 if (first == middle) {
751 }
else if (i == last) {
757template <
typename Iterator>
760 _NEFORCE
reverse(first, middle);
761 _NEFORCE
reverse(middle, last);
772template <
typename Iterator>
774 if (first == middle || middle == last) {
777 inner::__rotate_aux_dispatch(first, middle, last);
788template <
typename Iterator>
791 Iterator ptr1 = initial;
792 Iterator ptr2 = ptr1 + shift;
793 while (ptr2 != initial) {
796 if (last - ptr2 > shift) {
799 ptr2 = first + (shift - (last - ptr2));
802 *ptr1 = _NEFORCE
move(value);
814template <
typename Iterator>
816 auto n = _NEFORCE
gcd(last - first, middle - first);
818 inner::__rotate_cycle_aux(first, last, first + n, middle - first);
836template <
typename Iterator>
837constexpr void rotate(Iterator first, Iterator middle, Iterator last) {
840 if (first == middle || middle == last) {
843 inner::__rotate_aux(first, middle, last);
858template <
typename Iterator1,
typename Iterator2>
859constexpr Iterator2
rotate_copy(Iterator1 first, Iterator1 middle, Iterator1 last, Iterator2 result) {
860 return _NEFORCE
copy(first, middle, _NEFORCE
copy(middle, last, result));
874template <
typename Iterator>
878 "*first must be assignable");
880 if (first == last || n == 0) {
883 if (n >= _NEFORCE
distance(first, last)) {
884 for (; first != last; ++first) {
889 Iterator new_first = _NEFORCE
next(first, n);
890 _NEFORCE
copy(new_first, last, first);
891 Iterator
end = _NEFORCE
prev(last, -n);
892 for (;
end != last; ++
end) {
908template <
typename Iterator>
912 "*first must be assignable");
914 if (first == last || n == 0) {
917 if (n >= _NEFORCE
distance(first, last)) {
918 for (; first != last; ++first) {
923 auto new_last = _NEFORCE
prev(last, -n);
925 auto end = _NEFORCE
next(first, n);
926 for (; first !=
end; ++first) {
945template <
typename Iterator1,
typename Iterator2,
typename UnaryOperation>
946constexpr Iterator2
transform(Iterator1 first, Iterator1 last, Iterator2 result,
947 UnaryOperation op)
noexcept(
noexcept(++first) &&
noexcept(++result) &&
948 noexcept(*result = op(*first))) {
950 "Iterators must be forward_iterator");
951 static_assert(
is_invocable_v<UnaryOperation,
decltype(*first)>,
"UnaryOperation must be invocable");
953 "*result must be assignable");
955 for (; first != last; ++first, ++result) {
956 *result = op(*first);
977template <
typename Iterator1,
typename Iterator2,
typename Iterator3,
typename BinaryOperation>
978constexpr Iterator3
transform(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator3 result,
979 BinaryOperation binary_op)
noexcept(
noexcept(++first1) &&
noexcept(first2) &&
980 noexcept(++result) &&
981 noexcept(*result = binary_op(*first1, *first2))) {
983 "Iterators must be forward_iterator");
984 static_assert(
is_invocable_v<BinaryOperation,
decltype(*first1),
decltype(*first2)>,
985 "UnaryOperation must be invocable");
988 "*result must be assignable");
990 for (; first1 != last1; ++first1, ++first2, ++result) {
991 *result = binary_op(*first1, *first2);
1011template <
typename Iterator1,
typename Iterator2,
typename BinaryPredicate>
1012constexpr Iterator2
unique_copy(Iterator1 first, Iterator1 last, Iterator2 result, BinaryPredicate binary_pred) {
1014 "Iterators must be forward_iterator");
1015 static_assert(
is_invocable_v<BinaryPredicate,
decltype(*result),
decltype(*first)>,
1016 "BinaryPredicate must be invocable");
1018 if (first == last) {
1024 while (++first != last) {
1025 if (!binary_pred(*result, *first)) {
1041template <
typename Iterator1,
typename Iterator2>
1042constexpr Iterator2
unique_copy(Iterator1 first, Iterator1 last, Iterator2 result) {
1055template <
typename Iterator>
1056constexpr Iterator
unique(Iterator first, Iterator last) {
1072template <
typename Iterator,
typename BinaryPredicate>
1073constexpr Iterator
unique(Iterator first, Iterator last, BinaryPredicate binary_pred) {
1075 return _NEFORCE
unique_copy(first, last, first, binary_pred);
1082NEFORCE_END_NAMESPACE__
typename add_reference< T >::rvalue add_rvalue_reference_t
add_rvalue_reference的便捷别名
constexpr Iterator adjacent_find(Iterator first, Iterator last, BinaryPredicate binary_pred)
查找第一对满足条件的相邻元素
NEFORCE_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
NEFORCE_INLINE17 constexpr bool is_invocable_v
is_invocable的便捷变量模板
typename inner::__invoke_result_aux< F, Args... >::type invoke_result_t
invoke_result的便捷别名
NEFORCE_INLINE17 constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
NEFORCE_INLINE17 constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
NEFORCE_INLINE17 constexpr bool is_ranges_bid_iter_v
检查是否为范围双向迭代器
NEFORCE_INLINE17 constexpr bool is_ranges_rnd_iter_v
检查是否为范围随机访问迭代器
constexpr Iterator prev(Iterator iter, iter_difference_t< Iterator > n=-1)
获取迭代器的前一个位置
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
typename iterator_traits< Iterator >::value_type iter_value_t
获取迭代器的值类型
typename iterator_traits< Iterator >::difference_type iter_difference_t
获取迭代器的差值类型
NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 T gcd(const T &m, const T &n) noexcept
计算最大公约数
NEFORCE_CONSTEXPR14 void * memory_move(void *dest, const void *src, size_t count) noexcept
从源内存移动数据到目标内存
constexpr Iterator2 transform(Iterator1 first, Iterator1 last, Iterator2 result, UnaryOperation op) noexcept(noexcept(++first) &&noexcept(++result) &&noexcept(*result=op(*first)))
对范围元素应用一元变换
constexpr Iterator unique(Iterator first, Iterator last)
移除连续重复元素
constexpr Iterator2 unique_copy(Iterator1 first, Iterator1 last, Iterator2 result, BinaryPredicate binary_pred)
复制唯一元素
constexpr void replace(Iterator first, Iterator last, const T &old_value, const T &new_value)
替换范围元素
constexpr void fill(Iterator first, Iterator last, const T &value) noexcept(is_nothrow_assignable_v< iter_value_t< Iterator >, T >)
填充范围元素
constexpr Iterator for_each_n(Iterator first, iter_difference_t< Iterator > n, Function f)
对指定数量的元素应用函数
constexpr Iterator2 copy_backward(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_backward_aux(first, last, result)))
反向复制范围元素
constexpr Function for_each(Iterator first, Iterator last, Function f)
对范围元素应用函数
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_aux(first, last, result)))
复制范围元素
constexpr Iterator2 copy_if(Iterator1 first, Iterator1 last, Iterator2 result, Pred pred)
复制满足谓词的元素
constexpr void shift_right(Iterator first, Iterator last, iter_difference_t< Iterator > n)
向右移位
constexpr Iterator generate_n(Iterator first, iter_difference_t< Iterator > n, Generator gen)
用生成器的值填充指定数量的元素
constexpr pair< Iterator1, Iterator2 > copy_n(Iterator1 first, iter_difference_t< Iterator1 > count, Iterator2 result)
复制指定数量的元素
constexpr Iterator2 move_backward(Iterator1 first, Iterator1 last, Iterator2 result)
反向移动范围元素
constexpr void replace_if(Iterator first, Iterator last, Predicate pred, const T &new_value)
根据谓词替换范围元素
constexpr void shift_left(Iterator first, Iterator last, iter_difference_t< Iterator > n)
向左移位
constexpr void reverse(Iterator first, Iterator last)
反转范围元素顺序
constexpr void generate(Iterator first, Iterator last, Generator gen)
用生成器的值填充范围
constexpr Iterator2 rotate_copy(Iterator1 first, Iterator1 middle, Iterator1 last, Iterator2 result)
旋转并复制元素
constexpr Iterator2 swap_ranges(Iterator1 first1, Iterator1 last1, Iterator2 first2)
交换两个范围的元素
constexpr Iterator2 replace_copy(Iterator1 first, Iterator1 last, Iterator2 result, const T &old_value, const T &new_value)
替换并复制元素
constexpr void iter_swap(Iterator1 a, Iterator2 b) noexcept(noexcept(_NEFORCE swap(*a, *b)))
交换迭代器指向的元素
constexpr void rotate(Iterator first, Iterator middle, Iterator last)
旋转范围元素
constexpr Iterator fill_n(Iterator first, iter_difference_t< Iterator > n, const T &value) noexcept(is_nothrow_assignable_v< iter_value_t< Iterator >, T >)
填充指定数量的元素
constexpr Iterator2 replace_copy_if(Iterator1 first, Iterator1 last, Iterator2 result, Predicate pred, const T &new_value)
根据谓词替换并复制元素
void swap()=delete
删除无参数的swap重载
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
NEFORCE_ALWAYS_INLINE constexpr T initialize() noexcept(is_nothrow_default_constructible< T >::value)
返回类型T的默认初始化值
NEFORCE_INLINE17 constexpr bool is_nothrow_assignable_v
is_nothrow_assignable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_copy_assignable_v
is_nothrow_copy_assignable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_move_assignable_v
is_nothrow_move_assignable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_assignable_v
is_assignable的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名