1#ifndef NEFORCE_CORE_ALGORITHM_SHIFT_HPP__
2#define NEFORCE_CORE_ALGORITHM_SHIFT_HPP__
15NEFORCE_BEGIN_NAMESPACE__
43template <
typename Iterator1,
typename Iterator2>
45__copy_aux(Iterator1 first, Iterator1 last,
47 auto n = _NEFORCE
distance(first, last);
48 for (; n > 0; --n, ++first, ++result) {
65template <
typename Iterator1,
typename Iterator2>
67__copy_aux(Iterator1 first, Iterator1 last, Iterator2 result)
noexcept {
68 const auto n =
static_cast<size_t>(last - first);
71 return _NEFORCE
next(result, n);
89template <
typename Iterator1,
typename Iterator2>
90constexpr Iterator2
copy(Iterator1 first, Iterator1 last,
91 Iterator2 result)
noexcept(
noexcept(inner::__copy_aux(first, last, result))) {
97 return inner::__copy_aux(first, last, result);
112template <
typename Iterator1,
typename Iterator2>
115 return _NEFORCE
copy(first, _NEFORCE
next(first,
count), result);
127template <
typename Iterator1,
typename Iterator2>
130 for (;
count > 0; --
count, ++first, ++result) {
150template <
typename Iterator1,
typename Iterator2>
154 return inner::__copy_n_aux(first,
count, result);
170template <
typename Iterator1,
typename Iterator2,
typename Pred>
171constexpr Iterator2
copy_if(Iterator1 first, Iterator1 last, Iterator2 result, Pred pred) {
175 for (; first != last; ++first) {
197template <
typename Iterator1,
typename Iterator2>
199__copy_backward_aux(Iterator1 first, Iterator1 last,
219template <
typename Iterator1,
typename Iterator2>
221 Iterator2 result)
noexcept {
222 const auto n =
static_cast<size_t>(last - first);
223 auto dest = _NEFORCE
prev(result, n);
243template <
typename Iterator1,
typename Iterator2>
246 Iterator2 result)
noexcept(
noexcept(inner::__copy_backward_aux(first, last, result))) {
248 "Iterators must be bidirectional_iterator");
253 return inner::__copy_backward_aux(first, last, result);
268template <
typename Iterator1,
typename Iterator2>
270__move_aux(Iterator1 first, Iterator1 last,
273 for (; n > 0; --n, ++first, ++result) {
274 *result = _NEFORCE
move(*first);
288template <
typename Iterator1,
typename Iterator2>
290__move_aux(Iterator1 first, Iterator1 last, Iterator2 result)
noexcept {
291 const auto n =
static_cast<size_t>(last - first);
311template <
typename Iterator1,
typename Iterator2>
312constexpr Iterator2
move(Iterator1 first, Iterator1 last,
313 Iterator2 result)
noexcept(
noexcept(inner::__move_aux(first, last, result))) {
315 "Iterators must be input_iterator");
320 return inner::__move_aux(first, last, result);
335template <
typename Iterator1,
typename Iterator2>
337__move_backward_aux(Iterator1 first, Iterator1 last, Iterator2 result) {
338 for (
size_t n = _NEFORCE
distance(first, last); n > 0; --n) {
339 *--result = _NEFORCE
move(*--last);
353template <
typename Iterator1,
typename Iterator2>
355__move_backward_aux(Iterator1 first, Iterator1 last, Iterator2 result)
noexcept {
356 const auto n =
static_cast<size_t>(last - first);
357 auto dest = result - n;
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");
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) {
722 while (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);
837template <
typename Iterator>
838constexpr Iterator
rotate(Iterator first, Iterator middle, Iterator last) {
841 if (first == middle) {
844 if (middle == last) {
848 auto dist = _NEFORCE
distance(middle, last);
849 inner::__rotate_aux(first, middle, last);
850 return _NEFORCE
next(first, dist);
865template <
typename Iterator1,
typename Iterator2>
866constexpr Iterator2
rotate_copy(Iterator1 first, Iterator1 middle, Iterator1 last, Iterator2 result) {
867 return _NEFORCE
copy(first, middle, _NEFORCE
copy(middle, last, result));
883template <
typename Iterator>
891 auto dist = _NEFORCE
distance(first, last);
892 if (
static_cast<decltype(dist)
>(n) >= dist) {
896 Iterator new_last = _NEFORCE
next(first, dist - n);
897 _NEFORCE
move(_NEFORCE
next(first, n), last, first);
914template <
typename Iterator>
922 auto dist = _NEFORCE
distance(first, last);
923 if (
static_cast<decltype(dist)
>(n) >= dist) {
927 Iterator new_first = _NEFORCE
next(first, n);
946template <
typename Iterator1,
typename Iterator2,
typename UnaryOperation>
947constexpr Iterator2
transform(Iterator1 first, Iterator1 last, Iterator2 result,
948 UnaryOperation op)
noexcept(
noexcept(++first) &&
noexcept(++result) &&
949 noexcept(*result = op(*first))) {
951 "Iterators must be forward_iterator");
952 static_assert(
is_invocable_v<UnaryOperation,
decltype(*first)>,
"UnaryOperation must be invocable");
954 "*result must be assignable");
956 for (; first != last; ++first, ++result) {
957 *result = op(*first);
978template <
typename Iterator1,
typename Iterator2,
typename Iterator3,
typename BinaryOperation>
979constexpr Iterator3
transform(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator3 result,
980 BinaryOperation binary_op)
noexcept(
noexcept(++first1) &&
noexcept(first2) &&
981 noexcept(++result) &&
982 noexcept(*result = binary_op(*first1, *first2))) {
984 "Iterators must be forward_iterator");
985 static_assert(
is_invocable_v<BinaryOperation,
decltype(*first1),
decltype(*first2)>,
986 "UnaryOperation must be invocable");
989 "*result must be assignable");
991 for (; first1 != last1; ++first1, ++first2, ++result) {
992 *result = binary_op(*first1, *first2);
1012template <
typename Iterator1,
typename Iterator2,
typename BinaryPredicate>
1013constexpr Iterator2
unique_copy(Iterator1 first, Iterator1 last, Iterator2 result, BinaryPredicate binary_pred) {
1015 "Iterators must be forward_iterator");
1016 static_assert(
is_invocable_v<BinaryPredicate,
decltype(*result),
decltype(*first)>,
1017 "BinaryPredicate must be invocable");
1019 if (first == last) {
1025 while (++first != last) {
1026 if (!binary_pred(*result, *first)) {
1042template <
typename Iterator1,
typename Iterator2>
1043constexpr Iterator2
unique_copy(Iterator1 first, Iterator1 last, Iterator2 result) {
1058template <
typename Iterator,
typename BinaryPredicate>
1059constexpr Iterator
unique(Iterator first, Iterator last, BinaryPredicate binary_pred) {
1061 if (first == last) {
1065 Iterator result = first;
1066 while (++first != last) {
1067 if (!binary_pred(*result, *first)) {
1068 *++result = _NEFORCE
move(*first);
1083template <
typename Iterator>
1084constexpr Iterator
unique(Iterator first, Iterator last) {
1092NEFORCE_END_NAMESPACE__
constexpr Iterator adjacent_find(Iterator first, Iterator last, BinaryPredicate binary_pred)
查找第一对满足条件的相邻元素
constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
constexpr bool is_invocable_v
is_invocable的便捷变量模板
typename inner::__invoke_result_aux< F, Args... >::type invoke_result_t
invoke_result的便捷别名
constexpr bool is_ranges_cot_iter_v
检查是否为范围连续迭代器
constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
constexpr bool is_ranges_rnd_iter_v
检查是否为范围随机访问迭代器
constexpr bool is_iter_v
检查类型是否为迭代器
constexpr bool is_ranges_bid_iter_v
检查是否为范围双向迭代器
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
constexpr Iterator prev(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的前一个位置
typename iterator_traits< Iterator >::value_type iter_value_t
获取迭代器的值类型
typename iterator_traits< Iterator >::difference_type iter_difference_t
获取迭代器的差值类型
constexpr T gcd(const T &m, const T &n) noexcept
计算最大公约数
constexpr 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 shift_right(Iterator first, Iterator last, iter_difference_t< Iterator > n)
向右移位
constexpr Iterator2 copy_n(Iterator1 first, iter_difference_t< Iterator1 > count, Iterator2 result)
复制指定数量的元素
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 Iterator rotate(Iterator first, Iterator middle, Iterator last)
旋转范围元素
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 Iterator generate_n(Iterator first, iter_difference_t< Iterator > n, Generator gen)
用生成器的值填充指定数量的元素
constexpr Iterator2 move_backward(Iterator1 first, Iterator1 last, Iterator2 result)
反向移动范围元素
constexpr Iterator unique(Iterator first, Iterator last, BinaryPredicate binary_pred)
根据谓词移除连续重复元素
constexpr void replace_if(Iterator first, Iterator last, Predicate pred, const T &new_value)
根据谓词替换范围元素
constexpr Iterator 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 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重载
constexpr bool is_nothrow_copy_assignable_v
is_nothrow_copy_assignable的便捷变量模板
constexpr bool is_assignable_v
is_assignable的便捷变量模板
constexpr bool is_nothrow_assignable_v
is_nothrow_assignable的便捷变量模板
constexpr bool is_nothrow_move_assignable_v
is_nothrow_move_assignable的便捷变量模板
constexpr bool is_trivially_copyable_v
is_trivially_copyable的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名