NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
merge.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_ALGORITHM_MERGE_HPP__
2#define NEFORCE_CORE_ALGORITHM_MERGE_HPP__
3
11
14NEFORCE_BEGIN_NAMESPACE__
15
21
27
50template <typename Iterator1, typename Iterator2, typename Iterator3, typename Compare>
51constexpr Iterator3 merge(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Iterator3 result,
52 Compare comp) {
55 "Iterator must be input_iterator");
56
57 while (first1 != last1 && first2 != last2) {
58 if (comp(*first2, *first1)) {
59 *result = *first2;
60 ++first2;
61 } else {
62 *result = *first1;
63 ++first1;
64 }
65 ++result;
66 }
67 return _NEFORCE copy(first2, last2, _NEFORCE copy(first1, last1, result));
68}
69
82template <typename Iterator1, typename Iterator2, typename Iterator3>
83constexpr Iterator3 merge(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Iterator3 result) {
84 return _NEFORCE merge(first1, last1, first2, last2, result, _NEFORCE less<>());
85}
86
88NEFORCE_BEGIN_INNER__
89
103template <typename Iterator, typename Compare>
104constexpr void __merge_without_buffer_aux(Iterator first, Iterator middle, Iterator last,
106 Compare comp) {
107
108 if (len1 == 0 || len2 == 0) {
109 return;
110 }
111 if (len1 + len2 == 2) {
112 if (comp(*middle, *first)) {
113 _NEFORCE iter_swap(first, middle);
114 }
115 return;
116 }
117 Iterator first_cut = first;
118 Iterator second_cut = middle;
120 auto len22 = len11;
121 if (len1 > len2) {
122 len11 = len1 / 2;
123 _NEFORCE advance(first_cut, len11);
124 second_cut = _NEFORCE lower_bound(middle, last, *first_cut, comp);
125 len22 = _NEFORCE distance(middle, second_cut);
126 } else {
127 len22 = len2 / 2;
128 _NEFORCE advance(second_cut, len22);
129 first_cut = _NEFORCE upper_bound(first, middle, *second_cut, comp);
130 len11 = _NEFORCE distance(first, first_cut);
131 }
132 _NEFORCE rotate(first_cut, middle, second_cut);
133 Iterator new_middle = first_cut;
134 _NEFORCE advance(new_middle, len22);
135 inner::__merge_without_buffer_aux(first, first_cut, new_middle, len11, len22, comp);
136 inner::__merge_without_buffer_aux(new_middle, second_cut, last, len1 - len11, len2 - len22, comp);
137}
138
154template <typename Iterator1, typename Iterator2>
155constexpr Iterator1 __rotate_with_buffer_aux(Iterator1 first, Iterator1 middle, Iterator1 last,
157 Iterator2 buffer, iter_difference_t<Iterator2> buffer_size) {
158
159 Iterator2 buffer_end;
160 if (len1 > len2 && len2 <= buffer_size) {
161 buffer_end = _NEFORCE copy(middle, last, buffer);
162 _NEFORCE copy_backward(first, middle, last);
163 return _NEFORCE copy(buffer, buffer_end, first);
164 }
165 if (len1 <= buffer_size) {
166 buffer_end = _NEFORCE copy(first, middle, buffer);
167 _NEFORCE copy(middle, last, first);
168 return _NEFORCE copy_backward(buffer, buffer_end, last);
169 }
170 _NEFORCE rotate(first, middle, last);
171 _NEFORCE advance(first, len2);
172 return first;
173}
174
191template <typename Iterator, typename Pointer, typename Compare>
192constexpr void __merge_with_buffer_aux(Iterator first, Iterator middle, Iterator last, iter_difference_t<Iterator> len1,
193 iter_difference_t<Iterator> len2, Pointer buffer,
194 iter_difference_t<Iterator> buffer_size, Compare comp) {
195
196 if (len1 <= len2 && len1 <= buffer_size) {
197 Pointer end_buffer = _NEFORCE copy(first, middle, buffer);
198 _NEFORCE merge(buffer, end_buffer, middle, last, first, comp);
199 } else if (len2 <= buffer_size) {
200 Pointer end_buffer = _NEFORCE copy(middle, last, buffer);
201 if (first == middle) {
202 _NEFORCE copy_backward(buffer, end_buffer, last);
203 return;
204 }
205 if (buffer == end_buffer) {
206 _NEFORCE copy_backward(first, middle, last);
207 return;
208 }
209 --middle;
210 --end_buffer;
211 while (true) {
212 if (comp(*end_buffer, *middle)) {
213 *--last = *middle;
214 if (first == middle) {
215 _NEFORCE copy_backward(buffer, ++end_buffer, last);
216 return;
217 }
218 --middle;
219 } else {
220 *--last = *end_buffer;
221 if (buffer == end_buffer) {
222 _NEFORCE copy_backward(first, ++middle, last);
223 return;
224 }
225 --end_buffer;
226 }
227 }
228 } else {
229 Iterator first_cut = first;
230 Iterator second_cut = middle;
232 auto len22 = len11;
233 if (len1 > len2) {
234 len11 = len1 / 2;
235 _NEFORCE advance(first_cut, len11);
236 second_cut = _NEFORCE lower_bound(middle, last, *first_cut, comp);
237 len22 = _NEFORCE distance(middle, second_cut);
238 } else {
239 len22 = len2 / 2;
240 _NEFORCE advance(second_cut, len22);
241 first_cut = _NEFORCE upper_bound(first, middle, *second_cut, comp);
242 len11 = _NEFORCE distance(first, first_cut);
243 }
244 Iterator new_middle = inner::__rotate_with_buffer_aux(first_cut, middle, second_cut, len1 - len11, len22,
245 buffer, buffer_size);
246
247 inner::__merge_with_buffer_aux(first, first_cut, new_middle, len11, len22, buffer, buffer_size, comp);
248 inner::__merge_with_buffer_aux(new_middle, second_cut, last, len1 - len11, len2 - len22, buffer, buffer_size,
249 comp);
250 }
251}
252
253template <typename Iterator, typename Compare>
255__inplace_merge_dispatch(Iterator first, Iterator middle, Iterator last, iter_difference_t<Iterator> len1,
256 iter_difference_t<Iterator> len2, Compare comp) {
257 inner::__merge_without_buffer_aux(first, middle, last, len1, len2, comp);
258 return;
259}
260
261template <typename Iterator, typename Compare>
263__inplace_merge_dispatch(Iterator first, Iterator middle, Iterator last, iter_difference_t<Iterator> len1,
264 iter_difference_t<Iterator> len2, Compare comp) {
266 try {
267 buffer = temporary_buffer<Iterator>(first, last);
268 } catch (...) {
269 inner::__merge_without_buffer_aux(first, middle, last, len1, len2, comp);
270 return;
271 }
272 inner::__merge_with_buffer_aux(first, middle, last, len1, len2, buffer.begin(), buffer.size(), comp);
273 return;
274}
275
276NEFORCE_END_INNER__
278
293template <typename Iterator, typename Compare>
294NEFORCE_CONSTEXPR20 void inplace_merge(Iterator first, Iterator middle, Iterator last, Compare comp) {
295 static_assert(is_ranges_bid_iter_v<Iterator>, "Iterator must be a bidirectional_iterator");
296
297 if (first == middle || middle == last) {
298 return;
299 }
300 auto len1 = _NEFORCE distance(first, middle);
301 auto len2 = _NEFORCE distance(middle, last);
302 inner::__inplace_merge_dispatch(first, middle, last, len1, len2, comp);
303}
304
312template <typename Iterator>
313NEFORCE_CONSTEXPR20 void inplace_merge(Iterator first, Iterator middle, Iterator last) {
314 return _NEFORCE inplace_merge(first, middle, last, _NEFORCE less<>());
315}
316 // MergeAlgorithms
318 // StandardAlgorithms
320
321NEFORCE_END_NAMESPACE__
322#endif // NEFORCE_CORE_ALGORITHM_MERGE_HPP__
constexpr Iterator upper_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个大于指定值的元素位置
constexpr Iterator lower_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个不小于指定值的元素位置
constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
constexpr bool is_ranges_bid_iter_v
检查是否为范围双向迭代器
constexpr void advance(Iterator &i, Distance n)
将迭代器前进指定距离
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
typename iterator_traits< Iterator >::difference_type iter_difference_t
获取迭代器的差值类型
constexpr Iterator3 merge(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Iterator3 result, Compare comp)
合并两个已排序序列
constexpr void inplace_merge(Iterator first, Iterator middle, Iterator last, Compare comp)
原地合并两个已排序的连续范围
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 Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_aux(first, last, result)))
复制范围元素
constexpr void iter_swap(Iterator1 a, Iterator2 b) noexcept(noexcept(_NEFORCE swap(*a, *b)))
交换迭代器指向的元素
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
移位和修改算法
小于比较仿函数
constexpr size_type size() const noexcept
获取缓冲区实际大小
constexpr pointer begin() noexcept
获取缓冲区起始迭代器
临时缓冲区