1#ifndef MSTL_CORE_ALGORITHM_SHIFT_HPP__
2#define MSTL_CORE_ALGORITHM_SHIFT_HPP__
37template <
typename Iterator1,
typename Iterator2, enable_if_t<!is_ranges_cot_iter_v<Iterator1>,
int> = 0>
38constexpr Iterator2 __copy_aux(Iterator1 first, Iterator1 last, Iterator2 result) {
40 for (; n > 0; --n, ++first, ++result) {
57template <
typename Iterator1,
typename Iterator2, enable_if_t<is_ranges_cot_iter_v<Iterator1>,
int> = 0>
58constexpr Iterator2 __copy_aux(Iterator1 first, Iterator1 last, Iterator2 result) {
59 const auto n =
static_cast<size_t>(last - first);
80template <
typename Iterator1,
typename Iterator2,
enable_if_t<
82constexpr Iterator2
copy(Iterator1 first, Iterator1 last, Iterator2 result) {
83 if (first == last)
return result;
84 return _INNER __copy_aux(first, last, result);
99template <
typename Iterator1,
typename Iterator2, enable_if_t<is_ranges_rnd_iter_v<Iterator1>,
int> = 0>
101 Iterator1 last = first +
count;
114template <
typename Iterator1,
typename Iterator2, enable_if_t<!is_ranges_rnd_iter_v<Iterator1>,
int> = 0>
135template <
typename Iterator1,
typename Iterator2,
enable_if_t<
154template <
typename Iterator1,
typename Iterator2,
typename UnaryPredicate>
155constexpr Iterator2
copy_if(Iterator1 first, Iterator1 last, Iterator2 result, UnaryPredicate unary_pred) {
156 for (; first != last; ++first) {
157 if (unary_pred(*first))
177template <
typename Iterator1,
typename Iterator2, enable_if_t<!is_ranges_cot_iter_v<Iterator1>,
int> = 0>
178constexpr Iterator2 __copy_backward_aux(Iterator1 first, Iterator1 last, Iterator2 result) {
196template <
typename Iterator1,
typename Iterator2, enable_if_t<is_ranges_cot_iter_v<Iterator1>,
int> = 0>
197constexpr Iterator2 __copy_backward_aux(Iterator1 first, Iterator1 last, Iterator2 result) {
198 const auto n =
static_cast<size_t>(last - first);
217template <
typename Iterator1,
typename Iterator2,
enable_if_t<
219constexpr Iterator2
copy_backward(Iterator1 first, Iterator1 last, Iterator2 result) {
220 if (first == last)
return result;
221 return _INNER __copy_backward_aux(first, last, result);
236template <
typename Iterator1,
typename Iterator2, enable_if_t<!is_ranges_cot_iter_v<Iterator1>,
int> = 0>
237constexpr Iterator2 __move_aux(Iterator1 first, Iterator1 last, Iterator2 result) {
239 for (; n > 0; --n, ++first, ++result)
253template <
typename Iterator1,
typename Iterator2, enable_if_t<is_ranges_cot_iter_v<Iterator1>,
int> = 0>
254constexpr Iterator2 __move_aux(Iterator1 first, Iterator1 last, Iterator2 result) {
255 const auto n =
static_cast<size_t>(last - first);
274template <
typename Iterator1,
typename Iterator2,
enable_if_t<
276constexpr Iterator2
move(Iterator1 first, Iterator1 last, Iterator2 result) {
277 if (first == last)
return result;
278 return _INNER __move_aux(first, last, result);
293template <
typename Iterator1,
typename Iterator2, enable_if_t<!is_ranges_cot_iter_v<Iterator1>,
int> = 0>
294constexpr Iterator2 __move_backward_aux(Iterator1 first, Iterator1 last, Iterator2 result) {
309template <
typename Iterator1,
typename Iterator2, enable_if_t<is_ranges_cot_iter_v<Iterator1>,
int> = 0>
310constexpr Iterator2 __move_backward_aux(Iterator1 first, Iterator1 last, Iterator2 result) {
311 const auto n =
static_cast<size_t>(last - first);
330template <
typename Iterator1,
typename Iterator2,
enable_if_t<
332constexpr Iterator2
move_backward(Iterator1 first, Iterator1 last, Iterator2 result) {
333 if (first == last)
return result;
334 return _INNER __move_backward_aux(first, last, result);
348template <
typename Iterator,
typename T, enable_if_t<is_ranges_input_iter_v<Iterator>,
int> = 0>
349constexpr void fill(Iterator first, Iterator last,
const T& value) {
350 for (; first != last; ++first) {
364template <
typename Iterator,
typename T, enable_if_t<is_ranges_input_iter_v<Iterator>,
int> = 0>
365constexpr Iterator
fill_n(Iterator first,
size_t n,
const T& value) {
366 for (; n > 0; --n, ++first) *first = value;
380template <
typename Iterator1,
typename Iterator2,
enable_if_t<
398template <
typename Iterator1,
typename Iterator2,
400constexpr Iterator2
swap_ranges(Iterator1 first1, Iterator1 last1, Iterator2 first2) {
401 for (; first1 != last1; ++first1, ++first2) {
419template <
typename Iterator,
typename Function, enable_if_t<is_ranges_input_iter_v<Iterator>,
int> = 0>
420constexpr Function
for_each(Iterator first, Iterator last, Function f) {
421 for (; first != last; ++first) f(*first);
434template <
typename Iterator,
typename Function, enable_if_t<is_ranges_input_iter_v<Iterator>,
int> = 0>
435constexpr Iterator
for_each_n(Iterator first,
const size_t n, Function f) {
436 for (
size_t i = 0; i < n; i++) {
454template <
typename Iterator,
typename Generator, enable_if_t<is_ranges_input_iter_v<Iterator>,
int> = 0>
455constexpr void generate(Iterator first, Iterator last, Generator gen) {
456 for (; first != last; ++first) {
470template <
typename Iterator,
typename Generator, enable_if_t<is_ranges_input_iter_v<Iterator>,
int> = 0>
471constexpr Iterator
generate_n(Iterator first,
size_t n, Generator gen) {
472 for (; n > 0; --n, ++first) {
493template <
typename Iterator1,
typename Iterator2,
typename T,
495constexpr Iterator2
replace_copy(Iterator1 first, Iterator1 last, Iterator2 result,
496 const T& old_value,
const T& new_value) {
497 for (; first != last; ++first, ++result) {
498 *result = *first == old_value ? new_value : *first;
518template <
typename Iterator1,
typename Iterator2,
typename Predicate,
typename T,
521 Predicate pred,
const T& new_value) {
522 for (; first != last; ++first, ++result) {
523 *result = pred(*first) ? new_value : *first;
539template <
typename Iterator,
typename T, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
540constexpr void replace(Iterator first, Iterator last,
const T& old_value,
const T& new_value) {
541 for (; first != last; ++first) {
542 if (*first == old_value) {
560template <
typename Iterator,
typename Predicate,
typename T, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
561constexpr void replace_if(Iterator first, Iterator last, Predicate pred,
const T& new_value) {
562 for (; first != last; ++first) {
563 if (pred(*first)) *first = new_value;
567#ifndef MSTL_STANDARD_17__
577template <
typename Iterator, enable_if_t<is_ranges_rnd_iter_v<Iterator>,
int> = 0>
578void __reverse_aux(Iterator first, Iterator last) {
579 while (first < last) {
592template <
typename Iterator, enable_if_t<!is_ranges_rnd_iter_v<Iterator>,
int> = 0>
593void __reverse_aux(Iterator first, Iterator last) {
595 if (first == last || first == --last)
return;
614template <
typename Iterator, enable_if_t<is_ranges_b
id_iter_v<Iterator>,
int> = 0>
615constexpr void reverse(Iterator first, Iterator last) {
616#ifdef MSTL_STANDARD_17__
618 while (first < last) {
626 if (first == last || first == --last)
return;
633 _INNER __reverse_aux(first, last);
639#ifndef MSTL_STANDARD_17__
640template <
typename Iterator, enable_if_t<!is_ranges_b
id_iter_v<Iterator>,
int> = 0>
641void __rotate_aux_dispatch(Iterator first, Iterator middle, Iterator last) {
642 for (Iterator i = middle; ;) {
646 if (first == middle) {
647 if (i == last)
return;
654template <
typename Iterator, enable_if_t<is_ranges_b
id_iter_v<Iterator>,
int> = 0>
655void __rotate_aux_dispatch(Iterator first, Iterator middle, Iterator last) {
669template <
typename Iterator, enable_if_t<!is_ranges_rnd_iter_v<Iterator>,
int> = 0>
670constexpr void __rotate_aux(Iterator first, Iterator middle, Iterator last) {
671 if (first == middle || middle == last)
return;
672#ifdef MSTL_STANDARD_17__
679 for (Iterator i = middle; ;) {
683 if (first == middle) {
684 if (i == last)
return;
686 }
else if (i == last) {
692 _INNER __rotate_aux_dispatch(first, middle, last);
705template <
typename Iterator,
typename Distance>
706constexpr void __rotate_cycle_aux(Iterator first, Iterator last, Iterator initial, Distance shift) {
708 Iterator ptr1 = initial;
709 Iterator ptr2 = ptr1 + shift;
710 while (ptr2 != initial) {
713 if (last - ptr2 > shift) {
716 ptr2 = first + (shift - (last - ptr2));
731template <
typename Iterator, enable_if_t<is_ranges_rnd_iter_v<Iterator>,
int> = 0>
732constexpr void __rotate_aux(Iterator first, Iterator middle, Iterator last) {
735 _INNER __rotate_cycle_aux(first, last, first + n, middle - first);
752template <
typename Iterator, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
753constexpr void rotate(Iterator first, Iterator middle, Iterator last) {
754 if (first == middle || middle == last)
return;
755 _INNER __rotate_aux(first, middle, last);
770template <
typename Iterator1,
typename Iterator2,
772constexpr Iterator2
rotate_copy(Iterator1 first, Iterator1 middle, Iterator1 last, Iterator2 result) {
787template <
typename Iterator,
789constexpr void shift_left(Iterator first, Iterator last,
size_t n) {
790 if (first == last || n == 0)
return;
792 for (; first != last; ++first) {
797 Iterator new_first =
_MSTL next(first, n);
800 for (;
end != last; ++
end) {
816template <
typename Iterator,
818constexpr void shift_right(Iterator first, Iterator last,
size_t n) {
819 if (first == last || n == 0)
return;
821 for (; first != last; ++first) {
829 for (; first !=
end; ++first) {
848template <
typename Iterator1,
typename Iterator2,
typename UnaryOperation,
850constexpr Iterator2
transform(Iterator1 first, Iterator1 last, Iterator2 result, UnaryOperation op)
851noexcept(
noexcept(++first) &&
noexcept(++result) &&
noexcept(*result = op(*first))) {
852 for (; first != last; ++first, ++result) {
853 *result = op(*first);
874template <
typename Iterator1,
typename Iterator2,
typename Iterator3,
typename BinaryOperation,
877 Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator3 result, BinaryOperation binary_op
879 noexcept(++first1) &&
noexcept(first2) &&
880 noexcept(++result) &&
noexcept(*result = binary_op(*first1, *first2))
882 for (; first1 != last1; ++first1, ++first2, ++result) {
883 *result = binary_op(*first1, *first2);
903template <
typename Iterator1,
typename Iterator2,
typename BinaryPredicate,
906 Iterator2 result, BinaryPredicate binary_pred) {
907 if (first == last)
return result;
909 while (++first != last) {
910 if (!binary_pred(*result, *first)) *++result = *first;
924template <
typename Iterator1,
typename Iterator2>
925constexpr Iterator2
unique_copy(Iterator1 first, Iterator1 last, Iterator2 result) {
938template <
typename Iterator, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
939constexpr Iterator
unique(Iterator first, Iterator last) {
955template <
typename Iterator,
typename BinaryPredicate, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
956constexpr Iterator
unique(Iterator first, Iterator last, BinaryPredicate binary_pred) {
constexpr Iterator adjacent_find(Iterator first, Iterator last, BinaryPredicate binary_pred)
查找第一对满足条件的相邻元素
MSTL_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
MSTL_INLINE17 constexpr bool is_iter_v
检查类型是否为迭代器
MSTL_INLINE17 constexpr bool is_ranges_rnd_iter_v
检查是否为范围随机访问迭代器
MSTL_INLINE17 constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
MSTL_INLINE17 constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
MSTL_INLINE17 constexpr bool is_ranges_bid_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
获取迭代器的差值类型
MSTL_CONST_FUNCTION MSTL_CONSTEXPR14 T gcd(const T &m, const T &n) noexcept
计算最大公约数
MSTL_CONSTEXPR14 void * memory_move(void *dest, const void *src, size_t count) noexcept
从源内存移动数据到目标内存
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
constexpr void iter_swap(Iterator1 a, Iterator2 b) noexcept(noexcept(_MSTL swap(*a, *b)))
交换迭代器指向的元素
constexpr Iterator for_each_n(Iterator first, const size_t n, Function f)
对指定数量的元素应用函数
constexpr Iterator2 copy_backward(Iterator1 first, Iterator1 last, Iterator2 result)
反向复制范围元素
constexpr void shift_left(Iterator first, Iterator last, size_t n)
向左移位
constexpr Iterator2 rotate_copy(Iterator1 first, Iterator1 middle, Iterator1 last, Iterator2 result)
旋转并复制元素
constexpr Iterator unique(Iterator first, Iterator last)
移除连续重复元素
constexpr void replace(Iterator first, Iterator last, const T &old_value, const T &new_value)
替换范围元素
constexpr Iterator2 replace_copy(Iterator1 first, Iterator1 last, Iterator2 result, const T &old_value, const T &new_value)
替换并复制元素
constexpr void reverse(Iterator first, Iterator last)
反转范围元素顺序
constexpr void fill(Iterator first, Iterator last, const T &value)
填充范围元素
constexpr Iterator2 replace_copy_if(Iterator1 first, Iterator1 last, Iterator2 result, Predicate pred, const T &new_value)
根据谓词替换并复制元素
constexpr void shift_right(Iterator first, Iterator last, size_t n)
向右移位
constexpr Iterator generate_n(Iterator first, size_t n, Generator gen)
用生成器的值填充指定数量的元素
constexpr Iterator2 move_backward(Iterator1 first, Iterator1 last, Iterator2 result)
反向移动范围元素
constexpr Iterator2 unique_copy(Iterator1 first, Iterator1 last, Iterator2 result, BinaryPredicate binary_pred)
复制唯一元素
constexpr void generate(Iterator first, Iterator last, Generator gen)
用生成器的值填充范围
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
constexpr void rotate(Iterator first, Iterator middle, Iterator last)
旋转范围元素
constexpr Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制范围元素
constexpr Iterator2 swap_ranges(Iterator1 first1, Iterator1 last1, Iterator2 first2)
交换两个范围的元素
constexpr Iterator2 copy_if(Iterator1 first, Iterator1 last, Iterator2 result, UnaryPredicate unary_pred)
复制满足谓词的元素
constexpr Function for_each(Iterator first, Iterator last, Function f)
对范围元素应用函数
constexpr void replace_if(Iterator first, Iterator last, Predicate pred, const T &new_value)
根据谓词替换范围元素
constexpr Iterator2 transform(Iterator1 first, Iterator1 last, Iterator2 result, UnaryOperation op) noexcept(noexcept(++first) &&noexcept(++result) &&noexcept(*result=op(*first)))
对范围元素应用一元变换
constexpr pair< Iterator1, Iterator2 > copy_n(Iterator1 first, size_t count, Iterator2 result)
复制指定数量的元素
constexpr Iterator fill_n(Iterator first, size_t n, const T &value)
填充指定数量的元素
void swap()=delete
删除无参数的swap重载
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
constexpr T initialize() noexcept(is_nothrow_default_constructible< T >::value)
返回类型T的默认初始化值
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名