1#ifndef MSTL_CORE_ALGORITHM_MERGE_HPP__
2#define MSTL_CORE_ALGORITHM_MERGE_HPP__
43template <
typename Iterator1,
typename Iterator2,
typename Iterator3,
typename Compare,
45constexpr Iterator3
merge(Iterator1 first1, Iterator1 last1, Iterator2 first2,
46 Iterator2 last2, Iterator3 result, Compare comp) {
47 while (first1 != last1 && first2 != last2) {
48 if (comp(*first2, *first1)) {
72template <
typename Iterator1,
typename Iterator2,
typename Iterator3>
73constexpr Iterator3
merge(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Iterator3 result) {
94template <
typename Iterator,
typename Distance,
typename Compare>
95constexpr void __merge_without_buffer_aux(Iterator first, Iterator middle, Iterator last,
96 Distance len1, Distance len2, Compare comp) {
97 if (len1 == 0 || len2 == 0)
return;
98 if (len1 + len2 == 2) {
102 Iterator first_cut = first;
103 Iterator second_cut = middle;
118 Iterator new_middle = first_cut;
120 _INNER __merge_without_buffer_aux(first, first_cut, new_middle, len11, len22, comp);
121 _INNER __merge_without_buffer_aux(new_middle, second_cut, last, len1 - len11, len2 - len22, comp);
140template <
typename Iterator1,
typename Iterator2,
typename Distance>
141constexpr Iterator1 __rotate_with_buffer_aux(Iterator1 first, Iterator1 middle, Iterator1 last,
142 Distance len1, Distance len2, Iterator2 buffer, Distance buffer_size) {
143 Iterator2 buffer_end;
144 if (len1 > len2 && len2 <= buffer_size) {
145 buffer_end =
_MSTL copy(middle, last, buffer);
147 return _MSTL copy(buffer, buffer_end, first);
149 if (len1 <= buffer_size) {
150 buffer_end =
_MSTL copy(first, middle, buffer);
176template <
typename Iterator,
typename Distance,
typename Po
inter,
typename Compare>
177constexpr void __merge_with_buffer_aux(Iterator first, Iterator middle, Iterator last,
178 Distance len1, Distance len2, Pointer buffer, Distance buffer_size, Compare comp) {
179 if (len1 <= len2 && len1 <= buffer_size) {
180 Pointer end_buffer =
_MSTL copy(first, middle, buffer);
181 _MSTL merge(buffer, end_buffer, middle, last, first, comp);
183 else if (len2 <= buffer_size) {
184 Pointer end_buffer =
_MSTL copy(middle, last, buffer);
185 if (first == middle) {
189 if (buffer == end_buffer) {
196 if (comp(*end_buffer, *middle)) {
198 if (first == middle) {
205 *--last = *end_buffer;
206 if (buffer == end_buffer) {
215 Iterator first_cut = first;
216 Iterator second_cut = middle;
230 Iterator new_middle =
_INNER __rotate_with_buffer_aux(
231 first_cut, middle, second_cut, len1 - len11, len22, buffer, buffer_size);
233 _INNER __merge_with_buffer_aux(
234 first, first_cut, new_middle, len11, len22, buffer, buffer_size, comp);
235 _INNER __merge_with_buffer_aux(
236 new_middle, second_cut, last, len1 - len11, len2 - len22, buffer, buffer_size, comp);
257template <
typename Iterator,
typename Compare, enable_if_t<is_ranges_b
id_iter_v<Iterator>,
int> = 0>
258constexpr void inplace_merge(Iterator first, Iterator middle, Iterator last, Compare comp) {
259 if (first == middle || middle == last)
return;
265 _INNER __merge_with_buffer_aux(
266 first, middle, last, len1, len2,
267 buffer.
begin(), Distance(buffer.
size()), comp
270 _INNER __merge_without_buffer_aux(first, middle, last, len1, len2, comp);
281template <
typename Iterator>
282constexpr void inplace_merge(Iterator first, Iterator middle, Iterator last) {
constexpr Iterator lower_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个不小于指定值的元素位置
constexpr Iterator upper_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个大于指定值的元素位置
MSTL_INLINE17 constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
constexpr void advance(Iterator &i, Distance n)
将迭代器前进指定距离
typename iterator_traits< Iterator >::value_type iter_value_t
获取迭代器的值类型
typename iterator_traits< Iterator >::difference_type iter_difference_t
获取迭代器的差值类型
constexpr void inplace_merge(Iterator first, Iterator middle, Iterator last, Compare comp)
原地合并两个已排序的连续范围
constexpr Iterator3 merge(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Iterator3 result, Compare comp)
合并两个已排序序列
#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 Iterator2 copy_backward(Iterator1 first, Iterator1 last, Iterator2 result)
反向复制范围元素
constexpr void rotate(Iterator first, Iterator middle, Iterator last)
旋转范围元素
constexpr Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制范围元素
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
MSTL_NODISCARD MSTL_CONSTEXPR20 size_type size() const noexcept
获取缓冲区实际大小
MSTL_NODISCARD MSTL_CONSTEXPR20 pointer begin() noexcept
获取缓冲区起始迭代器