MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
shift.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_ALGORITHM_SHIFT_HPP__
2#define MSTL_CORE_ALGORITHM_SHIFT_HPP__
3
11
16
22
25
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) {
41 *result = *first;
42 }
43 return result;
44}
45
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);
60 const auto bytes = n * sizeof(iter_value_t<Iterator1>);
61 _MSTL memory_move(_MSTL addressof(*result), _MSTL addressof(*first), bytes);
62 return result + n;
63}
64
67
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);
85}
86
89
99template <typename Iterator1, typename Iterator2, enable_if_t<is_ranges_rnd_iter_v<Iterator1>, int> = 0>
100constexpr pair<Iterator1, Iterator2> __copy_n_aux(Iterator1 first, size_t count, Iterator2 result) {
101 Iterator1 last = first + count;
102 return pair<Iterator1, Iterator2>(last, _MSTL copy(first, last, result));
103}
104
114template <typename Iterator1, typename Iterator2, enable_if_t<!is_ranges_rnd_iter_v<Iterator1>, int> = 0>
115constexpr pair<Iterator1, Iterator2> __copy_n_aux(Iterator1 first, size_t count, Iterator2 result) {
116 for (; count > 0; --count, ++first, ++result)
117 *result = *first;
118 return pair<Iterator1, Iterator2>(first, result);
119}
122
135template <typename Iterator1, typename Iterator2, enable_if_t<
137constexpr pair<Iterator1, Iterator2> copy_n(Iterator1 first, size_t count, Iterator2 result) {
138 return _INNER __copy_n_aux(first, count, result);
139}
140
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))
158 *result++ = *first;
159 }
160 return result;
161}
162
165
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) {
180 for (; n > 0; --n)
181 *--result = *--last;
182 return result;
183}
184
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);
200 return result;
201}
204
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);
222}
223
226
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)
240 *result = _MSTL move(*first);
241 return result;
242}
243
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);
257 return result + n;
258}
261
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);
279}
280
283
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) {
295 for (size_t n = _MSTL distance(first, last); n > 0; --n)
296 *--result = _MSTL move(*--last);
297 return result;
298}
299
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);
313 return result;
314}
317
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);
335}
336
337
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) {
351 *first = value;
352 }
353}
354
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;
367 return first;
368}
369
370
380template <typename Iterator1, typename Iterator2, enable_if_t<
382constexpr void iter_swap(Iterator1 a, Iterator2 b)
383noexcept(noexcept(_MSTL swap(*a, *b))) {
384 _MSTL swap(*a, *b);
385}
386
398template <typename Iterator1, typename Iterator2,
400constexpr Iterator2 swap_ranges(Iterator1 first1, Iterator1 last1, Iterator2 first2) {
401 for (; first1 != last1; ++first1, ++first2) {
402 _MSTL iter_swap(first1, first2);
403 }
404 return first2;
405}
406
407
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);
422 return f;
423}
424
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++) {
437 f(*first);
438 ++first;
439 }
440 return first;
441}
442
443
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) {
457 *first = gen();
458 }
459}
460
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) {
473 *first = gen();
474 }
475 return first;
476}
477
478
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;
499 }
500 return result;
501}
502
518template <typename Iterator1, typename Iterator2, typename Predicate, typename T,
520constexpr Iterator2 replace_copy_if(Iterator1 first, Iterator1 last, Iterator2 result,
521 Predicate pred, const T& new_value) {
522 for (; first != last; ++first, ++result) {
523 *result = pred(*first) ? new_value : *first;
524 }
525 return result;
526}
527
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) {
543 *first = new_value;
544 }
545 }
546}
547
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;
564 }
565}
566
567#ifndef MSTL_STANDARD_17__
570
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) {
580 --last;
581 _MSTL iter_swap(first, last);
582 ++first;
583 }
584}
585
592template <typename Iterator, enable_if_t<!is_ranges_rnd_iter_v<Iterator>, int> = 0>
593void __reverse_aux(Iterator first, Iterator last) {
594 while (true) {
595 if (first == last || first == --last) return;
596 --last;
597 _MSTL iter_swap(first, last);
598 ++first;
599 }
600}
601
604#endif // MSTL_STANDARD_17__
605
614template <typename Iterator, enable_if_t<is_ranges_bid_iter_v<Iterator>, int> = 0>
615constexpr void reverse(Iterator first, Iterator last) {
616#ifdef MSTL_STANDARD_17__
617 if constexpr (is_ranges_rnd_iter_v<Iterator>) {
618 while (first < last) {
619 --last;
620 _MSTL iter_swap(first, last);
621 ++first;
622 }
623 }
624 else {
625 while (true) {
626 if (first == last || first == --last) return;
627 --last;
628 _MSTL iter_swap(first, last);
629 ++first;
630 }
631 }
632#else
633 _INNER __reverse_aux(first, last);
634#endif
635}
636
639#ifndef MSTL_STANDARD_17__
640template <typename Iterator, enable_if_t<!is_ranges_bid_iter_v<Iterator>, int> = 0>
641void __rotate_aux_dispatch(Iterator first, Iterator middle, Iterator last) {
642 for (Iterator i = middle; ;) {
643 _MSTL iter_swap(first, i);
644 ++first;
645 ++i;
646 if (first == middle) {
647 if (i == last) return;
648 middle = i;
649 }
650 else if (i == last)
651 i = middle;
652 }
653}
654template <typename Iterator, enable_if_t<is_ranges_bid_iter_v<Iterator>, int> = 0>
655void __rotate_aux_dispatch(Iterator first, Iterator middle, Iterator last) {
656 _MSTL reverse(first, middle);
657 _MSTL reverse(middle, last);
658 _MSTL reverse(first, last);
659}
660#endif // MSTL_STANDARD_17__
661
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__
673 if constexpr (is_ranges_bid_iter_v<Iterator>) {
674 _MSTL reverse(first, middle);
675 _MSTL reverse(middle, last);
676 _MSTL reverse(first, last);
677 }
678 else {
679 for (Iterator i = middle; ;) {
680 _MSTL iter_swap(first, i);
681 ++first;
682 ++i;
683 if (first == middle) {
684 if (i == last) return;
685 middle = i;
686 } else if (i == last) {
687 i = middle;
688 }
689 }
690 }
691#else
692 _INNER __rotate_aux_dispatch(first, middle, last);
693#endif
694}
695
705template <typename Iterator, typename Distance>
706constexpr void __rotate_cycle_aux(Iterator first, Iterator last, Iterator initial, Distance shift) {
707 iter_value_t<Iterator> value = *initial;
708 Iterator ptr1 = initial;
709 Iterator ptr2 = ptr1 + shift;
710 while (ptr2 != initial) {
711 *ptr1 = *ptr2;
712 ptr1 = ptr2;
713 if (last - ptr2 > shift) {
714 ptr2 += shift;
715 } else {
716 ptr2 = first + (shift - (last - ptr2));
717 }
718 }
719 *ptr1 = value;
720}
721
731template <typename Iterator, enable_if_t<is_ranges_rnd_iter_v<Iterator>, int> = 0>
732constexpr void __rotate_aux(Iterator first, Iterator middle, Iterator last) {
733 iter_difference_t<Iterator> n = _MSTL gcd(last - first, middle - first);
734 while (n--) {
735 _INNER __rotate_cycle_aux(first, last, first + n, middle - first);
736 }
737}
738
741
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);
756}
757
770template <typename Iterator1, typename Iterator2,
772constexpr Iterator2 rotate_copy(Iterator1 first, Iterator1 middle, Iterator1 last, Iterator2 result) {
773 return _MSTL copy(first, middle, _MSTL copy(middle, last, result));
774}
775
776
787template <typename Iterator,
788 enable_if_t<is_ranges_fwd_iter_v<Iterator> && is_default_constructible_v<iter_value_t<Iterator>>, int> = 0>
789constexpr void shift_left(Iterator first, Iterator last, size_t n) {
790 if (first == last || n == 0) return;
791 if (n >= _MSTL distance(first, last)) {
792 for (; first != last; ++first) {
794 }
795 return;
796 }
797 Iterator new_first = _MSTL next(first, n);
798 _MSTL copy(new_first, last, first);
799 Iterator end = _MSTL prev(last, -n);
800 for (; end != last; ++end) {
802 }
803}
804
805
816template <typename Iterator,
817 enable_if_t<is_ranges_bid_iter_v<Iterator> && is_default_constructible_v<iter_value_t<Iterator>>, int> = 0>
818constexpr void shift_right(Iterator first, Iterator last, size_t n) {
819 if (first == last || n == 0) return;
820 if (n >= _MSTL distance(first, last)) {
821 for (; first != last; ++first) {
823 }
824 return;
825 }
826 auto new_last = _MSTL prev(last, -n);
827 _MSTL move_backward(first, new_last, last);
828 auto end = _MSTL next(first, n);
829 for (; first != end; ++first) {
831 }
832}
833
834
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);
854 }
855 return result;
856}
857
874template <typename Iterator1, typename Iterator2, typename Iterator3, typename BinaryOperation,
876constexpr Iterator3 transform(
877 Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator3 result, BinaryOperation binary_op
878) noexcept(
879 noexcept(++first1) && noexcept(first2) &&
880 noexcept(++result) && noexcept(*result = binary_op(*first1, *first2))
881) {
882 for (; first1 != last1; ++first1, ++first2, ++result) {
883 *result = binary_op(*first1, *first2);
884 }
885 return result;
886}
887
888
903template <typename Iterator1, typename Iterator2, typename BinaryPredicate,
905constexpr Iterator2 unique_copy(Iterator1 first, Iterator1 last,
906 Iterator2 result, BinaryPredicate binary_pred) {
907 if (first == last) return result;
908 *result = *first;
909 while (++first != last) {
910 if (!binary_pred(*result, *first)) *++result = *first;
911 }
912 return ++result;
913}
914
924template <typename Iterator1, typename Iterator2>
925constexpr Iterator2 unique_copy(Iterator1 first, Iterator1 last, Iterator2 result) {
926 return _MSTL unique_copy(first, last, result, _MSTL equal_to<iter_value_t<Iterator1>>());
927}
928
938template <typename Iterator, enable_if_t<is_ranges_fwd_iter_v<Iterator>, int> = 0>
939constexpr Iterator unique(Iterator first, Iterator last) {
940 first = _MSTL adjacent_find(first, last);
941 return _MSTL unique_copy(first, last, first);
942}
943
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) {
957 first = _MSTL adjacent_find(first, last, binary_pred);
958 return _MSTL unique_copy(first, last, first, binary_pred);
959}
960 // ShiftAlgorithms
962
964#endif // MSTL_CORE_ALGORITHM_SHIFT_HPP__
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的便捷别名
MSTL数学函数库
MSTL键值对
MSTL查找和搜索算法
相等比较仿函数
存储两个值的元组对