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
13NEFORCE_BEGIN_NAMESPACE__
14
20
26
49template <typename Iterator1, typename Iterator2, typename Iterator3, typename Compare>
50constexpr Iterator3 merge(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Iterator3 result,
51 Compare comp) {
53 "Iterator must be forward_iterator");
54
55 while (first1 != last1 && first2 != last2) {
56 if (comp(*first2, *first1)) {
57 *result = *first2;
58 ++first2;
59 } else {
60 *result = *first1;
61 ++first1;
62 }
63 ++result;
64 }
65 return _NEFORCE copy(first2, last2, _NEFORCE copy(first1, last1, result));
66}
67
80template <typename Iterator1, typename Iterator2, typename Iterator3>
81constexpr Iterator3 merge(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Iterator3 result) {
82 return _NEFORCE merge(first1, last1, first2, last2, result, _NEFORCE less<iter_value_t<Iterator1>>());
83}
84
86NEFORCE_BEGIN_INNER__
87
101template <typename Iterator, typename Compare>
102constexpr void __merge_without_buffer_aux(Iterator first, Iterator middle, Iterator last,
104 Compare comp) {
105
106 if (len1 == 0 || len2 == 0) {
107 return;
108 }
109 if (len1 + len2 == 2) {
110 if (comp(*middle, *first)) {
111 _NEFORCE iter_swap(first, middle);
112 }
113 return;
114 }
115 Iterator first_cut = first;
116 Iterator second_cut = middle;
118 auto len22 = len11;
119 if (len1 > len2) {
120 len11 = len1 / 2;
121 _NEFORCE advance(first_cut, len11);
122 second_cut = _NEFORCE lower_bound(middle, last, *first_cut, comp);
123 len22 = _NEFORCE distance(middle, second_cut);
124 } else {
125 len22 = len2 / 2;
126 _NEFORCE advance(second_cut, len22);
127 first_cut = _NEFORCE upper_bound(first, middle, *second_cut, comp);
128 len11 = _NEFORCE distance(first, first_cut);
129 }
130 _NEFORCE rotate(first_cut, middle, second_cut);
131 Iterator new_middle = first_cut;
132 _NEFORCE advance(new_middle, len22);
133 inner::__merge_without_buffer_aux(first, first_cut, new_middle, len11, len22, comp);
134 inner::__merge_without_buffer_aux(new_middle, second_cut, last, len1 - len11, len2 - len22, comp);
135}
136
152template <typename Iterator1, typename Iterator2>
153constexpr Iterator1 __rotate_with_buffer_aux(Iterator1 first, Iterator1 middle, Iterator1 last,
155 Iterator2 buffer, iter_difference_t<Iterator2> buffer_size) {
156
157 Iterator2 buffer_end;
158 if (len1 > len2 && len2 <= buffer_size) {
159 buffer_end = _NEFORCE copy(middle, last, buffer);
160 _NEFORCE copy_backward(first, middle, last);
161 return _NEFORCE copy(buffer, buffer_end, first);
162 }
163 if (len1 <= buffer_size) {
164 buffer_end = _NEFORCE copy(first, middle, buffer);
165 _NEFORCE copy(middle, last, first);
166 return _NEFORCE copy_backward(buffer, buffer_end, last);
167 }
168 _NEFORCE rotate(first, middle, last);
169 _NEFORCE advance(first, len2);
170 return first;
171}
172
189template <typename Iterator, typename Pointer, typename Compare>
190constexpr void __merge_with_buffer_aux(Iterator first, Iterator middle, Iterator last, iter_difference_t<Iterator> len1,
191 iter_difference_t<Iterator> len2, Pointer buffer,
192 iter_difference_t<Iterator> buffer_size, Compare comp) {
193
194 if (len1 <= len2 && len1 <= buffer_size) {
195 Pointer end_buffer = _NEFORCE copy(first, middle, buffer);
196 _NEFORCE merge(buffer, end_buffer, middle, last, first, comp);
197 } else if (len2 <= buffer_size) {
198 Pointer end_buffer = _NEFORCE copy(middle, last, buffer);
199 if (first == middle) {
200 _NEFORCE copy_backward(buffer, end_buffer, last);
201 return;
202 }
203 if (buffer == end_buffer) {
204 _NEFORCE copy_backward(first, middle, last);
205 return;
206 }
207 --middle;
208 --end_buffer;
209 while (true) {
210 if (comp(*end_buffer, *middle)) {
211 *--last = *middle;
212 if (first == middle) {
213 _NEFORCE copy_backward(buffer, ++end_buffer, last);
214 return;
215 }
216 --middle;
217 } else {
218 *--last = *end_buffer;
219 if (buffer == end_buffer) {
220 _NEFORCE copy_backward(first, ++middle, last);
221 return;
222 }
223 --end_buffer;
224 }
225 }
226 } else {
227 Iterator first_cut = first;
228 Iterator second_cut = middle;
230 auto len22 = len11;
231 if (len1 > len2) {
232 len11 = len1 / 2;
233 _NEFORCE advance(first_cut, len11);
234 second_cut = _NEFORCE lower_bound(middle, last, *first_cut, comp);
235 len22 = _NEFORCE distance(middle, second_cut);
236 } else {
237 len22 = len2 / 2;
238 _NEFORCE advance(second_cut, len22);
239 first_cut = _NEFORCE upper_bound(first, middle, *second_cut, comp);
240 len11 = _NEFORCE distance(first, first_cut);
241 }
242 Iterator new_middle = inner::__rotate_with_buffer_aux(first_cut, middle, second_cut, len1 - len11, len22,
243 buffer, buffer_size);
244
245 inner::__merge_with_buffer_aux(first, first_cut, new_middle, len11, len22, buffer, buffer_size, comp);
246 inner::__merge_with_buffer_aux(new_middle, second_cut, last, len1 - len11, len2 - len22, buffer, buffer_size,
247 comp);
248 }
249}
250
251NEFORCE_END_INNER__
253
268template <typename Iterator, typename Compare>
269NEFORCE_CONSTEXPR20 void inplace_merge(Iterator first, Iterator middle, Iterator last, Compare comp) {
270 static_assert(is_ranges_bid_iter_v<Iterator>, "Iterator must be a bidirectional_iterator");
271
272 if (first == middle || middle == last) {
273 return;
274 }
275 auto len1 = _NEFORCE distance(first, middle);
276 auto len2 = _NEFORCE distance(middle, last);
277 try {
278 temporary_buffer<Iterator> buffer(first, last);
279 inner::__merge_with_buffer_aux(first, middle, last, len1, len2, buffer.begin(), buffer.size(), comp);
280 } catch (...) {
281 inner::__merge_without_buffer_aux(first, middle, last, len1, len2, comp);
282 }
283}
284
292template <typename Iterator>
293NEFORCE_CONSTEXPR20 void inplace_merge(Iterator first, Iterator middle, Iterator last) {
294 return _NEFORCE inplace_merge(first, middle, last, _NEFORCE less<iter_value_t<Iterator>>());
295}
296 // MergeAlgorithms
298 // StandardAlgorithms
300
301NEFORCE_END_NAMESPACE__
302#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)
查找有序范围中第一个不小于指定值的元素位置
NEFORCE_INLINE17 constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
NEFORCE_INLINE17 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 >::value_type iter_value_t
获取迭代器的值类型
typename iterator_traits< Iterator >::difference_type iter_difference_t
获取迭代器的差值类型
constexpr Iterator3 merge(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Iterator3 result, Compare comp)
合并两个已排序序列
NEFORCE_CONSTEXPR20 void inplace_merge(Iterator first, Iterator middle, Iterator last, Compare comp)
原地合并两个已排序的连续范围
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)))
交换迭代器指向的元素
constexpr void rotate(Iterator first, Iterator middle, Iterator last)
旋转范围元素
小于比较仿函数
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 pointer begin() noexcept
获取缓冲区起始迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type size() const noexcept
获取缓冲区实际大小
临时缓冲区