1 /*
2 *
3 * Copyright (c) 1994
4 * Hewlett-Packard Company
5 *
6 * Permission to use, copy, modify, distribute and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation. Hewlett-Packard Company makes no
11 * representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 *
15 * Copyright (c) 1996
16 * Silicon Graphics Computer Systems, Inc.
17 *
18 * Permission to use, copy, modify, distribute and sell this software
19 * and its documentation for any purpose is hereby granted without fee,
20 * provided that the above copyright notice appear in all copies and
21 * that both that copyright notice and this permission notice appear
22 * in supporting documentation. Silicon Graphics makes no
23 * representations about the suitability of this software for any
24 * purpose. It is provided "as is" without express or implied warranty.
25 */
26
27 /* NOTE: This is an internal header file, included by other STL headers.
28 * You should not attempt to use it directly.
29 */
30
31 #ifndef __SGI_STL_INTERNAL_ALGO_H
32 #define __SGI_STL_INTERNAL_ALGO_H
33
34 #include <stl_heap.h>
35
36 __STL_BEGIN_NAMESPACE
37
38 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
39 #pragma set woff 1209
40 #endif
41
42 // __median (an extension, not present in the C++ standard).
43
44 template <class _Tp>
__median(const _Tp & __a,const _Tp & __b,const _Tp & __c)45 inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) {
46 if (__a < __b)
47 if (__b < __c)
48 return __b;
49 else if (__a < __c)
50 return __c;
51 else
52 return __a;
53 else if (__a < __c)
54 return __a;
55 else if (__b < __c)
56 return __c;
57 else
58 return __b;
59 }
60
61 template <class _Tp, class _Compare>
62 inline const _Tp&
__median(const _Tp & __a,const _Tp & __b,const _Tp & __c,_Compare __comp)63 __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) {
64 if (__comp(__a, __b))
65 if (__comp(__b, __c))
66 return __b;
67 else if (__comp(__a, __c))
68 return __c;
69 else
70 return __a;
71 else if (__comp(__a, __c))
72 return __a;
73 else if (__comp(__b, __c))
74 return __c;
75 else
76 return __b;
77 }
78
79 // for_each. Apply a function to every element of a range.
80 template <class _InputIter, class _Function>
for_each(_InputIter __first,_InputIter __last,_Function __f)81 _Function for_each(_InputIter __first, _InputIter __last, _Function __f) {
82 for ( ; __first != __last; ++__first)
83 __f(*__first);
84 return __f;
85 }
86
87 // find and find_if.
88
89 template <class _InputIter, class _Tp>
find(_InputIter __first,_InputIter __last,const _Tp & __val,input_iterator_tag)90 inline _InputIter find(_InputIter __first, _InputIter __last,
91 const _Tp& __val,
92 input_iterator_tag)
93 {
94 while (__first != __last && *__first != __val)
95 ++__first;
96 return __first;
97 }
98
99 template <class _InputIter, class _Predicate>
find_if(_InputIter __first,_InputIter __last,_Predicate __pred,input_iterator_tag)100 inline _InputIter find_if(_InputIter __first, _InputIter __last,
101 _Predicate __pred,
102 input_iterator_tag)
103 {
104 while (__first != __last && !__pred(*__first))
105 ++__first;
106 return __first;
107 }
108
109 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
110
111 template <class _RandomAccessIter, class _Tp>
find(_RandomAccessIter __first,_RandomAccessIter __last,const _Tp & __val,random_access_iterator_tag)112 _RandomAccessIter find(_RandomAccessIter __first, _RandomAccessIter __last,
113 const _Tp& __val,
114 random_access_iterator_tag)
115 {
116 typename iterator_traits<_RandomAccessIter>::difference_type __trip_count
117 = (__last - __first) >> 2;
118
119 for ( ; __trip_count > 0 ; --__trip_count) {
120 if (*__first == __val) return __first;
121 ++__first;
122
123 if (*__first == __val) return __first;
124 ++__first;
125
126 if (*__first == __val) return __first;
127 ++__first;
128
129 if (*__first == __val) return __first;
130 ++__first;
131 }
132
133 switch(__last - __first) {
134 case 3:
135 if (*__first == __val) return __first;
136 ++__first;
137 case 2:
138 if (*__first == __val) return __first;
139 ++__first;
140 case 1:
141 if (*__first == __val) return __first;
142 ++__first;
143 case 0:
144 default:
145 return __last;
146 }
147 }
148
149 template <class _RandomAccessIter, class _Predicate>
find_if(_RandomAccessIter __first,_RandomAccessIter __last,_Predicate __pred,random_access_iterator_tag)150 _RandomAccessIter find_if(_RandomAccessIter __first, _RandomAccessIter __last,
151 _Predicate __pred,
152 random_access_iterator_tag)
153 {
154 typename iterator_traits<_RandomAccessIter>::difference_type __trip_count
155 = (__last - __first) >> 2;
156
157 for ( ; __trip_count > 0 ; --__trip_count) {
158 if (__pred(*__first)) return __first;
159 ++__first;
160
161 if (__pred(*__first)) return __first;
162 ++__first;
163
164 if (__pred(*__first)) return __first;
165 ++__first;
166
167 if (__pred(*__first)) return __first;
168 ++__first;
169 }
170
171 switch(__last - __first) {
172 case 3:
173 if (__pred(*__first)) return __first;
174 ++__first;
175 case 2:
176 if (__pred(*__first)) return __first;
177 ++__first;
178 case 1:
179 if (__pred(*__first)) return __first;
180 ++__first;
181 case 0:
182 default:
183 return __last;
184 }
185 }
186
187 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
188
189 template <class _InputIter, class _Tp>
find(_InputIter __first,_InputIter __last,const _Tp & __val)190 inline _InputIter find(_InputIter __first, _InputIter __last,
191 const _Tp& __val)
192 {
193 return find(__first, __last, __val, __ITERATOR_CATEGORY(__first));
194 }
195
196 template <class _InputIter, class _Predicate>
find_if(_InputIter __first,_InputIter __last,_Predicate __pred)197 inline _InputIter find_if(_InputIter __first, _InputIter __last,
198 _Predicate __pred) {
199 return find_if(__first, __last, __pred, __ITERATOR_CATEGORY(__first));
200 }
201
202 // adjacent_find.
203
204 template <class _ForwardIter>
adjacent_find(_ForwardIter __first,_ForwardIter __last)205 _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last) {
206 if (__first == __last)
207 return __last;
208 _ForwardIter __next = __first;
209 while(++__next != __last) {
210 if (*__first == *__next)
211 return __first;
212 __first = __next;
213 }
214 return __last;
215 }
216
217 template <class _ForwardIter, class _BinaryPredicate>
adjacent_find(_ForwardIter __first,_ForwardIter __last,_BinaryPredicate __binary_pred)218 _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last,
219 _BinaryPredicate __binary_pred) {
220 if (__first == __last)
221 return __last;
222 _ForwardIter __next = __first;
223 while(++__next != __last) {
224 if (__binary_pred(*__first, *__next))
225 return __first;
226 __first = __next;
227 }
228 return __last;
229 }
230
231 // count and count_if. There are two version of each, one whose return type
232 // type is void and one (present only if we have partial specialization)
233 // whose return type is iterator_traits<_InputIter>::difference_type. The
234 // C++ standard only has the latter version, but the former, which was present
235 // in the HP STL, is retained for backward compatibility.
236
237 template <class _InputIter, class _Tp, class _Size>
count(_InputIter __first,_InputIter __last,const _Tp & __value,_Size & __n)238 void count(_InputIter __first, _InputIter __last, const _Tp& __value,
239 _Size& __n) {
240 for ( ; __first != __last; ++__first)
241 if (*__first == __value)
242 ++__n;
243 }
244
245 template <class _InputIter, class _Predicate, class _Size>
count_if(_InputIter __first,_InputIter __last,_Predicate __pred,_Size & __n)246 void count_if(_InputIter __first, _InputIter __last, _Predicate __pred,
247 _Size& __n) {
248 for ( ; __first != __last; ++__first)
249 if (__pred(*__first))
250 ++__n;
251 }
252
253 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
254
255 template <class _InputIter, class _Tp>
256 typename iterator_traits<_InputIter>::difference_type
count(_InputIter __first,_InputIter __last,const _Tp & __value)257 count(_InputIter __first, _InputIter __last, const _Tp& __value) {
258 typename iterator_traits<_InputIter>::difference_type __n = 0;
259 for ( ; __first != __last; ++__first)
260 if (*__first == __value)
261 ++__n;
262 return __n;
263 }
264
265 template <class _InputIter, class _Predicate>
266 typename iterator_traits<_InputIter>::difference_type
count_if(_InputIter __first,_InputIter __last,_Predicate __pred)267 count_if(_InputIter __first, _InputIter __last, _Predicate __pred) {
268 typename iterator_traits<_InputIter>::difference_type __n = 0;
269 for ( ; __first != __last; ++__first)
270 if (__pred(*__first))
271 ++__n;
272 return __n;
273 }
274
275
276 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
277
278 // search.
279
280 template <class _ForwardIter1, class _ForwardIter2>
search(_ForwardIter1 __first1,_ForwardIter1 __last1,_ForwardIter2 __first2,_ForwardIter2 __last2)281 _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
282 _ForwardIter2 __first2, _ForwardIter2 __last2)
283 {
284 // Test for empty ranges
285 if (__first1 == __last1 || __first2 == __last2)
286 return __first1;
287
288 // Test for a pattern of length 1.
289 _ForwardIter2 __tmp(__first2);
290 ++__tmp;
291 if (__tmp == __last2)
292 return find(__first1, __last1, *__first2);
293
294 // General case.
295
296 _ForwardIter2 __p1, __p;
297
298 __p1 = __first2; ++__p1;
299
300 _ForwardIter1 __current = __first1;
301
302 while (__first1 != __last1) {
303 __first1 = find(__first1, __last1, *__first2);
304 if (__first1 == __last1)
305 return __last1;
306
307 __p = __p1;
308 __current = __first1;
309 if (++__current == __last1)
310 return __last1;
311
312 while (*__current == *__p) {
313 if (++__p == __last2)
314 return __first1;
315 if (++__current == __last1)
316 return __last1;
317 }
318
319 ++__first1;
320 }
321 return __first1;
322 }
323
324 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPred>
search(_ForwardIter1 __first1,_ForwardIter1 __last1,_ForwardIter2 __first2,_ForwardIter2 __last2,_BinaryPred __predicate)325 _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
326 _ForwardIter2 __first2, _ForwardIter2 __last2,
327 _BinaryPred __predicate)
328 {
329 // Test for empty ranges
330 if (__first1 == __last1 || __first2 == __last2)
331 return __first1;
332
333 // Test for a pattern of length 1.
334 _ForwardIter2 __tmp(__first2);
335 ++__tmp;
336 if (__tmp == __last2)
337 return find(__first1, __last1, *__first2);
338
339 // General case.
340
341 _ForwardIter2 __p1, __p;
342
343 __p1 = __first2; ++__p1;
344
345 _ForwardIter1 __current = __first1;
346
347 while (__first1 != __last1) {
348 while (__first1 != __last1) {
349 if (__predicate(*__first1, *__first2))
350 break;
351 ++__first1;
352 }
353 while (__first1 != __last1 && !__predicate(*__first1, *__first2))
354 ++__first1;
355 if (__first1 == __last1)
356 return __last1;
357
358 __p = __p1;
359 __current = __first1;
360 if (++__current == __last1) return __last1;
361
362 while (__predicate(*__current, *__p)) {
363 if (++__p == __last2)
364 return __first1;
365 if (++__current == __last1)
366 return __last1;
367 }
368
369 ++__first1;
370 }
371 return __first1;
372 }
373
374 // search_n. Search for __count consecutive copies of __val.
375
376 template <class _ForwardIter, class _Integer, class _Tp>
search_n(_ForwardIter __first,_ForwardIter __last,_Integer __count,const _Tp & __val)377 _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
378 _Integer __count, const _Tp& __val) {
379 if (__count <= 0)
380 return __first;
381 else {
382 __first = find(__first, __last, __val);
383 while (__first != __last) {
384 _Integer __n = __count - 1;
385 _ForwardIter __i = __first;
386 ++__i;
387 while (__i != __last && __n != 0 && *__i == __val) {
388 ++__i;
389 --__n;
390 }
391 if (__n == 0)
392 return __first;
393 else
394 __first = find(__i, __last, __val);
395 }
396 return __last;
397 }
398 }
399
400 template <class _ForwardIter, class _Integer, class _Tp, class _BinaryPred>
search_n(_ForwardIter __first,_ForwardIter __last,_Integer __count,const _Tp & __val,_BinaryPred __binary_pred)401 _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
402 _Integer __count, const _Tp& __val,
403 _BinaryPred __binary_pred) {
404 if (__count <= 0)
405 return __first;
406 else {
407 while (__first != __last) {
408 if (__binary_pred(*__first, __val))
409 break;
410 ++__first;
411 }
412 while (__first != __last) {
413 _Integer __n = __count - 1;
414 _ForwardIter __i = __first;
415 ++__i;
416 while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) {
417 ++__i;
418 --__n;
419 }
420 if (__n == 0)
421 return __first;
422 else {
423 while (__i != __last) {
424 if (__binary_pred(*__i, __val))
425 break;
426 ++__i;
427 }
428 __first = __i;
429 }
430 }
431 return __last;
432 }
433 }
434
435 // swap_ranges
436
437 template <class _ForwardIter1, class _ForwardIter2>
swap_ranges(_ForwardIter1 __first1,_ForwardIter1 __last1,_ForwardIter2 __first2)438 _ForwardIter2 swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1,
439 _ForwardIter2 __first2) {
440 for ( ; __first1 != __last1; ++__first1, ++__first2)
441 iter_swap(__first1, __first2);
442 return __first2;
443 }
444
445 // transform
446
447 template <class _InputIter, class _OutputIter, class _UnaryOperation>
transform(_InputIter __first,_InputIter __last,_OutputIter __result,_UnaryOperation __oper)448 _OutputIter transform(_InputIter __first, _InputIter __last,
449 _OutputIter __result, _UnaryOperation __oper) {
450 for ( ; __first != __last; ++__first, ++__result)
451 *__result = __oper(*__first);
452 return __result;
453 }
454
455 template <class _InputIter1, class _InputIter2, class _OutputIter,
456 class _BinaryOperation>
transform(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_OutputIter __result,_BinaryOperation __binary_op)457 _OutputIter transform(_InputIter1 __first1, _InputIter1 __last1,
458 _InputIter2 __first2, _OutputIter __result,
459 _BinaryOperation __binary_op) {
460 for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result)
461 *__result = __binary_op(*__first1, *__first2);
462 return __result;
463 }
464
465 // replace, replace_if, replace_copy, replace_copy_if
466
467 template <class _ForwardIter, class _Tp>
replace(_ForwardIter __first,_ForwardIter __last,const _Tp & __old_value,const _Tp & __new_value)468 void replace(_ForwardIter __first, _ForwardIter __last,
469 const _Tp& __old_value, const _Tp& __new_value) {
470 for ( ; __first != __last; ++__first)
471 if (*__first == __old_value)
472 *__first = __new_value;
473 }
474
475 template <class _ForwardIter, class _Predicate, class _Tp>
replace_if(_ForwardIter __first,_ForwardIter __last,_Predicate __pred,const _Tp & __new_value)476 void replace_if(_ForwardIter __first, _ForwardIter __last,
477 _Predicate __pred, const _Tp& __new_value) {
478 for ( ; __first != __last; ++__first)
479 if (__pred(*__first))
480 *__first = __new_value;
481 }
482
483 template <class _InputIter, class _OutputIter, class _Tp>
replace_copy(_InputIter __first,_InputIter __last,_OutputIter __result,const _Tp & __old_value,const _Tp & __new_value)484 _OutputIter replace_copy(_InputIter __first, _InputIter __last,
485 _OutputIter __result,
486 const _Tp& __old_value, const _Tp& __new_value) {
487 for ( ; __first != __last; ++__first, ++__result)
488 *__result = *__first == __old_value ? __new_value : *__first;
489 return __result;
490 }
491
492 template <class Iterator, class _OutputIter, class _Predicate, class _Tp>
replace_copy_if(Iterator __first,Iterator __last,_OutputIter __result,_Predicate __pred,const _Tp & __new_value)493 _OutputIter replace_copy_if(Iterator __first, Iterator __last,
494 _OutputIter __result,
495 _Predicate __pred, const _Tp& __new_value) {
496 for ( ; __first != __last; ++__first, ++__result)
497 *__result = __pred(*__first) ? __new_value : *__first;
498 return __result;
499 }
500
501 // generate and generate_n
502
503 template <class _ForwardIter, class _Generator>
generate(_ForwardIter __first,_ForwardIter __last,_Generator __gen)504 void generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) {
505 for ( ; __first != __last; ++__first)
506 *__first = __gen();
507 }
508
509 template <class _OutputIter, class _Size, class _Generator>
generate_n(_OutputIter __first,_Size __n,_Generator __gen)510 _OutputIter generate_n(_OutputIter __first, _Size __n, _Generator __gen) {
511 for ( ; __n > 0; --__n, ++__first)
512 *__first = __gen();
513 return __first;
514 }
515
516 // remove, remove_if, remove_copy, remove_copy_if
517
518 template <class _InputIter, class _OutputIter, class _Tp>
remove_copy(_InputIter __first,_InputIter __last,_OutputIter __result,const _Tp & __value)519 _OutputIter remove_copy(_InputIter __first, _InputIter __last,
520 _OutputIter __result, const _Tp& __value) {
521 for ( ; __first != __last; ++__first)
522 if (*__first != __value) {
523 *__result = *__first;
524 ++__result;
525 }
526 return __result;
527 }
528
529 template <class _InputIter, class _OutputIter, class _Predicate>
remove_copy_if(_InputIter __first,_InputIter __last,_OutputIter __result,_Predicate __pred)530 _OutputIter remove_copy_if(_InputIter __first, _InputIter __last,
531 _OutputIter __result, _Predicate __pred) {
532 for ( ; __first != __last; ++__first)
533 if (!__pred(*__first)) {
534 *__result = *__first;
535 ++__result;
536 }
537 return __result;
538 }
539
540 template <class _ForwardIter, class _Tp>
remove(_ForwardIter __first,_ForwardIter __last,const _Tp & __value)541 _ForwardIter remove(_ForwardIter __first, _ForwardIter __last,
542 const _Tp& __value) {
543 __first = find(__first, __last, __value);
544 _ForwardIter __i = __first;
545 return __first == __last ? __first
546 : remove_copy(++__i, __last, __first, __value);
547 }
548
549 template <class _ForwardIter, class _Predicate>
remove_if(_ForwardIter __first,_ForwardIter __last,_Predicate __pred)550 _ForwardIter remove_if(_ForwardIter __first, _ForwardIter __last,
551 _Predicate __pred) {
552 __first = find_if(__first, __last, __pred);
553 _ForwardIter __i = __first;
554 return __first == __last ? __first
555 : remove_copy_if(++__i, __last, __first, __pred);
556 }
557
558 // unique and unique_copy
559
560 template <class _InputIter, class _OutputIter, class _Tp>
__unique_copy(_InputIter __first,_InputIter __last,_OutputIter __result,_Tp *)561 _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
562 _OutputIter __result, _Tp*) {
563 _Tp __value = *__first;
564 *__result = __value;
565 while (++__first != __last)
566 if (__value != *__first) {
567 __value = *__first;
568 *++__result = __value;
569 }
570 return ++__result;
571 }
572
573 template <class _InputIter, class _OutputIter>
__unique_copy(_InputIter __first,_InputIter __last,_OutputIter __result,output_iterator_tag)574 inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
575 _OutputIter __result,
576 output_iterator_tag) {
577 return __unique_copy(__first, __last, __result, __VALUE_TYPE(__first));
578 }
579
580 template <class _InputIter, class _ForwardIter>
__unique_copy(_InputIter __first,_InputIter __last,_ForwardIter __result,forward_iterator_tag)581 _ForwardIter __unique_copy(_InputIter __first, _InputIter __last,
582 _ForwardIter __result, forward_iterator_tag) {
583 *__result = *__first;
584 while (++__first != __last)
585 if (*__result != *__first) *++__result = *__first;
586 return ++__result;
587 }
588
589 template <class _InputIter, class _OutputIter>
unique_copy(_InputIter __first,_InputIter __last,_OutputIter __result)590 inline _OutputIter unique_copy(_InputIter __first, _InputIter __last,
591 _OutputIter __result) {
592 if (__first == __last) return __result;
593 return __unique_copy(__first, __last, __result,
594 __ITERATOR_CATEGORY(__result));
595 }
596
597 template <class _InputIter, class _OutputIter, class _BinaryPredicate,
598 class _Tp>
__unique_copy(_InputIter __first,_InputIter __last,_OutputIter __result,_BinaryPredicate __binary_pred,_Tp *)599 _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
600 _OutputIter __result,
601 _BinaryPredicate __binary_pred, _Tp*) {
602 _Tp __value = *__first;
603 *__result = __value;
604 while (++__first != __last)
605 if (!__binary_pred(__value, *__first)) {
606 __value = *__first;
607 *++__result = __value;
608 }
609 return ++__result;
610 }
611
612 template <class _InputIter, class _OutputIter, class _BinaryPredicate>
__unique_copy(_InputIter __first,_InputIter __last,_OutputIter __result,_BinaryPredicate __binary_pred,output_iterator_tag)613 inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
614 _OutputIter __result,
615 _BinaryPredicate __binary_pred,
616 output_iterator_tag) {
617 return __unique_copy(__first, __last, __result, __binary_pred,
618 __VALUE_TYPE(__first));
619 }
620
621 template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
__unique_copy(_InputIter __first,_InputIter __last,_ForwardIter __result,_BinaryPredicate __binary_pred,forward_iterator_tag)622 _ForwardIter __unique_copy(_InputIter __first, _InputIter __last,
623 _ForwardIter __result,
624 _BinaryPredicate __binary_pred,
625 forward_iterator_tag) {
626 *__result = *__first;
627 while (++__first != __last)
628 if (!__binary_pred(*__result, *__first)) *++__result = *__first;
629 return ++__result;
630 }
631
632 template <class _InputIter, class _OutputIter, class _BinaryPredicate>
unique_copy(_InputIter __first,_InputIter __last,_OutputIter __result,_BinaryPredicate __binary_pred)633 inline _OutputIter unique_copy(_InputIter __first, _InputIter __last,
634 _OutputIter __result,
635 _BinaryPredicate __binary_pred) {
636 if (__first == __last) return __result;
637 return __unique_copy(__first, __last, __result, __binary_pred,
638 __ITERATOR_CATEGORY(__result));
639 }
640
641 template <class _ForwardIter>
unique(_ForwardIter __first,_ForwardIter __last)642 _ForwardIter unique(_ForwardIter __first, _ForwardIter __last) {
643 __first = adjacent_find(__first, __last);
644 return unique_copy(__first, __last, __first);
645 }
646
647 template <class _ForwardIter, class _BinaryPredicate>
unique(_ForwardIter __first,_ForwardIter __last,_BinaryPredicate __binary_pred)648 _ForwardIter unique(_ForwardIter __first, _ForwardIter __last,
649 _BinaryPredicate __binary_pred) {
650 __first = adjacent_find(__first, __last, __binary_pred);
651 return unique_copy(__first, __last, __first, __binary_pred);
652 }
653
654 // reverse and reverse_copy, and their auxiliary functions
655
656 template <class _BidirectionalIter>
__reverse(_BidirectionalIter __first,_BidirectionalIter __last,bidirectional_iterator_tag)657 void __reverse(_BidirectionalIter __first, _BidirectionalIter __last,
658 bidirectional_iterator_tag) {
659 while (true)
660 if (__first == __last || __first == --__last)
661 return;
662 else
663 iter_swap(__first++, __last);
664 }
665
666 template <class _RandomAccessIter>
__reverse(_RandomAccessIter __first,_RandomAccessIter __last,random_access_iterator_tag)667 void __reverse(_RandomAccessIter __first, _RandomAccessIter __last,
668 random_access_iterator_tag) {
669 while (__first < __last)
670 iter_swap(__first++, --__last);
671 }
672
673 template <class _BidirectionalIter>
reverse(_BidirectionalIter __first,_BidirectionalIter __last)674 inline void reverse(_BidirectionalIter __first, _BidirectionalIter __last) {
675 __reverse(__first, __last, __ITERATOR_CATEGORY(__first));
676 }
677
678 template <class _BidirectionalIter, class _OutputIter>
reverse_copy(_BidirectionalIter __first,_BidirectionalIter __last,_OutputIter __result)679 _OutputIter reverse_copy(_BidirectionalIter __first,
680 _BidirectionalIter __last,
681 _OutputIter __result) {
682 while (__first != __last) {
683 --__last;
684 *__result = *__last;
685 ++__result;
686 }
687 return __result;
688 }
689
690 // rotate and rotate_copy, and their auxiliary functions
691
692 template <class _EuclideanRingElement>
__gcd(_EuclideanRingElement __m,_EuclideanRingElement __n)693 _EuclideanRingElement __gcd(_EuclideanRingElement __m,
694 _EuclideanRingElement __n)
695 {
696 while (__n != 0) {
697 _EuclideanRingElement __t = __m % __n;
698 __m = __n;
699 __n = __t;
700 }
701 return __m;
702 }
703
704 template <class _ForwardIter, class _Distance>
__rotate(_ForwardIter __first,_ForwardIter __middle,_ForwardIter __last,_Distance *,forward_iterator_tag)705 _ForwardIter __rotate(_ForwardIter __first,
706 _ForwardIter __middle,
707 _ForwardIter __last,
708 _Distance*,
709 forward_iterator_tag) {
710 if (__first == __middle)
711 return __last;
712 if (__last == __middle)
713 return __first;
714
715 _ForwardIter __first2 = __middle;
716 do {
717 swap(*__first++, *__first2++);
718 if (__first == __middle)
719 __middle = __first2;
720 } while (__first2 != __last);
721
722 _ForwardIter __new_middle = __first;
723
724 __first2 = __middle;
725
726 while (__first2 != __last) {
727 swap (*__first++, *__first2++);
728 if (__first == __middle)
729 __middle = __first2;
730 else if (__first2 == __last)
731 __first2 = __middle;
732 }
733
734 return __new_middle;
735 }
736
737
738 template <class _BidirectionalIter, class _Distance>
__rotate(_BidirectionalIter __first,_BidirectionalIter __middle,_BidirectionalIter __last,_Distance *,bidirectional_iterator_tag)739 _BidirectionalIter __rotate(_BidirectionalIter __first,
740 _BidirectionalIter __middle,
741 _BidirectionalIter __last,
742 _Distance*,
743 bidirectional_iterator_tag) {
744 if (__first == __middle)
745 return __last;
746 if (__last == __middle)
747 return __first;
748
749 __reverse(__first, __middle, bidirectional_iterator_tag());
750 __reverse(__middle, __last, bidirectional_iterator_tag());
751
752 while (__first != __middle && __middle != __last)
753 swap (*__first++, *--__last);
754
755 if (__first == __middle) {
756 __reverse(__middle, __last, bidirectional_iterator_tag());
757 return __last;
758 }
759 else {
760 __reverse(__first, __middle, bidirectional_iterator_tag());
761 return __first;
762 }
763 }
764
765 template <class _RandomAccessIter, class _Distance, class _Tp>
__rotate(_RandomAccessIter __first,_RandomAccessIter __middle,_RandomAccessIter __last,_Distance *,_Tp *)766 _RandomAccessIter __rotate(_RandomAccessIter __first,
767 _RandomAccessIter __middle,
768 _RandomAccessIter __last,
769 _Distance *, _Tp *) {
770
771 _Distance __n = __last - __first;
772 _Distance __k = __middle - __first;
773 _Distance __l = __n - __k;
774 _RandomAccessIter __result = __first + (__last - __middle);
775
776 if (__k == __l) {
777 swap_ranges(__first, __middle, __middle);
778 return __result;
779 }
780
781 _Distance __d = __gcd(__n, __k);
782
783 for (_Distance __i = 0; __i < __d; __i++) {
784 _Tp __tmp = *__first;
785 _RandomAccessIter __p = __first;
786
787 if (__k < __l) {
788 for (_Distance __j = 0; __j < __l/__d; __j++) {
789 if (__p > __first + __l) {
790 *__p = *(__p - __l);
791 __p -= __l;
792 }
793
794 *__p = *(__p + __k);
795 __p += __k;
796 }
797 }
798
799 else {
800 for (_Distance __j = 0; __j < __k/__d - 1; __j ++) {
801 if (__p < __last - __k) {
802 *__p = *(__p + __k);
803 __p += __k;
804 }
805
806 *__p = * (__p - __l);
807 __p -= __l;
808 }
809 }
810
811 *__p = __tmp;
812 ++__first;
813 }
814
815 return __result;
816 }
817
818 template <class _ForwardIter>
rotate(_ForwardIter __first,_ForwardIter __middle,_ForwardIter __last)819 inline _ForwardIter rotate(_ForwardIter __first, _ForwardIter __middle,
820 _ForwardIter __last) {
821 return __rotate(__first, __middle, __last,
822 __DISTANCE_TYPE(__first),
823 __ITERATOR_CATEGORY(__first));
824 }
825
826 template <class _ForwardIter, class _OutputIter>
rotate_copy(_ForwardIter __first,_ForwardIter __middle,_ForwardIter __last,_OutputIter __result)827 _OutputIter rotate_copy(_ForwardIter __first, _ForwardIter __middle,
828 _ForwardIter __last, _OutputIter __result) {
829 return copy(__first, __middle, copy(__middle, __last, __result));
830 }
831
832 // Return a random number in the range [0, __n). This function encapsulates
833 // whether we're using rand (part of the standard C library) or lrand48
834 // (not standard, but a much better choice whenever it's available).
835
836 template <class _Distance>
__random_number(_Distance __n)837 inline _Distance __random_number(_Distance __n) {
838 #ifdef __STL_NO_DRAND48
839 return rand() % __n;
840 #else
841 return lrand48() % __n;
842 #endif
843 }
844
845 // random_shuffle
846
847 template <class _RandomAccessIter>
random_shuffle(_RandomAccessIter __first,_RandomAccessIter __last)848 inline void random_shuffle(_RandomAccessIter __first,
849 _RandomAccessIter __last) {
850 if (__first == __last) return;
851 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
852 iter_swap(__i, __first + __random_number((__i - __first) + 1));
853 }
854
855 template <class _RandomAccessIter, class _RandomNumberGenerator>
random_shuffle(_RandomAccessIter __first,_RandomAccessIter __last,_RandomNumberGenerator & __rand)856 void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last,
857 _RandomNumberGenerator& __rand) {
858 if (__first == __last) return;
859 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
860 iter_swap(__i, __first + __rand((__i - __first) + 1));
861 }
862
863 // random_sample and random_sample_n (extensions, not part of the standard).
864
865 template <class _ForwardIter, class _OutputIter, class _Distance>
random_sample_n(_ForwardIter __first,_ForwardIter __last,_OutputIter __out,const _Distance __n)866 _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
867 _OutputIter __out, const _Distance __n)
868 {
869 _Distance __remaining = 0;
870 distance(__first, __last, __remaining);
871 _Distance __m = min(__n, __remaining);
872
873 while (__m > 0) {
874 if (__random_number(__remaining) < __m) {
875 *__out = *__first;
876 ++__out;
877 --__m;
878 }
879
880 --__remaining;
881 ++__first;
882 }
883 return __out;
884 }
885
886 template <class _ForwardIter, class _OutputIter, class _Distance,
887 class _RandomNumberGenerator>
random_sample_n(_ForwardIter __first,_ForwardIter __last,_OutputIter __out,const _Distance __n,_RandomNumberGenerator & __rand)888 _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
889 _OutputIter __out, const _Distance __n,
890 _RandomNumberGenerator& __rand)
891 {
892 _Distance __remaining = 0;
893 distance(__first, __last, __remaining);
894 _Distance __m = min(__n, __remaining);
895
896 while (__m > 0) {
897 if (__rand(__remaining) < __m) {
898 *__out = *__first;
899 ++__out;
900 --__m;
901 }
902
903 --__remaining;
904 ++__first;
905 }
906 return __out;
907 }
908
909 template <class _InputIter, class _RandomAccessIter, class _Distance>
__random_sample(_InputIter __first,_InputIter __last,_RandomAccessIter __out,const _Distance __n)910 _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
911 _RandomAccessIter __out,
912 const _Distance __n)
913 {
914 _Distance __m = 0;
915 _Distance __t = __n;
916 for ( ; __first != __last && __m < __n; ++__m, ++__first)
917 __out[__m] = *__first;
918
919 while (__first != __last) {
920 ++__t;
921 _Distance __M = __random_number(__t);
922 if (__M < __n)
923 __out[__M] = *__first;
924 ++__first;
925 }
926
927 return __out + __m;
928 }
929
930 template <class _InputIter, class _RandomAccessIter,
931 class _RandomNumberGenerator, class _Distance>
__random_sample(_InputIter __first,_InputIter __last,_RandomAccessIter __out,_RandomNumberGenerator & __rand,const _Distance __n)932 _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
933 _RandomAccessIter __out,
934 _RandomNumberGenerator& __rand,
935 const _Distance __n)
936 {
937 _Distance __m = 0;
938 _Distance __t = __n;
939 for ( ; __first != __last && __m < __n; ++__m, ++__first)
940 __out[__m] = *__first;
941
942 while (__first != __last) {
943 ++__t;
944 _Distance __M = __rand(__t);
945 if (__M < __n)
946 __out[__M] = *__first;
947 ++__first;
948 }
949
950 return __out + __m;
951 }
952
953 template <class _InputIter, class _RandomAccessIter>
954 inline _RandomAccessIter
random_sample(_InputIter __first,_InputIter __last,_RandomAccessIter __out_first,_RandomAccessIter __out_last)955 random_sample(_InputIter __first, _InputIter __last,
956 _RandomAccessIter __out_first, _RandomAccessIter __out_last)
957 {
958 return __random_sample(__first, __last,
959 __out_first, __out_last - __out_first);
960 }
961
962
963 template <class _InputIter, class _RandomAccessIter,
964 class _RandomNumberGenerator>
965 inline _RandomAccessIter
random_sample(_InputIter __first,_InputIter __last,_RandomAccessIter __out_first,_RandomAccessIter __out_last,_RandomNumberGenerator & __rand)966 random_sample(_InputIter __first, _InputIter __last,
967 _RandomAccessIter __out_first, _RandomAccessIter __out_last,
968 _RandomNumberGenerator& __rand)
969 {
970 return __random_sample(__first, __last,
971 __out_first, __rand,
972 __out_last - __out_first);
973 }
974
975 // partition, stable_partition, and their auxiliary functions
976
977 template <class _ForwardIter, class _Predicate>
__partition(_ForwardIter __first,_ForwardIter __last,_Predicate __pred,forward_iterator_tag)978 _ForwardIter __partition(_ForwardIter __first,
979 _ForwardIter __last,
980 _Predicate __pred,
981 forward_iterator_tag) {
982 if (__first == __last) return __first;
983
984 while (__pred(*__first))
985 if (++__first == __last) return __first;
986
987 _ForwardIter __next = __first;
988
989 while (++__next != __last)
990 if (__pred(*__next)) {
991 swap(*__first, *__next);
992 ++__first;
993 }
994
995 return __first;
996 }
997
998 template <class _BidirectionalIter, class _Predicate>
__partition(_BidirectionalIter __first,_BidirectionalIter __last,_Predicate __pred,bidirectional_iterator_tag)999 _BidirectionalIter __partition(_BidirectionalIter __first,
1000 _BidirectionalIter __last,
1001 _Predicate __pred,
1002 bidirectional_iterator_tag) {
1003 while (true) {
1004 while (true)
1005 if (__first == __last)
1006 return __first;
1007 else if (__pred(*__first))
1008 ++__first;
1009 else
1010 break;
1011 --__last;
1012 while (true)
1013 if (__first == __last)
1014 return __first;
1015 else if (!__pred(*__last))
1016 --__last;
1017 else
1018 break;
1019 iter_swap(__first, __last);
1020 ++__first;
1021 }
1022 }
1023
1024 template <class _ForwardIter, class _Predicate>
partition(_ForwardIter __first,_ForwardIter __last,_Predicate __pred)1025 inline _ForwardIter partition(_ForwardIter __first,
1026 _ForwardIter __last,
1027 _Predicate __pred) {
1028 return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first));
1029 }
1030
1031
1032 template <class _ForwardIter, class _Predicate, class _Distance>
__inplace_stable_partition(_ForwardIter __first,_ForwardIter __last,_Predicate __pred,_Distance __len)1033 _ForwardIter __inplace_stable_partition(_ForwardIter __first,
1034 _ForwardIter __last,
1035 _Predicate __pred, _Distance __len) {
1036 if (__len == 1)
1037 return __pred(*__first) ? __last : __first;
1038 _ForwardIter __middle = __first;
1039 advance(__middle, __len / 2);
1040 return rotate(__inplace_stable_partition(__first, __middle, __pred,
1041 __len / 2),
1042 __middle,
1043 __inplace_stable_partition(__middle, __last, __pred,
1044 __len - __len / 2));
1045 }
1046
1047 template <class _ForwardIter, class _Pointer, class _Predicate,
1048 class _Distance>
__stable_partition_adaptive(_ForwardIter __first,_ForwardIter __last,_Predicate __pred,_Distance __len,_Pointer __buffer,_Distance __buffer_size)1049 _ForwardIter __stable_partition_adaptive(_ForwardIter __first,
1050 _ForwardIter __last,
1051 _Predicate __pred, _Distance __len,
1052 _Pointer __buffer,
1053 _Distance __buffer_size)
1054 {
1055 if (__len <= __buffer_size) {
1056 _ForwardIter __result1 = __first;
1057 _Pointer __result2 = __buffer;
1058 for ( ; __first != __last ; ++__first)
1059 if (__pred(*__first)) {
1060 *__result1 = *__first;
1061 ++__result1;
1062 }
1063 else {
1064 *__result2 = *__first;
1065 ++__result2;
1066 }
1067 copy(__buffer, __result2, __result1);
1068 return __result1;
1069 }
1070 else {
1071 _ForwardIter __middle = __first;
1072 advance(__middle, __len / 2);
1073 return rotate(__stable_partition_adaptive(
1074 __first, __middle, __pred,
1075 __len / 2, __buffer, __buffer_size),
1076 __middle,
1077 __stable_partition_adaptive(
1078 __middle, __last, __pred,
1079 __len - __len / 2, __buffer, __buffer_size));
1080 }
1081 }
1082
1083 template <class _ForwardIter, class _Predicate, class _Tp, class _Distance>
1084 inline _ForwardIter
__stable_partition_aux(_ForwardIter __first,_ForwardIter __last,_Predicate __pred,_Tp *,_Distance *)1085 __stable_partition_aux(_ForwardIter __first, _ForwardIter __last,
1086 _Predicate __pred, _Tp*, _Distance*)
1087 {
1088 _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last);
1089 if (__buf.size() > 0)
1090 return __stable_partition_adaptive(__first, __last, __pred,
1091 _Distance(__buf.requested_size()),
1092 __buf.begin(), __buf.size());
1093 else
1094 return __inplace_stable_partition(__first, __last, __pred,
1095 _Distance(__buf.requested_size()));
1096 }
1097
1098 template <class _ForwardIter, class _Predicate>
stable_partition(_ForwardIter __first,_ForwardIter __last,_Predicate __pred)1099 inline _ForwardIter stable_partition(_ForwardIter __first,
1100 _ForwardIter __last,
1101 _Predicate __pred) {
1102 if (__first == __last)
1103 return __first;
1104 else
1105 return __stable_partition_aux(__first, __last, __pred,
1106 __VALUE_TYPE(__first),
1107 __DISTANCE_TYPE(__first));
1108 }
1109
1110 template <class _RandomAccessIter, class _Tp>
__unguarded_partition(_RandomAccessIter __first,_RandomAccessIter __last,_Tp __pivot)1111 _RandomAccessIter __unguarded_partition(_RandomAccessIter __first,
1112 _RandomAccessIter __last,
1113 _Tp __pivot)
1114 {
1115 while (true) {
1116 while (*__first < __pivot)
1117 ++__first;
1118 --__last;
1119 while (__pivot < *__last)
1120 --__last;
1121 if (!(__first < __last))
1122 return __first;
1123 iter_swap(__first, __last);
1124 ++__first;
1125 }
1126 }
1127
1128 template <class _RandomAccessIter, class _Tp, class _Compare>
__unguarded_partition(_RandomAccessIter __first,_RandomAccessIter __last,_Tp __pivot,_Compare __comp)1129 _RandomAccessIter __unguarded_partition(_RandomAccessIter __first,
1130 _RandomAccessIter __last,
1131 _Tp __pivot, _Compare __comp)
1132 {
1133 while (true) {
1134 while (__comp(*__first, __pivot))
1135 ++__first;
1136 --__last;
1137 while (__comp(__pivot, *__last))
1138 --__last;
1139 if (!(__first < __last))
1140 return __first;
1141 iter_swap(__first, __last);
1142 ++__first;
1143 }
1144 }
1145
1146 const int __stl_threshold = 16;
1147
1148 // sort() and its auxiliary functions.
1149
1150 template <class _RandomAccessIter, class _Tp>
__unguarded_linear_insert(_RandomAccessIter __last,_Tp __val)1151 void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) {
1152 _RandomAccessIter __next = __last;
1153 --__next;
1154 while (__val < *__next) {
1155 *__last = *__next;
1156 __last = __next;
1157 --__next;
1158 }
1159 *__last = __val;
1160 }
1161
1162 template <class _RandomAccessIter, class _Tp, class _Compare>
__unguarded_linear_insert(_RandomAccessIter __last,_Tp __val,_Compare __comp)1163 void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val,
1164 _Compare __comp) {
1165 _RandomAccessIter __next = __last;
1166 --__next;
1167 while (__comp(__val, *__next)) {
1168 *__last = *__next;
1169 __last = __next;
1170 --__next;
1171 }
1172 *__last = __val;
1173 }
1174
1175 template <class _RandomAccessIter, class _Tp>
__linear_insert(_RandomAccessIter __first,_RandomAccessIter __last,_Tp *)1176 inline void __linear_insert(_RandomAccessIter __first,
1177 _RandomAccessIter __last, _Tp*) {
1178 _Tp __val = *__last;
1179 if (__val < *__first) {
1180 copy_backward(__first, __last, __last + 1);
1181 *__first = __val;
1182 }
1183 else
1184 __unguarded_linear_insert(__last, __val);
1185 }
1186
1187 template <class _RandomAccessIter, class _Tp, class _Compare>
__linear_insert(_RandomAccessIter __first,_RandomAccessIter __last,_Tp *,_Compare __comp)1188 inline void __linear_insert(_RandomAccessIter __first,
1189 _RandomAccessIter __last, _Tp*, _Compare __comp) {
1190 _Tp __val = *__last;
1191 if (__comp(__val, *__first)) {
1192 copy_backward(__first, __last, __last + 1);
1193 *__first = __val;
1194 }
1195 else
1196 __unguarded_linear_insert(__last, __val, __comp);
1197 }
1198
1199 template <class _RandomAccessIter>
__insertion_sort(_RandomAccessIter __first,_RandomAccessIter __last)1200 void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) {
1201 if (__first == __last) return;
1202 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
1203 __linear_insert(__first, __i, __VALUE_TYPE(__first));
1204 }
1205
1206 template <class _RandomAccessIter, class _Compare>
__insertion_sort(_RandomAccessIter __first,_RandomAccessIter __last,_Compare __comp)1207 void __insertion_sort(_RandomAccessIter __first,
1208 _RandomAccessIter __last, _Compare __comp) {
1209 if (__first == __last) return;
1210 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
1211 __linear_insert(__first, __i, __VALUE_TYPE(__first), __comp);
1212 }
1213
1214 template <class _RandomAccessIter, class _Tp>
__unguarded_insertion_sort_aux(_RandomAccessIter __first,_RandomAccessIter __last,_Tp *)1215 void __unguarded_insertion_sort_aux(_RandomAccessIter __first,
1216 _RandomAccessIter __last, _Tp*) {
1217 for (_RandomAccessIter __i = __first; __i != __last; ++__i)
1218 __unguarded_linear_insert(__i, _Tp(*__i));
1219 }
1220
1221 template <class _RandomAccessIter>
__unguarded_insertion_sort(_RandomAccessIter __first,_RandomAccessIter __last)1222 inline void __unguarded_insertion_sort(_RandomAccessIter __first,
1223 _RandomAccessIter __last) {
1224 __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first));
1225 }
1226
1227 template <class _RandomAccessIter, class _Tp, class _Compare>
__unguarded_insertion_sort_aux(_RandomAccessIter __first,_RandomAccessIter __last,_Tp *,_Compare __comp)1228 void __unguarded_insertion_sort_aux(_RandomAccessIter __first,
1229 _RandomAccessIter __last,
1230 _Tp*, _Compare __comp) {
1231 for (_RandomAccessIter __i = __first; __i != __last; ++__i)
1232 __unguarded_linear_insert(__i, _Tp(*__i), __comp);
1233 }
1234
1235 template <class _RandomAccessIter, class _Compare>
__unguarded_insertion_sort(_RandomAccessIter __first,_RandomAccessIter __last,_Compare __comp)1236 inline void __unguarded_insertion_sort(_RandomAccessIter __first,
1237 _RandomAccessIter __last,
1238 _Compare __comp) {
1239 __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first),
1240 __comp);
1241 }
1242
1243 template <class _RandomAccessIter>
__final_insertion_sort(_RandomAccessIter __first,_RandomAccessIter __last)1244 void __final_insertion_sort(_RandomAccessIter __first,
1245 _RandomAccessIter __last) {
1246 if (__last - __first > __stl_threshold) {
1247 __insertion_sort(__first, __first + __stl_threshold);
1248 __unguarded_insertion_sort(__first + __stl_threshold, __last);
1249 }
1250 else
1251 __insertion_sort(__first, __last);
1252 }
1253
1254 template <class _RandomAccessIter, class _Compare>
__final_insertion_sort(_RandomAccessIter __first,_RandomAccessIter __last,_Compare __comp)1255 void __final_insertion_sort(_RandomAccessIter __first,
1256 _RandomAccessIter __last, _Compare __comp) {
1257 if (__last - __first > __stl_threshold) {
1258 __insertion_sort(__first, __first + __stl_threshold, __comp);
1259 __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp);
1260 }
1261 else
1262 __insertion_sort(__first, __last, __comp);
1263 }
1264
1265 template <class _Size>
__lg(_Size __n)1266 inline _Size __lg(_Size __n) {
1267 _Size __k;
1268 for (__k = 0; __n != 1; __n >>= 1) ++__k;
1269 return __k;
1270 }
1271
1272 template <class _RandomAccessIter, class _Tp, class _Size>
__introsort_loop(_RandomAccessIter __first,_RandomAccessIter __last,_Tp *,_Size __depth_limit)1273 void __introsort_loop(_RandomAccessIter __first,
1274 _RandomAccessIter __last, _Tp*,
1275 _Size __depth_limit)
1276 {
1277 while (__last - __first > __stl_threshold) {
1278 if (__depth_limit == 0) {
1279 partial_sort(__first, __last, __last);
1280 return;
1281 }
1282 --__depth_limit;
1283 _RandomAccessIter __cut =
1284 __unguarded_partition(__first, __last,
1285 _Tp(__median(*__first,
1286 *(__first + (__last - __first)/2),
1287 *(__last - 1))));
1288 __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit);
1289 __last = __cut;
1290 }
1291 }
1292
1293 template <class _RandomAccessIter, class _Tp, class _Size, class _Compare>
__introsort_loop(_RandomAccessIter __first,_RandomAccessIter __last,_Tp *,_Size __depth_limit,_Compare __comp)1294 void __introsort_loop(_RandomAccessIter __first,
1295 _RandomAccessIter __last, _Tp*,
1296 _Size __depth_limit, _Compare __comp)
1297 {
1298 while (__last - __first > __stl_threshold) {
1299 if (__depth_limit == 0) {
1300 partial_sort(__first, __last, __last, __comp);
1301 return;
1302 }
1303 --__depth_limit;
1304 _RandomAccessIter __cut =
1305 __unguarded_partition(__first, __last,
1306 _Tp(__median(*__first,
1307 *(__first + (__last - __first)/2),
1308 *(__last - 1), __comp)),
1309 __comp);
1310 __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp);
1311 __last = __cut;
1312 }
1313 }
1314
1315 template <class _RandomAccessIter>
sort(_RandomAccessIter __first,_RandomAccessIter __last)1316 inline void sort(_RandomAccessIter __first, _RandomAccessIter __last) {
1317 if (__first != __last) {
1318 __introsort_loop(__first, __last,
1319 __VALUE_TYPE(__first),
1320 __lg(__last - __first) * 2);
1321 __final_insertion_sort(__first, __last);
1322 }
1323 }
1324
1325 template <class _RandomAccessIter, class _Compare>
sort(_RandomAccessIter __first,_RandomAccessIter __last,_Compare __comp)1326 inline void sort(_RandomAccessIter __first, _RandomAccessIter __last,
1327 _Compare __comp) {
1328 if (__first != __last) {
1329 __introsort_loop(__first, __last,
1330 __VALUE_TYPE(__first),
1331 __lg(__last - __first) * 2,
1332 __comp);
1333 __final_insertion_sort(__first, __last, __comp);
1334 }
1335 }
1336
1337 // stable_sort() and its auxiliary functions.
1338
1339 template <class _RandomAccessIter>
__inplace_stable_sort(_RandomAccessIter __first,_RandomAccessIter __last)1340 void __inplace_stable_sort(_RandomAccessIter __first,
1341 _RandomAccessIter __last) {
1342 if (__last - __first < 15) {
1343 __insertion_sort(__first, __last);
1344 return;
1345 }
1346 _RandomAccessIter __middle = __first + (__last - __first) / 2;
1347 __inplace_stable_sort(__first, __middle);
1348 __inplace_stable_sort(__middle, __last);
1349 __merge_without_buffer(__first, __middle, __last,
1350 __middle - __first,
1351 __last - __middle);
1352 }
1353
1354 template <class _RandomAccessIter, class _Compare>
__inplace_stable_sort(_RandomAccessIter __first,_RandomAccessIter __last,_Compare __comp)1355 void __inplace_stable_sort(_RandomAccessIter __first,
1356 _RandomAccessIter __last, _Compare __comp) {
1357 if (__last - __first < 15) {
1358 __insertion_sort(__first, __last, __comp);
1359 return;
1360 }
1361 _RandomAccessIter __middle = __first + (__last - __first) / 2;
1362 __inplace_stable_sort(__first, __middle, __comp);
1363 __inplace_stable_sort(__middle, __last, __comp);
1364 __merge_without_buffer(__first, __middle, __last,
1365 __middle - __first,
1366 __last - __middle,
1367 __comp);
1368 }
1369
1370 template <class _RandomAccessIter1, class _RandomAccessIter2,
1371 class _Distance>
__merge_sort_loop(_RandomAccessIter1 __first,_RandomAccessIter1 __last,_RandomAccessIter2 __result,_Distance __step_size)1372 void __merge_sort_loop(_RandomAccessIter1 __first,
1373 _RandomAccessIter1 __last,
1374 _RandomAccessIter2 __result, _Distance __step_size) {
1375 _Distance __two_step = 2 * __step_size;
1376
1377 while (__last - __first >= __two_step) {
1378 __result = merge(__first, __first + __step_size,
1379 __first + __step_size, __first + __two_step,
1380 __result);
1381 __first += __two_step;
1382 }
1383
1384 __step_size = min(_Distance(__last - __first), __step_size);
1385 merge(__first, __first + __step_size, __first + __step_size, __last,
1386 __result);
1387 }
1388
1389 template <class _RandomAccessIter1, class _RandomAccessIter2,
1390 class _Distance, class _Compare>
__merge_sort_loop(_RandomAccessIter1 __first,_RandomAccessIter1 __last,_RandomAccessIter2 __result,_Distance __step_size,_Compare __comp)1391 void __merge_sort_loop(_RandomAccessIter1 __first,
1392 _RandomAccessIter1 __last,
1393 _RandomAccessIter2 __result, _Distance __step_size,
1394 _Compare __comp) {
1395 _Distance __two_step = 2 * __step_size;
1396
1397 while (__last - __first >= __two_step) {
1398 __result = merge(__first, __first + __step_size,
1399 __first + __step_size, __first + __two_step,
1400 __result,
1401 __comp);
1402 __first += __two_step;
1403 }
1404 __step_size = min(_Distance(__last - __first), __step_size);
1405
1406 merge(__first, __first + __step_size,
1407 __first + __step_size, __last,
1408 __result,
1409 __comp);
1410 }
1411
1412 const int __stl_chunk_size = 7;
1413
1414 template <class _RandomAccessIter, class _Distance>
__chunk_insertion_sort(_RandomAccessIter __first,_RandomAccessIter __last,_Distance __chunk_size)1415 void __chunk_insertion_sort(_RandomAccessIter __first,
1416 _RandomAccessIter __last, _Distance __chunk_size)
1417 {
1418 while (__last - __first >= __chunk_size) {
1419 __insertion_sort(__first, __first + __chunk_size);
1420 __first += __chunk_size;
1421 }
1422 __insertion_sort(__first, __last);
1423 }
1424
1425 template <class _RandomAccessIter, class _Distance, class _Compare>
__chunk_insertion_sort(_RandomAccessIter __first,_RandomAccessIter __last,_Distance __chunk_size,_Compare __comp)1426 void __chunk_insertion_sort(_RandomAccessIter __first,
1427 _RandomAccessIter __last,
1428 _Distance __chunk_size, _Compare __comp)
1429 {
1430 while (__last - __first >= __chunk_size) {
1431 __insertion_sort(__first, __first + __chunk_size, __comp);
1432 __first += __chunk_size;
1433 }
1434 __insertion_sort(__first, __last, __comp);
1435 }
1436
1437 template <class _RandomAccessIter, class _Pointer, class _Distance>
__merge_sort_with_buffer(_RandomAccessIter __first,_RandomAccessIter __last,_Pointer __buffer,_Distance *)1438 void __merge_sort_with_buffer(_RandomAccessIter __first,
1439 _RandomAccessIter __last,
1440 _Pointer __buffer, _Distance*) {
1441 _Distance __len = __last - __first;
1442 _Pointer __buffer_last = __buffer + __len;
1443
1444 _Distance __step_size = __stl_chunk_size;
1445 __chunk_insertion_sort(__first, __last, __step_size);
1446
1447 while (__step_size < __len) {
1448 __merge_sort_loop(__first, __last, __buffer, __step_size);
1449 __step_size *= 2;
1450 __merge_sort_loop(__buffer, __buffer_last, __first, __step_size);
1451 __step_size *= 2;
1452 }
1453 }
1454
1455 template <class _RandomAccessIter, class _Pointer, class _Distance,
1456 class _Compare>
__merge_sort_with_buffer(_RandomAccessIter __first,_RandomAccessIter __last,_Pointer __buffer,_Distance *,_Compare __comp)1457 void __merge_sort_with_buffer(_RandomAccessIter __first,
1458 _RandomAccessIter __last, _Pointer __buffer,
1459 _Distance*, _Compare __comp) {
1460 _Distance __len = __last - __first;
1461 _Pointer __buffer_last = __buffer + __len;
1462
1463 _Distance __step_size = __stl_chunk_size;
1464 __chunk_insertion_sort(__first, __last, __step_size, __comp);
1465
1466 while (__step_size < __len) {
1467 __merge_sort_loop(__first, __last, __buffer, __step_size, __comp);
1468 __step_size *= 2;
1469 __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp);
1470 __step_size *= 2;
1471 }
1472 }
1473
1474 template <class _RandomAccessIter, class _Pointer, class _Distance>
__stable_sort_adaptive(_RandomAccessIter __first,_RandomAccessIter __last,_Pointer __buffer,_Distance __buffer_size)1475 void __stable_sort_adaptive(_RandomAccessIter __first,
1476 _RandomAccessIter __last, _Pointer __buffer,
1477 _Distance __buffer_size) {
1478 _Distance __len = (__last - __first + 1) / 2;
1479 _RandomAccessIter __middle = __first + __len;
1480 if (__len > __buffer_size) {
1481 __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size);
1482 __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size);
1483 }
1484 else {
1485 __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0);
1486 __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0);
1487 }
1488 __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first),
1489 _Distance(__last - __middle), __buffer, __buffer_size);
1490 }
1491
1492 template <class _RandomAccessIter, class _Pointer, class _Distance,
1493 class _Compare>
__stable_sort_adaptive(_RandomAccessIter __first,_RandomAccessIter __last,_Pointer __buffer,_Distance __buffer_size,_Compare __comp)1494 void __stable_sort_adaptive(_RandomAccessIter __first,
1495 _RandomAccessIter __last, _Pointer __buffer,
1496 _Distance __buffer_size, _Compare __comp) {
1497 _Distance __len = (__last - __first + 1) / 2;
1498 _RandomAccessIter __middle = __first + __len;
1499 if (__len > __buffer_size) {
1500 __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size,
1501 __comp);
1502 __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size,
1503 __comp);
1504 }
1505 else {
1506 __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0,
1507 __comp);
1508 __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0,
1509 __comp);
1510 }
1511 __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first),
1512 _Distance(__last - __middle), __buffer, __buffer_size,
1513 __comp);
1514 }
1515
1516 template <class _RandomAccessIter, class _Tp, class _Distance>
__stable_sort_aux(_RandomAccessIter __first,_RandomAccessIter __last,_Tp *,_Distance *)1517 inline void __stable_sort_aux(_RandomAccessIter __first,
1518 _RandomAccessIter __last, _Tp*, _Distance*) {
1519 _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last);
1520 if (buf.begin() == 0)
1521 __inplace_stable_sort(__first, __last);
1522 else
1523 __stable_sort_adaptive(__first, __last, buf.begin(),
1524 _Distance(buf.size()));
1525 }
1526
1527 template <class _RandomAccessIter, class _Tp, class _Distance, class _Compare>
__stable_sort_aux(_RandomAccessIter __first,_RandomAccessIter __last,_Tp *,_Distance *,_Compare __comp)1528 inline void __stable_sort_aux(_RandomAccessIter __first,
1529 _RandomAccessIter __last, _Tp*, _Distance*,
1530 _Compare __comp) {
1531 _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last);
1532 if (buf.begin() == 0)
1533 __inplace_stable_sort(__first, __last, __comp);
1534 else
1535 __stable_sort_adaptive(__first, __last, buf.begin(),
1536 _Distance(buf.size()),
1537 __comp);
1538 }
1539
1540 template <class _RandomAccessIter>
stable_sort(_RandomAccessIter __first,_RandomAccessIter __last)1541 inline void stable_sort(_RandomAccessIter __first,
1542 _RandomAccessIter __last) {
1543 __stable_sort_aux(__first, __last,
1544 __VALUE_TYPE(__first),
1545 __DISTANCE_TYPE(__first));
1546 }
1547
1548 template <class _RandomAccessIter, class _Compare>
stable_sort(_RandomAccessIter __first,_RandomAccessIter __last,_Compare __comp)1549 inline void stable_sort(_RandomAccessIter __first,
1550 _RandomAccessIter __last, _Compare __comp) {
1551 __stable_sort_aux(__first, __last,
1552 __VALUE_TYPE(__first),
1553 __DISTANCE_TYPE(__first),
1554 __comp);
1555 }
1556
1557 // partial_sort, partial_sort_copy, and auxiliary functions.
1558
1559 template <class _RandomAccessIter, class _Tp>
__partial_sort(_RandomAccessIter __first,_RandomAccessIter __middle,_RandomAccessIter __last,_Tp *)1560 void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle,
1561 _RandomAccessIter __last, _Tp*) {
1562 make_heap(__first, __middle);
1563 for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
1564 if (*__i < *__first)
1565 __pop_heap(__first, __middle, __i, _Tp(*__i),
1566 __DISTANCE_TYPE(__first));
1567 sort_heap(__first, __middle);
1568 }
1569
1570 template <class _RandomAccessIter>
partial_sort(_RandomAccessIter __first,_RandomAccessIter __middle,_RandomAccessIter __last)1571 inline void partial_sort(_RandomAccessIter __first,
1572 _RandomAccessIter __middle,
1573 _RandomAccessIter __last) {
1574 __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first));
1575 }
1576
1577 template <class _RandomAccessIter, class _Tp, class _Compare>
__partial_sort(_RandomAccessIter __first,_RandomAccessIter __middle,_RandomAccessIter __last,_Tp *,_Compare __comp)1578 void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle,
1579 _RandomAccessIter __last, _Tp*, _Compare __comp) {
1580 make_heap(__first, __middle, __comp);
1581 for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
1582 if (__comp(*__i, *__first))
1583 __pop_heap(__first, __middle, __i, _Tp(*__i), __comp,
1584 __DISTANCE_TYPE(__first));
1585 sort_heap(__first, __middle, __comp);
1586 }
1587
1588 template <class _RandomAccessIter, class _Compare>
partial_sort(_RandomAccessIter __first,_RandomAccessIter __middle,_RandomAccessIter __last,_Compare __comp)1589 inline void partial_sort(_RandomAccessIter __first,
1590 _RandomAccessIter __middle,
1591 _RandomAccessIter __last, _Compare __comp) {
1592 __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first), __comp);
1593 }
1594
1595 template <class _InputIter, class _RandomAccessIter, class _Distance,
1596 class _Tp>
__partial_sort_copy(_InputIter __first,_InputIter __last,_RandomAccessIter __result_first,_RandomAccessIter __result_last,_Distance *,_Tp *)1597 _RandomAccessIter __partial_sort_copy(_InputIter __first,
1598 _InputIter __last,
1599 _RandomAccessIter __result_first,
1600 _RandomAccessIter __result_last,
1601 _Distance*, _Tp*) {
1602 if (__result_first == __result_last) return __result_last;
1603 _RandomAccessIter __result_real_last = __result_first;
1604 while(__first != __last && __result_real_last != __result_last) {
1605 *__result_real_last = *__first;
1606 ++__result_real_last;
1607 ++__first;
1608 }
1609 make_heap(__result_first, __result_real_last);
1610 while (__first != __last) {
1611 if (*__first < *__result_first)
1612 __adjust_heap(__result_first, _Distance(0),
1613 _Distance(__result_real_last - __result_first),
1614 _Tp(*__first));
1615 ++__first;
1616 }
1617 sort_heap(__result_first, __result_real_last);
1618 return __result_real_last;
1619 }
1620
1621 template <class _InputIter, class _RandomAccessIter>
1622 inline _RandomAccessIter
partial_sort_copy(_InputIter __first,_InputIter __last,_RandomAccessIter __result_first,_RandomAccessIter __result_last)1623 partial_sort_copy(_InputIter __first, _InputIter __last,
1624 _RandomAccessIter __result_first,
1625 _RandomAccessIter __result_last) {
1626 return __partial_sort_copy(__first, __last, __result_first, __result_last,
1627 __DISTANCE_TYPE(__result_first),
1628 __VALUE_TYPE(__first));
1629 }
1630
1631 template <class _InputIter, class _RandomAccessIter, class _Compare,
1632 class _Distance, class _Tp>
__partial_sort_copy(_InputIter __first,_InputIter __last,_RandomAccessIter __result_first,_RandomAccessIter __result_last,_Compare __comp,_Distance *,_Tp *)1633 _RandomAccessIter __partial_sort_copy(_InputIter __first,
1634 _InputIter __last,
1635 _RandomAccessIter __result_first,
1636 _RandomAccessIter __result_last,
1637 _Compare __comp, _Distance*, _Tp*) {
1638 if (__result_first == __result_last) return __result_last;
1639 _RandomAccessIter __result_real_last = __result_first;
1640 while(__first != __last && __result_real_last != __result_last) {
1641 *__result_real_last = *__first;
1642 ++__result_real_last;
1643 ++__first;
1644 }
1645 make_heap(__result_first, __result_real_last, __comp);
1646 while (__first != __last) {
1647 if (__comp(*__first, *__result_first))
1648 __adjust_heap(__result_first, _Distance(0),
1649 _Distance(__result_real_last - __result_first),
1650 _Tp(*__first),
1651 __comp);
1652 ++__first;
1653 }
1654 sort_heap(__result_first, __result_real_last, __comp);
1655 return __result_real_last;
1656 }
1657
1658 template <class _InputIter, class _RandomAccessIter, class _Compare>
1659 inline _RandomAccessIter
partial_sort_copy(_InputIter __first,_InputIter __last,_RandomAccessIter __result_first,_RandomAccessIter __result_last,_Compare __comp)1660 partial_sort_copy(_InputIter __first, _InputIter __last,
1661 _RandomAccessIter __result_first,
1662 _RandomAccessIter __result_last, _Compare __comp) {
1663 return __partial_sort_copy(__first, __last, __result_first, __result_last,
1664 __comp,
1665 __DISTANCE_TYPE(__result_first),
1666 __VALUE_TYPE(__first));
1667 }
1668
1669 // nth_element() and its auxiliary functions.
1670
1671 template <class _RandomAccessIter, class _Tp>
__nth_element(_RandomAccessIter __first,_RandomAccessIter __nth,_RandomAccessIter __last,_Tp *)1672 void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
1673 _RandomAccessIter __last, _Tp*) {
1674 while (__last - __first > 3) {
1675 _RandomAccessIter __cut =
1676 __unguarded_partition(__first, __last,
1677 _Tp(__median(*__first,
1678 *(__first + (__last - __first)/2),
1679 *(__last - 1))));
1680 if (__cut <= __nth)
1681 __first = __cut;
1682 else
1683 __last = __cut;
1684 }
1685 __insertion_sort(__first, __last);
1686 }
1687
1688 template <class _RandomAccessIter>
nth_element(_RandomAccessIter __first,_RandomAccessIter __nth,_RandomAccessIter __last)1689 inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
1690 _RandomAccessIter __last) {
1691 __nth_element(__first, __nth, __last, __VALUE_TYPE(__first));
1692 }
1693
1694 template <class _RandomAccessIter, class _Tp, class _Compare>
__nth_element(_RandomAccessIter __first,_RandomAccessIter __nth,_RandomAccessIter __last,_Tp *,_Compare __comp)1695 void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
1696 _RandomAccessIter __last, _Tp*, _Compare __comp) {
1697 while (__last - __first > 3) {
1698 _RandomAccessIter __cut =
1699 __unguarded_partition(__first, __last,
1700 _Tp(__median(*__first,
1701 *(__first + (__last - __first)/2),
1702 *(__last - 1),
1703 __comp)),
1704 __comp);
1705 if (__cut <= __nth)
1706 __first = __cut;
1707 else
1708 __last = __cut;
1709 }
1710 __insertion_sort(__first, __last, __comp);
1711 }
1712
1713 template <class _RandomAccessIter, class _Compare>
nth_element(_RandomAccessIter __first,_RandomAccessIter __nth,_RandomAccessIter __last,_Compare __comp)1714 inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
1715 _RandomAccessIter __last, _Compare __comp) {
1716 __nth_element(__first, __nth, __last, __VALUE_TYPE(__first), __comp);
1717 }
1718
1719
1720 // Binary search (lower_bound, upper_bound, equal_range, binary_search).
1721
1722 template <class _ForwardIter, class _Tp, class _Distance>
__lower_bound(_ForwardIter __first,_ForwardIter __last,const _Tp & __val,_Distance *)1723 _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last,
1724 const _Tp& __val, _Distance*)
1725 {
1726 _Distance __len = 0;
1727 distance(__first, __last, __len);
1728 _Distance __half;
1729 _ForwardIter __middle;
1730
1731 while (__len > 0) {
1732 __half = __len >> 1;
1733 __middle = __first;
1734 advance(__middle, __half);
1735 if (*__middle < __val) {
1736 __first = __middle;
1737 ++__first;
1738 __len = __len - __half - 1;
1739 }
1740 else
1741 __len = __half;
1742 }
1743 return __first;
1744 }
1745
1746 template <class _ForwardIter, class _Tp>
lower_bound(_ForwardIter __first,_ForwardIter __last,const _Tp & __val)1747 inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last,
1748 const _Tp& __val) {
1749 return __lower_bound(__first, __last, __val,
1750 __DISTANCE_TYPE(__first));
1751 }
1752
1753 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
__lower_bound(_ForwardIter __first,_ForwardIter __last,const _Tp & __val,_Compare __comp,_Distance *)1754 _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last,
1755 const _Tp& __val, _Compare __comp, _Distance*)
1756 {
1757 _Distance __len = 0;
1758 distance(__first, __last, __len);
1759 _Distance __half;
1760 _ForwardIter __middle;
1761
1762 while (__len > 0) {
1763 __half = __len >> 1;
1764 __middle = __first;
1765 advance(__middle, __half);
1766 if (__comp(*__middle, __val)) {
1767 __first = __middle;
1768 ++__first;
1769 __len = __len - __half - 1;
1770 }
1771 else
1772 __len = __half;
1773 }
1774 return __first;
1775 }
1776
1777 template <class _ForwardIter, class _Tp, class _Compare>
lower_bound(_ForwardIter __first,_ForwardIter __last,const _Tp & __val,_Compare __comp)1778 inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last,
1779 const _Tp& __val, _Compare __comp) {
1780 return __lower_bound(__first, __last, __val, __comp,
1781 __DISTANCE_TYPE(__first));
1782 }
1783
1784 template <class _ForwardIter, class _Tp, class _Distance>
__upper_bound(_ForwardIter __first,_ForwardIter __last,const _Tp & __val,_Distance *)1785 _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last,
1786 const _Tp& __val, _Distance*)
1787 {
1788 _Distance __len = 0;
1789 distance(__first, __last, __len);
1790 _Distance __half;
1791 _ForwardIter __middle;
1792
1793 while (__len > 0) {
1794 __half = __len >> 1;
1795 __middle = __first;
1796 advance(__middle, __half);
1797 if (__val < *__middle)
1798 __len = __half;
1799 else {
1800 __first = __middle;
1801 ++__first;
1802 __len = __len - __half - 1;
1803 }
1804 }
1805 return __first;
1806 }
1807
1808 template <class _ForwardIter, class _Tp>
upper_bound(_ForwardIter __first,_ForwardIter __last,const _Tp & __val)1809 inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last,
1810 const _Tp& __val) {
1811 return __upper_bound(__first, __last, __val,
1812 __DISTANCE_TYPE(__first));
1813 }
1814
1815 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
__upper_bound(_ForwardIter __first,_ForwardIter __last,const _Tp & __val,_Compare __comp,_Distance *)1816 _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last,
1817 const _Tp& __val, _Compare __comp, _Distance*)
1818 {
1819 _Distance __len = 0;
1820 distance(__first, __last, __len);
1821 _Distance __half;
1822 _ForwardIter __middle;
1823
1824 while (__len > 0) {
1825 __half = __len >> 1;
1826 __middle = __first;
1827 advance(__middle, __half);
1828 if (__comp(__val, *__middle))
1829 __len = __half;
1830 else {
1831 __first = __middle;
1832 ++__first;
1833 __len = __len - __half - 1;
1834 }
1835 }
1836 return __first;
1837 }
1838
1839 template <class _ForwardIter, class _Tp, class _Compare>
upper_bound(_ForwardIter __first,_ForwardIter __last,const _Tp & __val,_Compare __comp)1840 inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last,
1841 const _Tp& __val, _Compare __comp) {
1842 return __upper_bound(__first, __last, __val, __comp,
1843 __DISTANCE_TYPE(__first));
1844 }
1845
1846 template <class _ForwardIter, class _Tp, class _Distance>
1847 pair<_ForwardIter, _ForwardIter>
__equal_range(_ForwardIter __first,_ForwardIter __last,const _Tp & __val,_Distance *)1848 __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
1849 _Distance*)
1850 {
1851 _Distance __len = 0;
1852 distance(__first, __last, __len);
1853 _Distance __half;
1854 _ForwardIter __middle, __left, __right;
1855
1856 while (__len > 0) {
1857 __half = __len >> 1;
1858 __middle = __first;
1859 advance(__middle, __half);
1860 if (*__middle < __val) {
1861 __first = __middle;
1862 ++__first;
1863 __len = __len - __half - 1;
1864 }
1865 else if (__val < *__middle)
1866 __len = __half;
1867 else {
1868 __left = lower_bound(__first, __middle, __val);
1869 advance(__first, __len);
1870 __right = upper_bound(++__middle, __first, __val);
1871 return pair<_ForwardIter, _ForwardIter>(__left, __right);
1872 }
1873 }
1874 return pair<_ForwardIter, _ForwardIter>(__first, __first);
1875 }
1876
1877 template <class _ForwardIter, class _Tp>
1878 inline pair<_ForwardIter, _ForwardIter>
equal_range(_ForwardIter __first,_ForwardIter __last,const _Tp & __val)1879 equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) {
1880 return __equal_range(__first, __last, __val,
1881 __DISTANCE_TYPE(__first));
1882 }
1883
1884 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
1885 pair<_ForwardIter, _ForwardIter>
__equal_range(_ForwardIter __first,_ForwardIter __last,const _Tp & __val,_Compare __comp,_Distance *)1886 __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
1887 _Compare __comp, _Distance*)
1888 {
1889 _Distance __len = 0;
1890 distance(__first, __last, __len);
1891 _Distance __half;
1892 _ForwardIter __middle, __left, __right;
1893
1894 while (__len > 0) {
1895 __half = __len >> 1;
1896 __middle = __first;
1897 advance(__middle, __half);
1898 if (__comp(*__middle, __val)) {
1899 __first = __middle;
1900 ++__first;
1901 __len = __len - __half - 1;
1902 }
1903 else if (__comp(__val, *__middle))
1904 __len = __half;
1905 else {
1906 __left = lower_bound(__first, __middle, __val, __comp);
1907 advance(__first, __len);
1908 __right = upper_bound(++__middle, __first, __val, __comp);
1909 return pair<_ForwardIter, _ForwardIter>(__left, __right);
1910 }
1911 }
1912 return pair<_ForwardIter, _ForwardIter>(__first, __first);
1913 }
1914
1915 template <class _ForwardIter, class _Tp, class _Compare>
1916 inline pair<_ForwardIter, _ForwardIter>
equal_range(_ForwardIter __first,_ForwardIter __last,const _Tp & __val,_Compare __comp)1917 equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
1918 _Compare __comp) {
1919 return __equal_range(__first, __last, __val, __comp,
1920 __DISTANCE_TYPE(__first));
1921 }
1922
1923 template <class _ForwardIter, class _Tp>
binary_search(_ForwardIter __first,_ForwardIter __last,const _Tp & __val)1924 bool binary_search(_ForwardIter __first, _ForwardIter __last,
1925 const _Tp& __val) {
1926 _ForwardIter __i = lower_bound(__first, __last, __val);
1927 return __i != __last && !(__val < *__i);
1928 }
1929
1930 template <class _ForwardIter, class _Tp, class _Compare>
binary_search(_ForwardIter __first,_ForwardIter __last,const _Tp & __val,_Compare __comp)1931 bool binary_search(_ForwardIter __first, _ForwardIter __last,
1932 const _Tp& __val,
1933 _Compare __comp) {
1934 _ForwardIter __i = lower_bound(__first, __last, __val, __comp);
1935 return __i != __last && !__comp(__val, *__i);
1936 }
1937
1938 // merge, with and without an explicitly supplied comparison function.
1939
1940 template <class _InputIter1, class _InputIter2, class _OutputIter>
merge(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2,_OutputIter __result)1941 _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1,
1942 _InputIter2 __first2, _InputIter2 __last2,
1943 _OutputIter __result) {
1944 while (__first1 != __last1 && __first2 != __last2) {
1945 if (*__first2 < *__first1) {
1946 *__result = *__first2;
1947 ++__first2;
1948 }
1949 else {
1950 *__result = *__first1;
1951 ++__first1;
1952 }
1953 ++__result;
1954 }
1955 return copy(__first2, __last2, copy(__first1, __last1, __result));
1956 }
1957
1958 template <class _InputIter1, class _InputIter2, class _OutputIter,
1959 class _Compare>
merge(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2,_OutputIter __result,_Compare __comp)1960 _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1,
1961 _InputIter2 __first2, _InputIter2 __last2,
1962 _OutputIter __result, _Compare __comp) {
1963 while (__first1 != __last1 && __first2 != __last2) {
1964 if (__comp(*__first2, *__first1)) {
1965 *__result = *__first2;
1966 ++__first2;
1967 }
1968 else {
1969 *__result = *__first1;
1970 ++__first1;
1971 }
1972 ++__result;
1973 }
1974 return copy(__first2, __last2, copy(__first1, __last1, __result));
1975 }
1976
1977 // inplace_merge and its auxiliary functions.
1978
1979 template <class _BidirectionalIter, class _Distance>
__merge_without_buffer(_BidirectionalIter __first,_BidirectionalIter __middle,_BidirectionalIter __last,_Distance __len1,_Distance __len2)1980 void __merge_without_buffer(_BidirectionalIter __first,
1981 _BidirectionalIter __middle,
1982 _BidirectionalIter __last,
1983 _Distance __len1, _Distance __len2) {
1984 if (__len1 == 0 || __len2 == 0)
1985 return;
1986 if (__len1 + __len2 == 2) {
1987 if (*__middle < *__first)
1988 iter_swap(__first, __middle);
1989 return;
1990 }
1991 _BidirectionalIter __first_cut = __first;
1992 _BidirectionalIter __second_cut = __middle;
1993 _Distance __len11 = 0;
1994 _Distance __len22 = 0;
1995 if (__len1 > __len2) {
1996 __len11 = __len1 / 2;
1997 advance(__first_cut, __len11);
1998 __second_cut = lower_bound(__middle, __last, *__first_cut);
1999 distance(__middle, __second_cut, __len22);
2000 }
2001 else {
2002 __len22 = __len2 / 2;
2003 advance(__second_cut, __len22);
2004 __first_cut = upper_bound(__first, __middle, *__second_cut);
2005 distance(__first, __first_cut, __len11);
2006 }
2007 _BidirectionalIter __new_middle
2008 = rotate(__first_cut, __middle, __second_cut);
2009 __merge_without_buffer(__first, __first_cut, __new_middle,
2010 __len11, __len22);
2011 __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11,
2012 __len2 - __len22);
2013 }
2014
2015 template <class _BidirectionalIter, class _Distance, class _Compare>
__merge_without_buffer(_BidirectionalIter __first,_BidirectionalIter __middle,_BidirectionalIter __last,_Distance __len1,_Distance __len2,_Compare __comp)2016 void __merge_without_buffer(_BidirectionalIter __first,
2017 _BidirectionalIter __middle,
2018 _BidirectionalIter __last,
2019 _Distance __len1, _Distance __len2,
2020 _Compare __comp) {
2021 if (__len1 == 0 || __len2 == 0)
2022 return;
2023 if (__len1 + __len2 == 2) {
2024 if (__comp(*__middle, *__first))
2025 iter_swap(__first, __middle);
2026 return;
2027 }
2028 _BidirectionalIter __first_cut = __first;
2029 _BidirectionalIter __second_cut = __middle;
2030 _Distance __len11 = 0;
2031 _Distance __len22 = 0;
2032 if (__len1 > __len2) {
2033 __len11 = __len1 / 2;
2034 advance(__first_cut, __len11);
2035 __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
2036 distance(__middle, __second_cut, __len22);
2037 }
2038 else {
2039 __len22 = __len2 / 2;
2040 advance(__second_cut, __len22);
2041 __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
2042 distance(__first, __first_cut, __len11);
2043 }
2044 _BidirectionalIter __new_middle
2045 = rotate(__first_cut, __middle, __second_cut);
2046 __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22,
2047 __comp);
2048 __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11,
2049 __len2 - __len22, __comp);
2050 }
2051
2052 template <class _BidirectionalIter1, class _BidirectionalIter2,
2053 class _Distance>
__rotate_adaptive(_BidirectionalIter1 __first,_BidirectionalIter1 __middle,_BidirectionalIter1 __last,_Distance __len1,_Distance __len2,_BidirectionalIter2 __buffer,_Distance __buffer_size)2054 _BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first,
2055 _BidirectionalIter1 __middle,
2056 _BidirectionalIter1 __last,
2057 _Distance __len1, _Distance __len2,
2058 _BidirectionalIter2 __buffer,
2059 _Distance __buffer_size) {
2060 _BidirectionalIter2 __buffer_end;
2061 if (__len1 > __len2 && __len2 <= __buffer_size) {
2062 __buffer_end = copy(__middle, __last, __buffer);
2063 copy_backward(__first, __middle, __last);
2064 return copy(__buffer, __buffer_end, __first);
2065 }
2066 else if (__len1 <= __buffer_size) {
2067 __buffer_end = copy(__first, __middle, __buffer);
2068 copy(__middle, __last, __first);
2069 return copy_backward(__buffer, __buffer_end, __last);
2070 }
2071 else
2072 return rotate(__first, __middle, __last);
2073 }
2074
2075 template <class _BidirectionalIter1, class _BidirectionalIter2,
2076 class _BidirectionalIter3>
__merge_backward(_BidirectionalIter1 __first1,_BidirectionalIter1 __last1,_BidirectionalIter2 __first2,_BidirectionalIter2 __last2,_BidirectionalIter3 __result)2077 _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1,
2078 _BidirectionalIter1 __last1,
2079 _BidirectionalIter2 __first2,
2080 _BidirectionalIter2 __last2,
2081 _BidirectionalIter3 __result) {
2082 if (__first1 == __last1)
2083 return copy_backward(__first2, __last2, __result);
2084 if (__first2 == __last2)
2085 return copy_backward(__first1, __last1, __result);
2086 --__last1;
2087 --__last2;
2088 while (true) {
2089 if (*__last2 < *__last1) {
2090 *--__result = *__last1;
2091 if (__first1 == __last1)
2092 return copy_backward(__first2, ++__last2, __result);
2093 --__last1;
2094 }
2095 else {
2096 *--__result = *__last2;
2097 if (__first2 == __last2)
2098 return copy_backward(__first1, ++__last1, __result);
2099 --__last2;
2100 }
2101 }
2102 }
2103
2104 template <class _BidirectionalIter1, class _BidirectionalIter2,
2105 class _BidirectionalIter3, class _Compare>
__merge_backward(_BidirectionalIter1 __first1,_BidirectionalIter1 __last1,_BidirectionalIter2 __first2,_BidirectionalIter2 __last2,_BidirectionalIter3 __result,_Compare __comp)2106 _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1,
2107 _BidirectionalIter1 __last1,
2108 _BidirectionalIter2 __first2,
2109 _BidirectionalIter2 __last2,
2110 _BidirectionalIter3 __result,
2111 _Compare __comp) {
2112 if (__first1 == __last1)
2113 return copy_backward(__first2, __last2, __result);
2114 if (__first2 == __last2)
2115 return copy_backward(__first1, __last1, __result);
2116 --__last1;
2117 --__last2;
2118 while (true) {
2119 if (__comp(*__last2, *__last1)) {
2120 *--__result = *__last1;
2121 if (__first1 == __last1)
2122 return copy_backward(__first2, ++__last2, __result);
2123 --__last1;
2124 }
2125 else {
2126 *--__result = *__last2;
2127 if (__first2 == __last2)
2128 return copy_backward(__first1, ++__last1, __result);
2129 --__last2;
2130 }
2131 }
2132 }
2133
2134 template <class _BidirectionalIter, class _Distance, class _Pointer>
__merge_adaptive(_BidirectionalIter __first,_BidirectionalIter __middle,_BidirectionalIter __last,_Distance __len1,_Distance __len2,_Pointer __buffer,_Distance __buffer_size)2135 void __merge_adaptive(_BidirectionalIter __first,
2136 _BidirectionalIter __middle,
2137 _BidirectionalIter __last,
2138 _Distance __len1, _Distance __len2,
2139 _Pointer __buffer, _Distance __buffer_size) {
2140 if (__len1 <= __len2 && __len1 <= __buffer_size) {
2141 _Pointer __buffer_end = copy(__first, __middle, __buffer);
2142 merge(__buffer, __buffer_end, __middle, __last, __first);
2143 }
2144 else if (__len2 <= __buffer_size) {
2145 _Pointer __buffer_end = copy(__middle, __last, __buffer);
2146 __merge_backward(__first, __middle, __buffer, __buffer_end, __last);
2147 }
2148 else {
2149 _BidirectionalIter __first_cut = __first;
2150 _BidirectionalIter __second_cut = __middle;
2151 _Distance __len11 = 0;
2152 _Distance __len22 = 0;
2153 if (__len1 > __len2) {
2154 __len11 = __len1 / 2;
2155 advance(__first_cut, __len11);
2156 __second_cut = lower_bound(__middle, __last, *__first_cut);
2157 distance(__middle, __second_cut, __len22);
2158 }
2159 else {
2160 __len22 = __len2 / 2;
2161 advance(__second_cut, __len22);
2162 __first_cut = upper_bound(__first, __middle, *__second_cut);
2163 distance(__first, __first_cut, __len11);
2164 }
2165 _BidirectionalIter __new_middle =
2166 __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11,
2167 __len22, __buffer, __buffer_size);
2168 __merge_adaptive(__first, __first_cut, __new_middle, __len11,
2169 __len22, __buffer, __buffer_size);
2170 __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
2171 __len2 - __len22, __buffer, __buffer_size);
2172 }
2173 }
2174
2175 template <class _BidirectionalIter, class _Distance, class _Pointer,
2176 class _Compare>
__merge_adaptive(_BidirectionalIter __first,_BidirectionalIter __middle,_BidirectionalIter __last,_Distance __len1,_Distance __len2,_Pointer __buffer,_Distance __buffer_size,_Compare __comp)2177 void __merge_adaptive(_BidirectionalIter __first,
2178 _BidirectionalIter __middle,
2179 _BidirectionalIter __last,
2180 _Distance __len1, _Distance __len2,
2181 _Pointer __buffer, _Distance __buffer_size,
2182 _Compare __comp) {
2183 if (__len1 <= __len2 && __len1 <= __buffer_size) {
2184 _Pointer __buffer_end = copy(__first, __middle, __buffer);
2185 merge(__buffer, __buffer_end, __middle, __last, __first, __comp);
2186 }
2187 else if (__len2 <= __buffer_size) {
2188 _Pointer __buffer_end = copy(__middle, __last, __buffer);
2189 __merge_backward(__first, __middle, __buffer, __buffer_end, __last,
2190 __comp);
2191 }
2192 else {
2193 _BidirectionalIter __first_cut = __first;
2194 _BidirectionalIter __second_cut = __middle;
2195 _Distance __len11 = 0;
2196 _Distance __len22 = 0;
2197 if (__len1 > __len2) {
2198 __len11 = __len1 / 2;
2199 advance(__first_cut, __len11);
2200 __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
2201 distance(__middle, __second_cut, __len22);
2202 }
2203 else {
2204 __len22 = __len2 / 2;
2205 advance(__second_cut, __len22);
2206 __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
2207 distance(__first, __first_cut, __len11);
2208 }
2209 _BidirectionalIter __new_middle =
2210 __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11,
2211 __len22, __buffer, __buffer_size);
2212 __merge_adaptive(__first, __first_cut, __new_middle, __len11,
2213 __len22, __buffer, __buffer_size, __comp);
2214 __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
2215 __len2 - __len22, __buffer, __buffer_size, __comp);
2216 }
2217 }
2218
2219 template <class _BidirectionalIter, class _Tp, class _Distance>
__inplace_merge_aux(_BidirectionalIter __first,_BidirectionalIter __middle,_BidirectionalIter __last,_Tp *,_Distance *)2220 inline void __inplace_merge_aux(_BidirectionalIter __first,
2221 _BidirectionalIter __middle,
2222 _BidirectionalIter __last, _Tp*, _Distance*) {
2223 _Distance __len1 = 0;
2224 distance(__first, __middle, __len1);
2225 _Distance __len2 = 0;
2226 distance(__middle, __last, __len2);
2227
2228 _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last);
2229 if (__buf.begin() == 0)
2230 __merge_without_buffer(__first, __middle, __last, __len1, __len2);
2231 else
2232 __merge_adaptive(__first, __middle, __last, __len1, __len2,
2233 __buf.begin(), _Distance(__buf.size()));
2234 }
2235
2236 template <class _BidirectionalIter, class _Tp,
2237 class _Distance, class _Compare>
__inplace_merge_aux(_BidirectionalIter __first,_BidirectionalIter __middle,_BidirectionalIter __last,_Tp *,_Distance *,_Compare __comp)2238 inline void __inplace_merge_aux(_BidirectionalIter __first,
2239 _BidirectionalIter __middle,
2240 _BidirectionalIter __last, _Tp*, _Distance*,
2241 _Compare __comp) {
2242 _Distance __len1 = 0;
2243 distance(__first, __middle, __len1);
2244 _Distance __len2 = 0;
2245 distance(__middle, __last, __len2);
2246
2247 _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last);
2248 if (__buf.begin() == 0)
2249 __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp);
2250 else
2251 __merge_adaptive(__first, __middle, __last, __len1, __len2,
2252 __buf.begin(), _Distance(__buf.size()),
2253 __comp);
2254 }
2255
2256 template <class _BidirectionalIter>
inplace_merge(_BidirectionalIter __first,_BidirectionalIter __middle,_BidirectionalIter __last)2257 inline void inplace_merge(_BidirectionalIter __first,
2258 _BidirectionalIter __middle,
2259 _BidirectionalIter __last) {
2260 if (__first == __middle || __middle == __last)
2261 return;
2262 __inplace_merge_aux(__first, __middle, __last,
2263 __VALUE_TYPE(__first), __DISTANCE_TYPE(__first));
2264 }
2265
2266 template <class _BidirectionalIter, class _Compare>
inplace_merge(_BidirectionalIter __first,_BidirectionalIter __middle,_BidirectionalIter __last,_Compare __comp)2267 inline void inplace_merge(_BidirectionalIter __first,
2268 _BidirectionalIter __middle,
2269 _BidirectionalIter __last, _Compare __comp) {
2270 if (__first == __middle || __middle == __last)
2271 return;
2272 __inplace_merge_aux(__first, __middle, __last,
2273 __VALUE_TYPE(__first), __DISTANCE_TYPE(__first),
2274 __comp);
2275 }
2276
2277 // Set algorithms: includes, set_union, set_intersection, set_difference,
2278 // set_symmetric_difference. All of these algorithms have the precondition
2279 // that their input ranges are sorted and the postcondition that their output
2280 // ranges are sorted.
2281
2282 template <class _InputIter1, class _InputIter2>
includes(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2)2283 bool includes(_InputIter1 __first1, _InputIter1 __last1,
2284 _InputIter2 __first2, _InputIter2 __last2) {
2285 while (__first1 != __last1 && __first2 != __last2)
2286 if (*__first2 < *__first1)
2287 return false;
2288 else if(*__first1 < *__first2)
2289 ++__first1;
2290 else
2291 ++__first1, ++__first2;
2292
2293 return __first2 == __last2;
2294 }
2295
2296 template <class _InputIter1, class _InputIter2, class _Compare>
includes(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2,_Compare __comp)2297 bool includes(_InputIter1 __first1, _InputIter1 __last1,
2298 _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) {
2299 while (__first1 != __last1 && __first2 != __last2)
2300 if (__comp(*__first2, *__first1))
2301 return false;
2302 else if(__comp(*__first1, *__first2))
2303 ++__first1;
2304 else
2305 ++__first1, ++__first2;
2306
2307 return __first2 == __last2;
2308 }
2309
2310 template <class _InputIter1, class _InputIter2, class _OutputIter>
set_union(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2,_OutputIter __result)2311 _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1,
2312 _InputIter2 __first2, _InputIter2 __last2,
2313 _OutputIter __result) {
2314 while (__first1 != __last1 && __first2 != __last2) {
2315 if (*__first1 < *__first2) {
2316 *__result = *__first1;
2317 ++__first1;
2318 }
2319 else if (*__first2 < *__first1) {
2320 *__result = *__first2;
2321 ++__first2;
2322 }
2323 else {
2324 *__result = *__first1;
2325 ++__first1;
2326 ++__first2;
2327 }
2328 ++__result;
2329 }
2330 return copy(__first2, __last2, copy(__first1, __last1, __result));
2331 }
2332
2333 template <class _InputIter1, class _InputIter2, class _OutputIter,
2334 class _Compare>
set_union(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2,_OutputIter __result,_Compare __comp)2335 _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1,
2336 _InputIter2 __first2, _InputIter2 __last2,
2337 _OutputIter __result, _Compare __comp) {
2338 while (__first1 != __last1 && __first2 != __last2) {
2339 if (__comp(*__first1, *__first2)) {
2340 *__result = *__first1;
2341 ++__first1;
2342 }
2343 else if (__comp(*__first2, *__first1)) {
2344 *__result = *__first2;
2345 ++__first2;
2346 }
2347 else {
2348 *__result = *__first1;
2349 ++__first1;
2350 ++__first2;
2351 }
2352 ++__result;
2353 }
2354 return copy(__first2, __last2, copy(__first1, __last1, __result));
2355 }
2356
2357 template <class _InputIter1, class _InputIter2, class _OutputIter>
set_intersection(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2,_OutputIter __result)2358 _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1,
2359 _InputIter2 __first2, _InputIter2 __last2,
2360 _OutputIter __result) {
2361 while (__first1 != __last1 && __first2 != __last2)
2362 if (*__first1 < *__first2)
2363 ++__first1;
2364 else if (*__first2 < *__first1)
2365 ++__first2;
2366 else {
2367 *__result = *__first1;
2368 ++__first1;
2369 ++__first2;
2370 ++__result;
2371 }
2372 return __result;
2373 }
2374
2375 template <class _InputIter1, class _InputIter2, class _OutputIter,
2376 class _Compare>
set_intersection(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2,_OutputIter __result,_Compare __comp)2377 _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1,
2378 _InputIter2 __first2, _InputIter2 __last2,
2379 _OutputIter __result, _Compare __comp) {
2380 while (__first1 != __last1 && __first2 != __last2)
2381 if (__comp(*__first1, *__first2))
2382 ++__first1;
2383 else if (__comp(*__first2, *__first1))
2384 ++__first2;
2385 else {
2386 *__result = *__first1;
2387 ++__first1;
2388 ++__first2;
2389 ++__result;
2390 }
2391 return __result;
2392 }
2393
2394 template <class _InputIter1, class _InputIter2, class _OutputIter>
set_difference(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2,_OutputIter __result)2395 _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1,
2396 _InputIter2 __first2, _InputIter2 __last2,
2397 _OutputIter __result) {
2398 while (__first1 != __last1 && __first2 != __last2)
2399 if (*__first1 < *__first2) {
2400 *__result = *__first1;
2401 ++__first1;
2402 ++__result;
2403 }
2404 else if (*__first2 < *__first1)
2405 ++__first2;
2406 else {
2407 ++__first1;
2408 ++__first2;
2409 }
2410 return copy(__first1, __last1, __result);
2411 }
2412
2413 template <class _InputIter1, class _InputIter2, class _OutputIter,
2414 class _Compare>
set_difference(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2,_OutputIter __result,_Compare __comp)2415 _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1,
2416 _InputIter2 __first2, _InputIter2 __last2,
2417 _OutputIter __result, _Compare __comp) {
2418 while (__first1 != __last1 && __first2 != __last2)
2419 if (__comp(*__first1, *__first2)) {
2420 *__result = *__first1;
2421 ++__first1;
2422 ++__result;
2423 }
2424 else if (__comp(*__first2, *__first1))
2425 ++__first2;
2426 else {
2427 ++__first1;
2428 ++__first2;
2429 }
2430 return copy(__first1, __last1, __result);
2431 }
2432
2433 template <class _InputIter1, class _InputIter2, class _OutputIter>
2434 _OutputIter
set_symmetric_difference(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2,_OutputIter __result)2435 set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
2436 _InputIter2 __first2, _InputIter2 __last2,
2437 _OutputIter __result) {
2438 while (__first1 != __last1 && __first2 != __last2)
2439 if (*__first1 < *__first2) {
2440 *__result = *__first1;
2441 ++__first1;
2442 ++__result;
2443 }
2444 else if (*__first2 < *__first1) {
2445 *__result = *__first2;
2446 ++__first2;
2447 ++__result;
2448 }
2449 else {
2450 ++__first1;
2451 ++__first2;
2452 }
2453 return copy(__first2, __last2, copy(__first1, __last1, __result));
2454 }
2455
2456 template <class _InputIter1, class _InputIter2, class _OutputIter,
2457 class _Compare>
2458 _OutputIter
set_symmetric_difference(_InputIter1 __first1,_InputIter1 __last1,_InputIter2 __first2,_InputIter2 __last2,_OutputIter __result,_Compare __comp)2459 set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
2460 _InputIter2 __first2, _InputIter2 __last2,
2461 _OutputIter __result,
2462 _Compare __comp) {
2463 while (__first1 != __last1 && __first2 != __last2)
2464 if (__comp(*__first1, *__first2)) {
2465 *__result = *__first1;
2466 ++__first1;
2467 ++__result;
2468 }
2469 else if (__comp(*__first2, *__first1)) {
2470 *__result = *__first2;
2471 ++__first2;
2472 ++__result;
2473 }
2474 else {
2475 ++__first1;
2476 ++__first2;
2477 }
2478 return copy(__first2, __last2, copy(__first1, __last1, __result));
2479 }
2480
2481 // min_element and max_element, with and without an explicitly supplied
2482 // comparison function.
2483
2484 template <class _ForwardIter>
max_element(_ForwardIter __first,_ForwardIter __last)2485 _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) {
2486 if (__first == __last) return __first;
2487 _ForwardIter __result = __first;
2488 while (++__first != __last)
2489 if (*__result < *__first)
2490 __result = __first;
2491 return __result;
2492 }
2493
2494 template <class _ForwardIter, class _Compare>
max_element(_ForwardIter __first,_ForwardIter __last,_Compare __comp)2495 _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last,
2496 _Compare __comp) {
2497 if (__first == __last) return __first;
2498 _ForwardIter __result = __first;
2499 while (++__first != __last)
2500 if (__comp(*__result, *__first)) __result = __first;
2501 return __result;
2502 }
2503
2504 template <class _ForwardIter>
min_element(_ForwardIter __first,_ForwardIter __last)2505 _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) {
2506 if (__first == __last) return __first;
2507 _ForwardIter __result = __first;
2508 while (++__first != __last)
2509 if (*__first < *__result)
2510 __result = __first;
2511 return __result;
2512 }
2513
2514 template <class _ForwardIter, class _Compare>
min_element(_ForwardIter __first,_ForwardIter __last,_Compare __comp)2515 _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last,
2516 _Compare __comp) {
2517 if (__first == __last) return __first;
2518 _ForwardIter __result = __first;
2519 while (++__first != __last)
2520 if (__comp(*__first, *__result))
2521 __result = __first;
2522 return __result;
2523 }
2524
2525 // next_permutation and prev_permutation, with and without an explicitly
2526 // supplied comparison function.
2527
2528 template <class _BidirectionalIter>
next_permutation(_BidirectionalIter __first,_BidirectionalIter __last)2529 bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
2530 if (__first == __last)
2531 return false;
2532 _BidirectionalIter __i = __first;
2533 ++__i;
2534 if (__i == __last)
2535 return false;
2536 __i = __last;
2537 --__i;
2538
2539 for(;;) {
2540 _BidirectionalIter __ii = __i;
2541 --__i;
2542 if (*__i < *__ii) {
2543 _BidirectionalIter __j = __last;
2544 while (!(*__i < *--__j))
2545 {}
2546 iter_swap(__i, __j);
2547 reverse(__ii, __last);
2548 return true;
2549 }
2550 if (__i == __first) {
2551 reverse(__first, __last);
2552 return false;
2553 }
2554 }
2555 }
2556
2557 template <class _BidirectionalIter, class _Compare>
next_permutation(_BidirectionalIter __first,_BidirectionalIter __last,_Compare __comp)2558 bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
2559 _Compare __comp) {
2560 if (__first == __last)
2561 return false;
2562 _BidirectionalIter __i = __first;
2563 ++__i;
2564 if (__i == __last)
2565 return false;
2566 __i = __last;
2567 --__i;
2568
2569 for(;;) {
2570 _BidirectionalIter __ii = __i;
2571 --__i;
2572 if (__comp(*__i, *__ii)) {
2573 _BidirectionalIter __j = __last;
2574 while (!__comp(*__i, *--__j))
2575 {}
2576 iter_swap(__i, __j);
2577 reverse(__ii, __last);
2578 return true;
2579 }
2580 if (__i == __first) {
2581 reverse(__first, __last);
2582 return false;
2583 }
2584 }
2585 }
2586
2587 template <class _BidirectionalIter>
prev_permutation(_BidirectionalIter __first,_BidirectionalIter __last)2588 bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
2589 if (__first == __last)
2590 return false;
2591 _BidirectionalIter __i = __first;
2592 ++__i;
2593 if (__i == __last)
2594 return false;
2595 __i = __last;
2596 --__i;
2597
2598 for(;;) {
2599 _BidirectionalIter __ii = __i;
2600 --__i;
2601 if (*__ii < *__i) {
2602 _BidirectionalIter __j = __last;
2603 while (!(*--__j < *__i))
2604 {}
2605 iter_swap(__i, __j);
2606 reverse(__ii, __last);
2607 return true;
2608 }
2609 if (__i == __first) {
2610 reverse(__first, __last);
2611 return false;
2612 }
2613 }
2614 }
2615
2616 template <class _BidirectionalIter, class _Compare>
prev_permutation(_BidirectionalIter __first,_BidirectionalIter __last,_Compare __comp)2617 bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
2618 _Compare __comp) {
2619 if (__first == __last)
2620 return false;
2621 _BidirectionalIter __i = __first;
2622 ++__i;
2623 if (__i == __last)
2624 return false;
2625 __i = __last;
2626 --__i;
2627
2628 for(;;) {
2629 _BidirectionalIter __ii = __i;
2630 --__i;
2631 if (__comp(*__ii, *__i)) {
2632 _BidirectionalIter __j = __last;
2633 while (!__comp(*--__j, *__i))
2634 {}
2635 iter_swap(__i, __j);
2636 reverse(__ii, __last);
2637 return true;
2638 }
2639 if (__i == __first) {
2640 reverse(__first, __last);
2641 return false;
2642 }
2643 }
2644 }
2645
2646 // find_first_of, with and without an explicitly supplied comparison function.
2647
2648 template <class _InputIter, class _ForwardIter>
find_first_of(_InputIter __first1,_InputIter __last1,_ForwardIter __first2,_ForwardIter __last2)2649 _InputIter find_first_of(_InputIter __first1, _InputIter __last1,
2650 _ForwardIter __first2, _ForwardIter __last2)
2651 {
2652 for ( ; __first1 != __last1; ++__first1)
2653 for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter)
2654 if (*__first1 == *__iter)
2655 return __first1;
2656 return __last1;
2657 }
2658
2659 template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
find_first_of(_InputIter __first1,_InputIter __last1,_ForwardIter __first2,_ForwardIter __last2,_BinaryPredicate __comp)2660 _InputIter find_first_of(_InputIter __first1, _InputIter __last1,
2661 _ForwardIter __first2, _ForwardIter __last2,
2662 _BinaryPredicate __comp)
2663 {
2664 for ( ; __first1 != __last1; ++__first1)
2665 for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter)
2666 if (__comp(*__first1, *__iter))
2667 return __first1;
2668 return __last1;
2669 }
2670
2671
2672 // find_end, with and without an explicitly supplied comparison function.
2673 // Search [first2, last2) as a subsequence in [first1, last1), and return
2674 // the *last* possible match. Note that find_end for bidirectional iterators
2675 // is much faster than for forward iterators.
2676
2677 // find_end for forward iterators.
2678 template <class _ForwardIter1, class _ForwardIter2>
__find_end(_ForwardIter1 __first1,_ForwardIter1 __last1,_ForwardIter2 __first2,_ForwardIter2 __last2,forward_iterator_tag,forward_iterator_tag)2679 _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
2680 _ForwardIter2 __first2, _ForwardIter2 __last2,
2681 forward_iterator_tag, forward_iterator_tag)
2682 {
2683 if (__first2 == __last2)
2684 return __last1;
2685 else {
2686 _ForwardIter1 __result = __last1;
2687 while (1) {
2688 _ForwardIter1 __new_result
2689 = search(__first1, __last1, __first2, __last2);
2690 if (__new_result == __last1)
2691 return __result;
2692 else {
2693 __result = __new_result;
2694 __first1 = __new_result;
2695 ++__first1;
2696 }
2697 }
2698 }
2699 }
2700
2701 template <class _ForwardIter1, class _ForwardIter2,
2702 class _BinaryPredicate>
__find_end(_ForwardIter1 __first1,_ForwardIter1 __last1,_ForwardIter2 __first2,_ForwardIter2 __last2,forward_iterator_tag,forward_iterator_tag,_BinaryPredicate __comp)2703 _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
2704 _ForwardIter2 __first2, _ForwardIter2 __last2,
2705 forward_iterator_tag, forward_iterator_tag,
2706 _BinaryPredicate __comp)
2707 {
2708 if (__first2 == __last2)
2709 return __last1;
2710 else {
2711 _ForwardIter1 __result = __last1;
2712 while (1) {
2713 _ForwardIter1 __new_result
2714 = search(__first1, __last1, __first2, __last2, __comp);
2715 if (__new_result == __last1)
2716 return __result;
2717 else {
2718 __result = __new_result;
2719 __first1 = __new_result;
2720 ++__first1;
2721 }
2722 }
2723 }
2724 }
2725
2726 // find_end for bidirectional iterators. Requires partial specialization.
2727 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
2728
2729 template <class _BidirectionalIter1, class _BidirectionalIter2>
2730 _BidirectionalIter1
__find_end(_BidirectionalIter1 __first1,_BidirectionalIter1 __last1,_BidirectionalIter2 __first2,_BidirectionalIter2 __last2,bidirectional_iterator_tag,bidirectional_iterator_tag)2731 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
2732 _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
2733 bidirectional_iterator_tag, bidirectional_iterator_tag)
2734 {
2735 typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
2736 typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
2737
2738 _RevIter1 __rlast1(__first1);
2739 _RevIter2 __rlast2(__first2);
2740 _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
2741 _RevIter2(__last2), __rlast2);
2742
2743 if (__rresult == __rlast1)
2744 return __last1;
2745 else {
2746 _BidirectionalIter1 __result = __rresult.base();
2747 advance(__result, -distance(__first2, __last2));
2748 return __result;
2749 }
2750 }
2751
2752 template <class _BidirectionalIter1, class _BidirectionalIter2,
2753 class _BinaryPredicate>
2754 _BidirectionalIter1
__find_end(_BidirectionalIter1 __first1,_BidirectionalIter1 __last1,_BidirectionalIter2 __first2,_BidirectionalIter2 __last2,bidirectional_iterator_tag,bidirectional_iterator_tag,_BinaryPredicate __comp)2755 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
2756 _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
2757 bidirectional_iterator_tag, bidirectional_iterator_tag,
2758 _BinaryPredicate __comp)
2759 {
2760 typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
2761 typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
2762
2763 _RevIter1 __rlast1(__first1);
2764 _RevIter2 __rlast2(__first2);
2765 _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
2766 _RevIter2(__last2), __rlast2,
2767 __comp);
2768
2769 if (__rresult == __rlast1)
2770 return __last1;
2771 else {
2772 _BidirectionalIter1 __result = __rresult.base();
2773 advance(__result, -distance(__first2, __last2));
2774 return __result;
2775 }
2776 }
2777 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
2778
2779 // Dispatching functions for find_end.
2780
2781 template <class _ForwardIter1, class _ForwardIter2>
2782 inline _ForwardIter1
find_end(_ForwardIter1 __first1,_ForwardIter1 __last1,_ForwardIter2 __first2,_ForwardIter2 __last2)2783 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
2784 _ForwardIter2 __first2, _ForwardIter2 __last2)
2785 {
2786 return __find_end(__first1, __last1, __first2, __last2,
2787 __ITERATOR_CATEGORY(__first1),
2788 __ITERATOR_CATEGORY(__first2));
2789 }
2790
2791 template <class _ForwardIter1, class _ForwardIter2,
2792 class _BinaryPredicate>
2793 inline _ForwardIter1
find_end(_ForwardIter1 __first1,_ForwardIter1 __last1,_ForwardIter2 __first2,_ForwardIter2 __last2,_BinaryPredicate __comp)2794 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
2795 _ForwardIter2 __first2, _ForwardIter2 __last2,
2796 _BinaryPredicate __comp)
2797 {
2798 return __find_end(__first1, __last1, __first2, __last2,
2799 __ITERATOR_CATEGORY(__first1),
2800 __ITERATOR_CATEGORY(__first2),
2801 __comp);
2802 }
2803
2804 // is_heap, a predicate testing whether or not a range is
2805 // a heap. This function is an extension, not part of the C++
2806 // standard.
2807
2808 template <class _RandomAccessIter, class _Distance>
__is_heap(_RandomAccessIter __first,_Distance __n)2809 bool __is_heap(_RandomAccessIter __first, _Distance __n)
2810 {
2811 _Distance __parent = 0;
2812 for (_Distance __child = 1; __child < __n; ++__child) {
2813 if (__first[__parent] < __first[__child])
2814 return false;
2815 if ((__child & 1) == 0)
2816 ++__parent;
2817 }
2818 return true;
2819 }
2820
2821 template <class _RandomAccessIter, class _Distance, class _StrictWeakOrdering>
__is_heap(_RandomAccessIter __first,_StrictWeakOrdering __comp,_Distance __n)2822 bool __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp,
2823 _Distance __n)
2824 {
2825 _Distance __parent = 0;
2826 for (_Distance __child = 1; __child < __n; ++__child) {
2827 if (__comp(__first[__parent], __first[__child]))
2828 return false;
2829 if ((__child & 1) == 0)
2830 ++__parent;
2831 }
2832 return true;
2833 }
2834
2835 template <class _RandomAccessIter>
is_heap(_RandomAccessIter __first,_RandomAccessIter __last)2836 inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last)
2837 {
2838 return __is_heap(__first, __last - __first);
2839 }
2840
2841
2842 template <class _RandomAccessIter, class _StrictWeakOrdering>
is_heap(_RandomAccessIter __first,_RandomAccessIter __last,_StrictWeakOrdering __comp)2843 inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last,
2844 _StrictWeakOrdering __comp)
2845 {
2846 return __is_heap(__first, __comp, __last - __first);
2847 }
2848
2849 // is_sorted, a predicated testing whether a range is sorted in
2850 // nondescending order. This is an extension, not part of the C++
2851 // standard.
2852
2853 template <class _ForwardIter>
is_sorted(_ForwardIter __first,_ForwardIter __last)2854 bool is_sorted(_ForwardIter __first, _ForwardIter __last)
2855 {
2856 if (__first == __last)
2857 return true;
2858
2859 _ForwardIter __next = __first;
2860 for (++__next; __next != __last; __first = __next, ++__next) {
2861 if (*__next < *__first)
2862 return false;
2863 }
2864
2865 return true;
2866 }
2867
2868 template <class _ForwardIter, class _StrictWeakOrdering>
is_sorted(_ForwardIter __first,_ForwardIter __last,_StrictWeakOrdering __comp)2869 bool is_sorted(_ForwardIter __first, _ForwardIter __last,
2870 _StrictWeakOrdering __comp)
2871 {
2872 if (__first == __last)
2873 return true;
2874
2875 _ForwardIter __next = __first;
2876 for (++__next; __next != __last; __first = __next, ++__next) {
2877 if (__comp(*__next, *__first))
2878 return false;
2879 }
2880
2881 return true;
2882 }
2883
2884 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
2885 #pragma reset woff 1209
2886 #endif
2887
2888 __STL_END_NAMESPACE
2889
2890 #endif /* __SGI_STL_INTERNAL_ALGO_H */
2891
2892 // Local Variables:
2893 // mode:C++
2894 // End:
2895