xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/bits/stl_algo.h (revision e4b17023d31ea40e02fa06b141db27753ecc6934)
1*e4b17023SJohn Marino // Algorithm implementation -*- C++ -*-
2*e4b17023SJohn Marino 
3*e4b17023SJohn Marino // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
4*e4b17023SJohn Marino // 2010, 2011
5*e4b17023SJohn Marino // Free Software Foundation, Inc.
6*e4b17023SJohn Marino //
7*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library.  This library is free
8*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
9*e4b17023SJohn Marino // terms of the GNU General Public License as published by the
10*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
11*e4b17023SJohn Marino // any later version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
14*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
15*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*e4b17023SJohn Marino // GNU General Public License for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
19*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
20*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
23*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
24*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
26*e4b17023SJohn Marino 
27*e4b17023SJohn Marino /*
28*e4b17023SJohn Marino  *
29*e4b17023SJohn Marino  * Copyright (c) 1994
30*e4b17023SJohn Marino  * Hewlett-Packard Company
31*e4b17023SJohn Marino  *
32*e4b17023SJohn Marino  * Permission to use, copy, modify, distribute and sell this software
33*e4b17023SJohn Marino  * and its documentation for any purpose is hereby granted without fee,
34*e4b17023SJohn Marino  * provided that the above copyright notice appear in all copies and
35*e4b17023SJohn Marino  * that both that copyright notice and this permission notice appear
36*e4b17023SJohn Marino  * in supporting documentation.  Hewlett-Packard Company makes no
37*e4b17023SJohn Marino  * representations about the suitability of this software for any
38*e4b17023SJohn Marino  * purpose.  It is provided "as is" without express or implied warranty.
39*e4b17023SJohn Marino  *
40*e4b17023SJohn Marino  *
41*e4b17023SJohn Marino  * Copyright (c) 1996
42*e4b17023SJohn Marino  * Silicon Graphics Computer Systems, Inc.
43*e4b17023SJohn Marino  *
44*e4b17023SJohn Marino  * Permission to use, copy, modify, distribute and sell this software
45*e4b17023SJohn Marino  * and its documentation for any purpose is hereby granted without fee,
46*e4b17023SJohn Marino  * provided that the above copyright notice appear in all copies and
47*e4b17023SJohn Marino  * that both that copyright notice and this permission notice appear
48*e4b17023SJohn Marino  * in supporting documentation.  Silicon Graphics makes no
49*e4b17023SJohn Marino  * representations about the suitability of this software for any
50*e4b17023SJohn Marino  * purpose.  It is provided "as is" without express or implied warranty.
51*e4b17023SJohn Marino  */
52*e4b17023SJohn Marino 
53*e4b17023SJohn Marino /** @file bits/stl_algo.h
54*e4b17023SJohn Marino  *  This is an internal header file, included by other library headers.
55*e4b17023SJohn Marino  *  Do not attempt to use it directly. @headername{algorithm}
56*e4b17023SJohn Marino  */
57*e4b17023SJohn Marino 
58*e4b17023SJohn Marino #ifndef _STL_ALGO_H
59*e4b17023SJohn Marino #define _STL_ALGO_H 1
60*e4b17023SJohn Marino 
61*e4b17023SJohn Marino #include <cstdlib>             // for rand
62*e4b17023SJohn Marino #include <bits/algorithmfwd.h>
63*e4b17023SJohn Marino #include <bits/stl_heap.h>
64*e4b17023SJohn Marino #include <bits/stl_tempbuf.h>  // for _Temporary_buffer
65*e4b17023SJohn Marino 
66*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
67*e4b17023SJohn Marino #include <random>     // for std::uniform_int_distribution
68*e4b17023SJohn Marino #include <functional> // for std::bind
69*e4b17023SJohn Marino #endif
70*e4b17023SJohn Marino 
71*e4b17023SJohn Marino // See concept_check.h for the __glibcxx_*_requires macros.
72*e4b17023SJohn Marino 
73*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
74*e4b17023SJohn Marino {
75*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
76*e4b17023SJohn Marino 
77*e4b17023SJohn Marino   /// Swaps the median value of *__a, *__b and *__c to *__a
78*e4b17023SJohn Marino   template<typename _Iterator>
79*e4b17023SJohn Marino     void
80*e4b17023SJohn Marino     __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c)
81*e4b17023SJohn Marino     {
82*e4b17023SJohn Marino       // concept requirements
83*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<
84*e4b17023SJohn Marino 	    typename iterator_traits<_Iterator>::value_type>)
85*e4b17023SJohn Marino 
86*e4b17023SJohn Marino       if (*__a < *__b)
87*e4b17023SJohn Marino 	{
88*e4b17023SJohn Marino 	  if (*__b < *__c)
89*e4b17023SJohn Marino 	    std::iter_swap(__a, __b);
90*e4b17023SJohn Marino 	  else if (*__a < *__c)
91*e4b17023SJohn Marino 	    std::iter_swap(__a, __c);
92*e4b17023SJohn Marino 	}
93*e4b17023SJohn Marino       else if (*__a < *__c)
94*e4b17023SJohn Marino 	return;
95*e4b17023SJohn Marino       else if (*__b < *__c)
96*e4b17023SJohn Marino 	std::iter_swap(__a, __c);
97*e4b17023SJohn Marino       else
98*e4b17023SJohn Marino 	std::iter_swap(__a, __b);
99*e4b17023SJohn Marino     }
100*e4b17023SJohn Marino 
101*e4b17023SJohn Marino   /// Swaps the median value of *__a, *__b and *__c under __comp to *__a
102*e4b17023SJohn Marino   template<typename _Iterator, typename _Compare>
103*e4b17023SJohn Marino     void
104*e4b17023SJohn Marino     __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c,
105*e4b17023SJohn Marino 			_Compare __comp)
106*e4b17023SJohn Marino     {
107*e4b17023SJohn Marino       // concept requirements
108*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool,
109*e4b17023SJohn Marino 	    typename iterator_traits<_Iterator>::value_type,
110*e4b17023SJohn Marino 	    typename iterator_traits<_Iterator>::value_type>)
111*e4b17023SJohn Marino 
112*e4b17023SJohn Marino       if (__comp(*__a, *__b))
113*e4b17023SJohn Marino 	{
114*e4b17023SJohn Marino 	  if (__comp(*__b, *__c))
115*e4b17023SJohn Marino 	    std::iter_swap(__a, __b);
116*e4b17023SJohn Marino 	  else if (__comp(*__a, *__c))
117*e4b17023SJohn Marino 	    std::iter_swap(__a, __c);
118*e4b17023SJohn Marino 	}
119*e4b17023SJohn Marino       else if (__comp(*__a, *__c))
120*e4b17023SJohn Marino 	return;
121*e4b17023SJohn Marino       else if (__comp(*__b, *__c))
122*e4b17023SJohn Marino 	std::iter_swap(__a, __c);
123*e4b17023SJohn Marino       else
124*e4b17023SJohn Marino 	std::iter_swap(__a, __b);
125*e4b17023SJohn Marino     }
126*e4b17023SJohn Marino 
127*e4b17023SJohn Marino   // for_each
128*e4b17023SJohn Marino 
129*e4b17023SJohn Marino   /// This is an overload used by find() for the Input Iterator case.
130*e4b17023SJohn Marino   template<typename _InputIterator, typename _Tp>
131*e4b17023SJohn Marino     inline _InputIterator
132*e4b17023SJohn Marino     __find(_InputIterator __first, _InputIterator __last,
133*e4b17023SJohn Marino 	   const _Tp& __val, input_iterator_tag)
134*e4b17023SJohn Marino     {
135*e4b17023SJohn Marino       while (__first != __last && !(*__first == __val))
136*e4b17023SJohn Marino 	++__first;
137*e4b17023SJohn Marino       return __first;
138*e4b17023SJohn Marino     }
139*e4b17023SJohn Marino 
140*e4b17023SJohn Marino   /// This is an overload used by find_if() for the Input Iterator case.
141*e4b17023SJohn Marino   template<typename _InputIterator, typename _Predicate>
142*e4b17023SJohn Marino     inline _InputIterator
143*e4b17023SJohn Marino     __find_if(_InputIterator __first, _InputIterator __last,
144*e4b17023SJohn Marino 	      _Predicate __pred, input_iterator_tag)
145*e4b17023SJohn Marino     {
146*e4b17023SJohn Marino       while (__first != __last && !bool(__pred(*__first)))
147*e4b17023SJohn Marino 	++__first;
148*e4b17023SJohn Marino       return __first;
149*e4b17023SJohn Marino     }
150*e4b17023SJohn Marino 
151*e4b17023SJohn Marino   /// This is an overload used by find() for the RAI case.
152*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Tp>
153*e4b17023SJohn Marino     _RandomAccessIterator
154*e4b17023SJohn Marino     __find(_RandomAccessIterator __first, _RandomAccessIterator __last,
155*e4b17023SJohn Marino 	   const _Tp& __val, random_access_iterator_tag)
156*e4b17023SJohn Marino     {
157*e4b17023SJohn Marino       typename iterator_traits<_RandomAccessIterator>::difference_type
158*e4b17023SJohn Marino 	__trip_count = (__last - __first) >> 2;
159*e4b17023SJohn Marino 
160*e4b17023SJohn Marino       for (; __trip_count > 0; --__trip_count)
161*e4b17023SJohn Marino 	{
162*e4b17023SJohn Marino 	  if (*__first == __val)
163*e4b17023SJohn Marino 	    return __first;
164*e4b17023SJohn Marino 	  ++__first;
165*e4b17023SJohn Marino 
166*e4b17023SJohn Marino 	  if (*__first == __val)
167*e4b17023SJohn Marino 	    return __first;
168*e4b17023SJohn Marino 	  ++__first;
169*e4b17023SJohn Marino 
170*e4b17023SJohn Marino 	  if (*__first == __val)
171*e4b17023SJohn Marino 	    return __first;
172*e4b17023SJohn Marino 	  ++__first;
173*e4b17023SJohn Marino 
174*e4b17023SJohn Marino 	  if (*__first == __val)
175*e4b17023SJohn Marino 	    return __first;
176*e4b17023SJohn Marino 	  ++__first;
177*e4b17023SJohn Marino 	}
178*e4b17023SJohn Marino 
179*e4b17023SJohn Marino       switch (__last - __first)
180*e4b17023SJohn Marino 	{
181*e4b17023SJohn Marino 	case 3:
182*e4b17023SJohn Marino 	  if (*__first == __val)
183*e4b17023SJohn Marino 	    return __first;
184*e4b17023SJohn Marino 	  ++__first;
185*e4b17023SJohn Marino 	case 2:
186*e4b17023SJohn Marino 	  if (*__first == __val)
187*e4b17023SJohn Marino 	    return __first;
188*e4b17023SJohn Marino 	  ++__first;
189*e4b17023SJohn Marino 	case 1:
190*e4b17023SJohn Marino 	  if (*__first == __val)
191*e4b17023SJohn Marino 	    return __first;
192*e4b17023SJohn Marino 	  ++__first;
193*e4b17023SJohn Marino 	case 0:
194*e4b17023SJohn Marino 	default:
195*e4b17023SJohn Marino 	  return __last;
196*e4b17023SJohn Marino 	}
197*e4b17023SJohn Marino     }
198*e4b17023SJohn Marino 
199*e4b17023SJohn Marino   /// This is an overload used by find_if() for the RAI case.
200*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Predicate>
201*e4b17023SJohn Marino     _RandomAccessIterator
202*e4b17023SJohn Marino     __find_if(_RandomAccessIterator __first, _RandomAccessIterator __last,
203*e4b17023SJohn Marino 	      _Predicate __pred, random_access_iterator_tag)
204*e4b17023SJohn Marino     {
205*e4b17023SJohn Marino       typename iterator_traits<_RandomAccessIterator>::difference_type
206*e4b17023SJohn Marino 	__trip_count = (__last - __first) >> 2;
207*e4b17023SJohn Marino 
208*e4b17023SJohn Marino       for (; __trip_count > 0; --__trip_count)
209*e4b17023SJohn Marino 	{
210*e4b17023SJohn Marino 	  if (__pred(*__first))
211*e4b17023SJohn Marino 	    return __first;
212*e4b17023SJohn Marino 	  ++__first;
213*e4b17023SJohn Marino 
214*e4b17023SJohn Marino 	  if (__pred(*__first))
215*e4b17023SJohn Marino 	    return __first;
216*e4b17023SJohn Marino 	  ++__first;
217*e4b17023SJohn Marino 
218*e4b17023SJohn Marino 	  if (__pred(*__first))
219*e4b17023SJohn Marino 	    return __first;
220*e4b17023SJohn Marino 	  ++__first;
221*e4b17023SJohn Marino 
222*e4b17023SJohn Marino 	  if (__pred(*__first))
223*e4b17023SJohn Marino 	    return __first;
224*e4b17023SJohn Marino 	  ++__first;
225*e4b17023SJohn Marino 	}
226*e4b17023SJohn Marino 
227*e4b17023SJohn Marino       switch (__last - __first)
228*e4b17023SJohn Marino 	{
229*e4b17023SJohn Marino 	case 3:
230*e4b17023SJohn Marino 	  if (__pred(*__first))
231*e4b17023SJohn Marino 	    return __first;
232*e4b17023SJohn Marino 	  ++__first;
233*e4b17023SJohn Marino 	case 2:
234*e4b17023SJohn Marino 	  if (__pred(*__first))
235*e4b17023SJohn Marino 	    return __first;
236*e4b17023SJohn Marino 	  ++__first;
237*e4b17023SJohn Marino 	case 1:
238*e4b17023SJohn Marino 	  if (__pred(*__first))
239*e4b17023SJohn Marino 	    return __first;
240*e4b17023SJohn Marino 	  ++__first;
241*e4b17023SJohn Marino 	case 0:
242*e4b17023SJohn Marino 	default:
243*e4b17023SJohn Marino 	  return __last;
244*e4b17023SJohn Marino 	}
245*e4b17023SJohn Marino     }
246*e4b17023SJohn Marino 
247*e4b17023SJohn Marino   /// This is an overload used by find_if_not() for the Input Iterator case.
248*e4b17023SJohn Marino   template<typename _InputIterator, typename _Predicate>
249*e4b17023SJohn Marino     inline _InputIterator
250*e4b17023SJohn Marino     __find_if_not(_InputIterator __first, _InputIterator __last,
251*e4b17023SJohn Marino 		  _Predicate __pred, input_iterator_tag)
252*e4b17023SJohn Marino     {
253*e4b17023SJohn Marino       while (__first != __last && bool(__pred(*__first)))
254*e4b17023SJohn Marino 	++__first;
255*e4b17023SJohn Marino       return __first;
256*e4b17023SJohn Marino     }
257*e4b17023SJohn Marino 
258*e4b17023SJohn Marino   /// This is an overload used by find_if_not() for the RAI case.
259*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Predicate>
260*e4b17023SJohn Marino     _RandomAccessIterator
261*e4b17023SJohn Marino     __find_if_not(_RandomAccessIterator __first, _RandomAccessIterator __last,
262*e4b17023SJohn Marino 		  _Predicate __pred, random_access_iterator_tag)
263*e4b17023SJohn Marino     {
264*e4b17023SJohn Marino       typename iterator_traits<_RandomAccessIterator>::difference_type
265*e4b17023SJohn Marino 	__trip_count = (__last - __first) >> 2;
266*e4b17023SJohn Marino 
267*e4b17023SJohn Marino       for (; __trip_count > 0; --__trip_count)
268*e4b17023SJohn Marino 	{
269*e4b17023SJohn Marino 	  if (!bool(__pred(*__first)))
270*e4b17023SJohn Marino 	    return __first;
271*e4b17023SJohn Marino 	  ++__first;
272*e4b17023SJohn Marino 
273*e4b17023SJohn Marino 	  if (!bool(__pred(*__first)))
274*e4b17023SJohn Marino 	    return __first;
275*e4b17023SJohn Marino 	  ++__first;
276*e4b17023SJohn Marino 
277*e4b17023SJohn Marino 	  if (!bool(__pred(*__first)))
278*e4b17023SJohn Marino 	    return __first;
279*e4b17023SJohn Marino 	  ++__first;
280*e4b17023SJohn Marino 
281*e4b17023SJohn Marino 	  if (!bool(__pred(*__first)))
282*e4b17023SJohn Marino 	    return __first;
283*e4b17023SJohn Marino 	  ++__first;
284*e4b17023SJohn Marino 	}
285*e4b17023SJohn Marino 
286*e4b17023SJohn Marino       switch (__last - __first)
287*e4b17023SJohn Marino 	{
288*e4b17023SJohn Marino 	case 3:
289*e4b17023SJohn Marino 	  if (!bool(__pred(*__first)))
290*e4b17023SJohn Marino 	    return __first;
291*e4b17023SJohn Marino 	  ++__first;
292*e4b17023SJohn Marino 	case 2:
293*e4b17023SJohn Marino 	  if (!bool(__pred(*__first)))
294*e4b17023SJohn Marino 	    return __first;
295*e4b17023SJohn Marino 	  ++__first;
296*e4b17023SJohn Marino 	case 1:
297*e4b17023SJohn Marino 	  if (!bool(__pred(*__first)))
298*e4b17023SJohn Marino 	    return __first;
299*e4b17023SJohn Marino 	  ++__first;
300*e4b17023SJohn Marino 	case 0:
301*e4b17023SJohn Marino 	default:
302*e4b17023SJohn Marino 	  return __last;
303*e4b17023SJohn Marino 	}
304*e4b17023SJohn Marino     }
305*e4b17023SJohn Marino 
306*e4b17023SJohn Marino   /// Provided for stable_partition to use.
307*e4b17023SJohn Marino   template<typename _InputIterator, typename _Predicate>
308*e4b17023SJohn Marino     inline _InputIterator
309*e4b17023SJohn Marino     __find_if_not(_InputIterator __first, _InputIterator __last,
310*e4b17023SJohn Marino 		  _Predicate __pred)
311*e4b17023SJohn Marino     {
312*e4b17023SJohn Marino       return std::__find_if_not(__first, __last, __pred,
313*e4b17023SJohn Marino 				std::__iterator_category(__first));
314*e4b17023SJohn Marino     }
315*e4b17023SJohn Marino 
316*e4b17023SJohn Marino   /// Like find_if_not(), but uses and updates a count of the
317*e4b17023SJohn Marino   /// remaining range length instead of comparing against an end
318*e4b17023SJohn Marino   /// iterator.
319*e4b17023SJohn Marino   template<typename _InputIterator, typename _Predicate, typename _Distance>
320*e4b17023SJohn Marino     _InputIterator
321*e4b17023SJohn Marino     __find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate __pred)
322*e4b17023SJohn Marino     {
323*e4b17023SJohn Marino       for (; __len; --__len, ++__first)
324*e4b17023SJohn Marino 	if (!bool(__pred(*__first)))
325*e4b17023SJohn Marino 	  break;
326*e4b17023SJohn Marino       return __first;
327*e4b17023SJohn Marino     }
328*e4b17023SJohn Marino 
329*e4b17023SJohn Marino   // set_difference
330*e4b17023SJohn Marino   // set_intersection
331*e4b17023SJohn Marino   // set_symmetric_difference
332*e4b17023SJohn Marino   // set_union
333*e4b17023SJohn Marino   // for_each
334*e4b17023SJohn Marino   // find
335*e4b17023SJohn Marino   // find_if
336*e4b17023SJohn Marino   // find_first_of
337*e4b17023SJohn Marino   // adjacent_find
338*e4b17023SJohn Marino   // count
339*e4b17023SJohn Marino   // count_if
340*e4b17023SJohn Marino   // search
341*e4b17023SJohn Marino 
342*e4b17023SJohn Marino   /**
343*e4b17023SJohn Marino    *  This is an uglified
344*e4b17023SJohn Marino    *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&)
345*e4b17023SJohn Marino    *  overloaded for forward iterators.
346*e4b17023SJohn Marino   */
347*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Integer, typename _Tp>
348*e4b17023SJohn Marino     _ForwardIterator
349*e4b17023SJohn Marino     __search_n(_ForwardIterator __first, _ForwardIterator __last,
350*e4b17023SJohn Marino 	       _Integer __count, const _Tp& __val,
351*e4b17023SJohn Marino 	       std::forward_iterator_tag)
352*e4b17023SJohn Marino     {
353*e4b17023SJohn Marino       __first = _GLIBCXX_STD_A::find(__first, __last, __val);
354*e4b17023SJohn Marino       while (__first != __last)
355*e4b17023SJohn Marino 	{
356*e4b17023SJohn Marino 	  typename iterator_traits<_ForwardIterator>::difference_type
357*e4b17023SJohn Marino 	    __n = __count;
358*e4b17023SJohn Marino 	  _ForwardIterator __i = __first;
359*e4b17023SJohn Marino 	  ++__i;
360*e4b17023SJohn Marino 	  while (__i != __last && __n != 1 && *__i == __val)
361*e4b17023SJohn Marino 	    {
362*e4b17023SJohn Marino 	      ++__i;
363*e4b17023SJohn Marino 	      --__n;
364*e4b17023SJohn Marino 	    }
365*e4b17023SJohn Marino 	  if (__n == 1)
366*e4b17023SJohn Marino 	    return __first;
367*e4b17023SJohn Marino 	  if (__i == __last)
368*e4b17023SJohn Marino 	    return __last;
369*e4b17023SJohn Marino 	  __first = _GLIBCXX_STD_A::find(++__i, __last, __val);
370*e4b17023SJohn Marino 	}
371*e4b17023SJohn Marino       return __last;
372*e4b17023SJohn Marino     }
373*e4b17023SJohn Marino 
374*e4b17023SJohn Marino   /**
375*e4b17023SJohn Marino    *  This is an uglified
376*e4b17023SJohn Marino    *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&)
377*e4b17023SJohn Marino    *  overloaded for random access iterators.
378*e4b17023SJohn Marino   */
379*e4b17023SJohn Marino   template<typename _RandomAccessIter, typename _Integer, typename _Tp>
380*e4b17023SJohn Marino     _RandomAccessIter
381*e4b17023SJohn Marino     __search_n(_RandomAccessIter __first, _RandomAccessIter __last,
382*e4b17023SJohn Marino 	       _Integer __count, const _Tp& __val,
383*e4b17023SJohn Marino 	       std::random_access_iterator_tag)
384*e4b17023SJohn Marino     {
385*e4b17023SJohn Marino 
386*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
387*e4b17023SJohn Marino 	_DistanceType;
388*e4b17023SJohn Marino 
389*e4b17023SJohn Marino       _DistanceType __tailSize = __last - __first;
390*e4b17023SJohn Marino       const _DistanceType __pattSize = __count;
391*e4b17023SJohn Marino 
392*e4b17023SJohn Marino       if (__tailSize < __pattSize)
393*e4b17023SJohn Marino         return __last;
394*e4b17023SJohn Marino 
395*e4b17023SJohn Marino       const _DistanceType __skipOffset = __pattSize - 1;
396*e4b17023SJohn Marino       _RandomAccessIter __lookAhead = __first + __skipOffset;
397*e4b17023SJohn Marino       __tailSize -= __pattSize;
398*e4b17023SJohn Marino 
399*e4b17023SJohn Marino       while (1) // the main loop...
400*e4b17023SJohn Marino 	{
401*e4b17023SJohn Marino 	  // __lookAhead here is always pointing to the last element of next
402*e4b17023SJohn Marino 	  // possible match.
403*e4b17023SJohn Marino 	  while (!(*__lookAhead == __val)) // the skip loop...
404*e4b17023SJohn Marino 	    {
405*e4b17023SJohn Marino 	      if (__tailSize < __pattSize)
406*e4b17023SJohn Marino 		return __last;  // Failure
407*e4b17023SJohn Marino 	      __lookAhead += __pattSize;
408*e4b17023SJohn Marino 	      __tailSize -= __pattSize;
409*e4b17023SJohn Marino 	    }
410*e4b17023SJohn Marino 	  _DistanceType __remainder = __skipOffset;
411*e4b17023SJohn Marino 	  for (_RandomAccessIter __backTrack = __lookAhead - 1;
412*e4b17023SJohn Marino 	       *__backTrack == __val; --__backTrack)
413*e4b17023SJohn Marino 	    {
414*e4b17023SJohn Marino 	      if (--__remainder == 0)
415*e4b17023SJohn Marino 		return (__lookAhead - __skipOffset); // Success
416*e4b17023SJohn Marino 	    }
417*e4b17023SJohn Marino 	  if (__remainder > __tailSize)
418*e4b17023SJohn Marino 	    return __last; // Failure
419*e4b17023SJohn Marino 	  __lookAhead += __remainder;
420*e4b17023SJohn Marino 	  __tailSize -= __remainder;
421*e4b17023SJohn Marino 	}
422*e4b17023SJohn Marino     }
423*e4b17023SJohn Marino 
424*e4b17023SJohn Marino   // search_n
425*e4b17023SJohn Marino 
426*e4b17023SJohn Marino   /**
427*e4b17023SJohn Marino    *  This is an uglified
428*e4b17023SJohn Marino    *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&,
429*e4b17023SJohn Marino    *	       _BinaryPredicate)
430*e4b17023SJohn Marino    *  overloaded for forward iterators.
431*e4b17023SJohn Marino   */
432*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Integer, typename _Tp,
433*e4b17023SJohn Marino            typename _BinaryPredicate>
434*e4b17023SJohn Marino     _ForwardIterator
435*e4b17023SJohn Marino     __search_n(_ForwardIterator __first, _ForwardIterator __last,
436*e4b17023SJohn Marino 	       _Integer __count, const _Tp& __val,
437*e4b17023SJohn Marino 	       _BinaryPredicate __binary_pred, std::forward_iterator_tag)
438*e4b17023SJohn Marino     {
439*e4b17023SJohn Marino       while (__first != __last && !bool(__binary_pred(*__first, __val)))
440*e4b17023SJohn Marino         ++__first;
441*e4b17023SJohn Marino 
442*e4b17023SJohn Marino       while (__first != __last)
443*e4b17023SJohn Marino 	{
444*e4b17023SJohn Marino 	  typename iterator_traits<_ForwardIterator>::difference_type
445*e4b17023SJohn Marino 	    __n = __count;
446*e4b17023SJohn Marino 	  _ForwardIterator __i = __first;
447*e4b17023SJohn Marino 	  ++__i;
448*e4b17023SJohn Marino 	  while (__i != __last && __n != 1 && bool(__binary_pred(*__i, __val)))
449*e4b17023SJohn Marino 	    {
450*e4b17023SJohn Marino 	      ++__i;
451*e4b17023SJohn Marino 	      --__n;
452*e4b17023SJohn Marino 	    }
453*e4b17023SJohn Marino 	  if (__n == 1)
454*e4b17023SJohn Marino 	    return __first;
455*e4b17023SJohn Marino 	  if (__i == __last)
456*e4b17023SJohn Marino 	    return __last;
457*e4b17023SJohn Marino 	  __first = ++__i;
458*e4b17023SJohn Marino 	  while (__first != __last
459*e4b17023SJohn Marino 		 && !bool(__binary_pred(*__first, __val)))
460*e4b17023SJohn Marino 	    ++__first;
461*e4b17023SJohn Marino 	}
462*e4b17023SJohn Marino       return __last;
463*e4b17023SJohn Marino     }
464*e4b17023SJohn Marino 
465*e4b17023SJohn Marino   /**
466*e4b17023SJohn Marino    *  This is an uglified
467*e4b17023SJohn Marino    *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&,
468*e4b17023SJohn Marino    *	       _BinaryPredicate)
469*e4b17023SJohn Marino    *  overloaded for random access iterators.
470*e4b17023SJohn Marino   */
471*e4b17023SJohn Marino   template<typename _RandomAccessIter, typename _Integer, typename _Tp,
472*e4b17023SJohn Marino 	   typename _BinaryPredicate>
473*e4b17023SJohn Marino     _RandomAccessIter
474*e4b17023SJohn Marino     __search_n(_RandomAccessIter __first, _RandomAccessIter __last,
475*e4b17023SJohn Marino 	       _Integer __count, const _Tp& __val,
476*e4b17023SJohn Marino 	       _BinaryPredicate __binary_pred, std::random_access_iterator_tag)
477*e4b17023SJohn Marino     {
478*e4b17023SJohn Marino 
479*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
480*e4b17023SJohn Marino 	_DistanceType;
481*e4b17023SJohn Marino 
482*e4b17023SJohn Marino       _DistanceType __tailSize = __last - __first;
483*e4b17023SJohn Marino       const _DistanceType __pattSize = __count;
484*e4b17023SJohn Marino 
485*e4b17023SJohn Marino       if (__tailSize < __pattSize)
486*e4b17023SJohn Marino         return __last;
487*e4b17023SJohn Marino 
488*e4b17023SJohn Marino       const _DistanceType __skipOffset = __pattSize - 1;
489*e4b17023SJohn Marino       _RandomAccessIter __lookAhead = __first + __skipOffset;
490*e4b17023SJohn Marino       __tailSize -= __pattSize;
491*e4b17023SJohn Marino 
492*e4b17023SJohn Marino       while (1) // the main loop...
493*e4b17023SJohn Marino 	{
494*e4b17023SJohn Marino 	  // __lookAhead here is always pointing to the last element of next
495*e4b17023SJohn Marino 	  // possible match.
496*e4b17023SJohn Marino 	  while (!bool(__binary_pred(*__lookAhead, __val))) // the skip loop...
497*e4b17023SJohn Marino 	    {
498*e4b17023SJohn Marino 	      if (__tailSize < __pattSize)
499*e4b17023SJohn Marino 		return __last;  // Failure
500*e4b17023SJohn Marino 	      __lookAhead += __pattSize;
501*e4b17023SJohn Marino 	      __tailSize -= __pattSize;
502*e4b17023SJohn Marino 	    }
503*e4b17023SJohn Marino 	  _DistanceType __remainder = __skipOffset;
504*e4b17023SJohn Marino 	  for (_RandomAccessIter __backTrack = __lookAhead - 1;
505*e4b17023SJohn Marino 	       __binary_pred(*__backTrack, __val); --__backTrack)
506*e4b17023SJohn Marino 	    {
507*e4b17023SJohn Marino 	      if (--__remainder == 0)
508*e4b17023SJohn Marino 		return (__lookAhead - __skipOffset); // Success
509*e4b17023SJohn Marino 	    }
510*e4b17023SJohn Marino 	  if (__remainder > __tailSize)
511*e4b17023SJohn Marino 	    return __last; // Failure
512*e4b17023SJohn Marino 	  __lookAhead += __remainder;
513*e4b17023SJohn Marino 	  __tailSize -= __remainder;
514*e4b17023SJohn Marino 	}
515*e4b17023SJohn Marino     }
516*e4b17023SJohn Marino 
517*e4b17023SJohn Marino   // find_end for forward iterators.
518*e4b17023SJohn Marino   template<typename _ForwardIterator1, typename _ForwardIterator2>
519*e4b17023SJohn Marino     _ForwardIterator1
520*e4b17023SJohn Marino     __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
521*e4b17023SJohn Marino 	       _ForwardIterator2 __first2, _ForwardIterator2 __last2,
522*e4b17023SJohn Marino 	       forward_iterator_tag, forward_iterator_tag)
523*e4b17023SJohn Marino     {
524*e4b17023SJohn Marino       if (__first2 == __last2)
525*e4b17023SJohn Marino 	return __last1;
526*e4b17023SJohn Marino       else
527*e4b17023SJohn Marino 	{
528*e4b17023SJohn Marino 	  _ForwardIterator1 __result = __last1;
529*e4b17023SJohn Marino 	  while (1)
530*e4b17023SJohn Marino 	    {
531*e4b17023SJohn Marino 	      _ForwardIterator1 __new_result
532*e4b17023SJohn Marino 		= _GLIBCXX_STD_A::search(__first1, __last1, __first2, __last2);
533*e4b17023SJohn Marino 	      if (__new_result == __last1)
534*e4b17023SJohn Marino 		return __result;
535*e4b17023SJohn Marino 	      else
536*e4b17023SJohn Marino 		{
537*e4b17023SJohn Marino 		  __result = __new_result;
538*e4b17023SJohn Marino 		  __first1 = __new_result;
539*e4b17023SJohn Marino 		  ++__first1;
540*e4b17023SJohn Marino 		}
541*e4b17023SJohn Marino 	    }
542*e4b17023SJohn Marino 	}
543*e4b17023SJohn Marino     }
544*e4b17023SJohn Marino 
545*e4b17023SJohn Marino   template<typename _ForwardIterator1, typename _ForwardIterator2,
546*e4b17023SJohn Marino 	   typename _BinaryPredicate>
547*e4b17023SJohn Marino     _ForwardIterator1
548*e4b17023SJohn Marino     __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
549*e4b17023SJohn Marino 	       _ForwardIterator2 __first2, _ForwardIterator2 __last2,
550*e4b17023SJohn Marino 	       forward_iterator_tag, forward_iterator_tag,
551*e4b17023SJohn Marino 	       _BinaryPredicate __comp)
552*e4b17023SJohn Marino     {
553*e4b17023SJohn Marino       if (__first2 == __last2)
554*e4b17023SJohn Marino 	return __last1;
555*e4b17023SJohn Marino       else
556*e4b17023SJohn Marino 	{
557*e4b17023SJohn Marino 	  _ForwardIterator1 __result = __last1;
558*e4b17023SJohn Marino 	  while (1)
559*e4b17023SJohn Marino 	    {
560*e4b17023SJohn Marino 	      _ForwardIterator1 __new_result
561*e4b17023SJohn Marino 		= _GLIBCXX_STD_A::search(__first1, __last1, __first2,
562*e4b17023SJohn Marino 					 __last2, __comp);
563*e4b17023SJohn Marino 	      if (__new_result == __last1)
564*e4b17023SJohn Marino 		return __result;
565*e4b17023SJohn Marino 	      else
566*e4b17023SJohn Marino 		{
567*e4b17023SJohn Marino 		  __result = __new_result;
568*e4b17023SJohn Marino 		  __first1 = __new_result;
569*e4b17023SJohn Marino 		  ++__first1;
570*e4b17023SJohn Marino 		}
571*e4b17023SJohn Marino 	    }
572*e4b17023SJohn Marino 	}
573*e4b17023SJohn Marino     }
574*e4b17023SJohn Marino 
575*e4b17023SJohn Marino   // find_end for bidirectional iterators (much faster).
576*e4b17023SJohn Marino   template<typename _BidirectionalIterator1, typename _BidirectionalIterator2>
577*e4b17023SJohn Marino     _BidirectionalIterator1
578*e4b17023SJohn Marino     __find_end(_BidirectionalIterator1 __first1,
579*e4b17023SJohn Marino 	       _BidirectionalIterator1 __last1,
580*e4b17023SJohn Marino 	       _BidirectionalIterator2 __first2,
581*e4b17023SJohn Marino 	       _BidirectionalIterator2 __last2,
582*e4b17023SJohn Marino 	       bidirectional_iterator_tag, bidirectional_iterator_tag)
583*e4b17023SJohn Marino     {
584*e4b17023SJohn Marino       // concept requirements
585*e4b17023SJohn Marino       __glibcxx_function_requires(_BidirectionalIteratorConcept<
586*e4b17023SJohn Marino 				  _BidirectionalIterator1>)
587*e4b17023SJohn Marino       __glibcxx_function_requires(_BidirectionalIteratorConcept<
588*e4b17023SJohn Marino 				  _BidirectionalIterator2>)
589*e4b17023SJohn Marino 
590*e4b17023SJohn Marino       typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1;
591*e4b17023SJohn Marino       typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2;
592*e4b17023SJohn Marino 
593*e4b17023SJohn Marino       _RevIterator1 __rlast1(__first1);
594*e4b17023SJohn Marino       _RevIterator2 __rlast2(__first2);
595*e4b17023SJohn Marino       _RevIterator1 __rresult = _GLIBCXX_STD_A::search(_RevIterator1(__last1),
596*e4b17023SJohn Marino 						       __rlast1,
597*e4b17023SJohn Marino 						       _RevIterator2(__last2),
598*e4b17023SJohn Marino 						       __rlast2);
599*e4b17023SJohn Marino 
600*e4b17023SJohn Marino       if (__rresult == __rlast1)
601*e4b17023SJohn Marino 	return __last1;
602*e4b17023SJohn Marino       else
603*e4b17023SJohn Marino 	{
604*e4b17023SJohn Marino 	  _BidirectionalIterator1 __result = __rresult.base();
605*e4b17023SJohn Marino 	  std::advance(__result, -std::distance(__first2, __last2));
606*e4b17023SJohn Marino 	  return __result;
607*e4b17023SJohn Marino 	}
608*e4b17023SJohn Marino     }
609*e4b17023SJohn Marino 
610*e4b17023SJohn Marino   template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
611*e4b17023SJohn Marino 	   typename _BinaryPredicate>
612*e4b17023SJohn Marino     _BidirectionalIterator1
613*e4b17023SJohn Marino     __find_end(_BidirectionalIterator1 __first1,
614*e4b17023SJohn Marino 	       _BidirectionalIterator1 __last1,
615*e4b17023SJohn Marino 	       _BidirectionalIterator2 __first2,
616*e4b17023SJohn Marino 	       _BidirectionalIterator2 __last2,
617*e4b17023SJohn Marino 	       bidirectional_iterator_tag, bidirectional_iterator_tag,
618*e4b17023SJohn Marino 	       _BinaryPredicate __comp)
619*e4b17023SJohn Marino     {
620*e4b17023SJohn Marino       // concept requirements
621*e4b17023SJohn Marino       __glibcxx_function_requires(_BidirectionalIteratorConcept<
622*e4b17023SJohn Marino 				  _BidirectionalIterator1>)
623*e4b17023SJohn Marino       __glibcxx_function_requires(_BidirectionalIteratorConcept<
624*e4b17023SJohn Marino 				  _BidirectionalIterator2>)
625*e4b17023SJohn Marino 
626*e4b17023SJohn Marino       typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1;
627*e4b17023SJohn Marino       typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2;
628*e4b17023SJohn Marino 
629*e4b17023SJohn Marino       _RevIterator1 __rlast1(__first1);
630*e4b17023SJohn Marino       _RevIterator2 __rlast2(__first2);
631*e4b17023SJohn Marino       _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1,
632*e4b17023SJohn Marino 					    _RevIterator2(__last2), __rlast2,
633*e4b17023SJohn Marino 					    __comp);
634*e4b17023SJohn Marino 
635*e4b17023SJohn Marino       if (__rresult == __rlast1)
636*e4b17023SJohn Marino 	return __last1;
637*e4b17023SJohn Marino       else
638*e4b17023SJohn Marino 	{
639*e4b17023SJohn Marino 	  _BidirectionalIterator1 __result = __rresult.base();
640*e4b17023SJohn Marino 	  std::advance(__result, -std::distance(__first2, __last2));
641*e4b17023SJohn Marino 	  return __result;
642*e4b17023SJohn Marino 	}
643*e4b17023SJohn Marino     }
644*e4b17023SJohn Marino 
645*e4b17023SJohn Marino   /**
646*e4b17023SJohn Marino    *  @brief  Find last matching subsequence in a sequence.
647*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
648*e4b17023SJohn Marino    *  @param  __first1  Start of range to search.
649*e4b17023SJohn Marino    *  @param  __last1   End of range to search.
650*e4b17023SJohn Marino    *  @param  __first2  Start of sequence to match.
651*e4b17023SJohn Marino    *  @param  __last2   End of sequence to match.
652*e4b17023SJohn Marino    *  @return   The last iterator @c i in the range
653*e4b17023SJohn Marino    *  @p [__first1,__last1-(__last2-__first2)) such that @c *(i+N) ==
654*e4b17023SJohn Marino    *  @p *(__first2+N) for each @c N in the range @p
655*e4b17023SJohn Marino    *  [0,__last2-__first2), or @p __last1 if no such iterator exists.
656*e4b17023SJohn Marino    *
657*e4b17023SJohn Marino    *  Searches the range @p [__first1,__last1) for a sub-sequence that
658*e4b17023SJohn Marino    *  compares equal value-by-value with the sequence given by @p
659*e4b17023SJohn Marino    *  [__first2,__last2) and returns an iterator to the __first
660*e4b17023SJohn Marino    *  element of the sub-sequence, or @p __last1 if the sub-sequence
661*e4b17023SJohn Marino    *  is not found.  The sub-sequence will be the last such
662*e4b17023SJohn Marino    *  subsequence contained in [__first,__last1).
663*e4b17023SJohn Marino    *
664*e4b17023SJohn Marino    *  Because the sub-sequence must lie completely within the range @p
665*e4b17023SJohn Marino    *  [__first1,__last1) it must start at a position less than @p
666*e4b17023SJohn Marino    *  __last1-(__last2-__first2) where @p __last2-__first2 is the
667*e4b17023SJohn Marino    *  length of the sub-sequence.  This means that the returned
668*e4b17023SJohn Marino    *  iterator @c i will be in the range @p
669*e4b17023SJohn Marino    *  [__first1,__last1-(__last2-__first2))
670*e4b17023SJohn Marino   */
671*e4b17023SJohn Marino   template<typename _ForwardIterator1, typename _ForwardIterator2>
672*e4b17023SJohn Marino     inline _ForwardIterator1
673*e4b17023SJohn Marino     find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
674*e4b17023SJohn Marino 	     _ForwardIterator2 __first2, _ForwardIterator2 __last2)
675*e4b17023SJohn Marino     {
676*e4b17023SJohn Marino       // concept requirements
677*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
678*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
679*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualOpConcept<
680*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator1>::value_type,
681*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator2>::value_type>)
682*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first1, __last1);
683*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first2, __last2);
684*e4b17023SJohn Marino 
685*e4b17023SJohn Marino       return std::__find_end(__first1, __last1, __first2, __last2,
686*e4b17023SJohn Marino 			     std::__iterator_category(__first1),
687*e4b17023SJohn Marino 			     std::__iterator_category(__first2));
688*e4b17023SJohn Marino     }
689*e4b17023SJohn Marino 
690*e4b17023SJohn Marino   /**
691*e4b17023SJohn Marino    *  @brief  Find last matching subsequence in a sequence using a predicate.
692*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
693*e4b17023SJohn Marino    *  @param  __first1  Start of range to search.
694*e4b17023SJohn Marino    *  @param  __last1   End of range to search.
695*e4b17023SJohn Marino    *  @param  __first2  Start of sequence to match.
696*e4b17023SJohn Marino    *  @param  __last2   End of sequence to match.
697*e4b17023SJohn Marino    *  @param  __comp    The predicate to use.
698*e4b17023SJohn Marino    *  @return The last iterator @c i in the range @p
699*e4b17023SJohn Marino    *  [__first1,__last1-(__last2-__first2)) such that @c
700*e4b17023SJohn Marino    *  predicate(*(i+N), @p (__first2+N)) is true for each @c N in the
701*e4b17023SJohn Marino    *  range @p [0,__last2-__first2), or @p __last1 if no such iterator
702*e4b17023SJohn Marino    *  exists.
703*e4b17023SJohn Marino    *
704*e4b17023SJohn Marino    *  Searches the range @p [__first1,__last1) for a sub-sequence that
705*e4b17023SJohn Marino    *  compares equal value-by-value with the sequence given by @p
706*e4b17023SJohn Marino    *  [__first2,__last2) using comp as a predicate and returns an
707*e4b17023SJohn Marino    *  iterator to the first element of the sub-sequence, or @p __last1
708*e4b17023SJohn Marino    *  if the sub-sequence is not found.  The sub-sequence will be the
709*e4b17023SJohn Marino    *  last such subsequence contained in [__first,__last1).
710*e4b17023SJohn Marino    *
711*e4b17023SJohn Marino    *  Because the sub-sequence must lie completely within the range @p
712*e4b17023SJohn Marino    *  [__first1,__last1) it must start at a position less than @p
713*e4b17023SJohn Marino    *  __last1-(__last2-__first2) where @p __last2-__first2 is the
714*e4b17023SJohn Marino    *  length of the sub-sequence.  This means that the returned
715*e4b17023SJohn Marino    *  iterator @c i will be in the range @p
716*e4b17023SJohn Marino    *  [__first1,__last1-(__last2-__first2))
717*e4b17023SJohn Marino   */
718*e4b17023SJohn Marino   template<typename _ForwardIterator1, typename _ForwardIterator2,
719*e4b17023SJohn Marino 	   typename _BinaryPredicate>
720*e4b17023SJohn Marino     inline _ForwardIterator1
721*e4b17023SJohn Marino     find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
722*e4b17023SJohn Marino 	     _ForwardIterator2 __first2, _ForwardIterator2 __last2,
723*e4b17023SJohn Marino 	     _BinaryPredicate __comp)
724*e4b17023SJohn Marino     {
725*e4b17023SJohn Marino       // concept requirements
726*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
727*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
728*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
729*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator1>::value_type,
730*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator2>::value_type>)
731*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first1, __last1);
732*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first2, __last2);
733*e4b17023SJohn Marino 
734*e4b17023SJohn Marino       return std::__find_end(__first1, __last1, __first2, __last2,
735*e4b17023SJohn Marino 			     std::__iterator_category(__first1),
736*e4b17023SJohn Marino 			     std::__iterator_category(__first2),
737*e4b17023SJohn Marino 			     __comp);
738*e4b17023SJohn Marino     }
739*e4b17023SJohn Marino 
740*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
741*e4b17023SJohn Marino   /**
742*e4b17023SJohn Marino    *  @brief  Checks that a predicate is true for all the elements
743*e4b17023SJohn Marino    *          of a sequence.
744*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
745*e4b17023SJohn Marino    *  @param  __first   An input iterator.
746*e4b17023SJohn Marino    *  @param  __last    An input iterator.
747*e4b17023SJohn Marino    *  @param  __pred    A predicate.
748*e4b17023SJohn Marino    *  @return  True if the check is true, false otherwise.
749*e4b17023SJohn Marino    *
750*e4b17023SJohn Marino    *  Returns true if @p __pred is true for each element in the range
751*e4b17023SJohn Marino    *  @p [__first,__last), and false otherwise.
752*e4b17023SJohn Marino   */
753*e4b17023SJohn Marino   template<typename _InputIterator, typename _Predicate>
754*e4b17023SJohn Marino     inline bool
755*e4b17023SJohn Marino     all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
756*e4b17023SJohn Marino     { return __last == std::find_if_not(__first, __last, __pred); }
757*e4b17023SJohn Marino 
758*e4b17023SJohn Marino   /**
759*e4b17023SJohn Marino    *  @brief  Checks that a predicate is false for all the elements
760*e4b17023SJohn Marino    *          of a sequence.
761*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
762*e4b17023SJohn Marino    *  @param  __first   An input iterator.
763*e4b17023SJohn Marino    *  @param  __last    An input iterator.
764*e4b17023SJohn Marino    *  @param  __pred    A predicate.
765*e4b17023SJohn Marino    *  @return  True if the check is true, false otherwise.
766*e4b17023SJohn Marino    *
767*e4b17023SJohn Marino    *  Returns true if @p __pred is false for each element in the range
768*e4b17023SJohn Marino    *  @p [__first,__last), and false otherwise.
769*e4b17023SJohn Marino   */
770*e4b17023SJohn Marino   template<typename _InputIterator, typename _Predicate>
771*e4b17023SJohn Marino     inline bool
772*e4b17023SJohn Marino     none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
773*e4b17023SJohn Marino     { return __last == _GLIBCXX_STD_A::find_if(__first, __last, __pred); }
774*e4b17023SJohn Marino 
775*e4b17023SJohn Marino   /**
776*e4b17023SJohn Marino    *  @brief  Checks that a predicate is false for at least an element
777*e4b17023SJohn Marino    *          of a sequence.
778*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
779*e4b17023SJohn Marino    *  @param  __first   An input iterator.
780*e4b17023SJohn Marino    *  @param  __last    An input iterator.
781*e4b17023SJohn Marino    *  @param  __pred    A predicate.
782*e4b17023SJohn Marino    *  @return  True if the check is true, false otherwise.
783*e4b17023SJohn Marino    *
784*e4b17023SJohn Marino    *  Returns true if an element exists in the range @p
785*e4b17023SJohn Marino    *  [__first,__last) such that @p __pred is true, and false
786*e4b17023SJohn Marino    *  otherwise.
787*e4b17023SJohn Marino   */
788*e4b17023SJohn Marino   template<typename _InputIterator, typename _Predicate>
789*e4b17023SJohn Marino     inline bool
790*e4b17023SJohn Marino     any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
791*e4b17023SJohn Marino     { return !std::none_of(__first, __last, __pred); }
792*e4b17023SJohn Marino 
793*e4b17023SJohn Marino   /**
794*e4b17023SJohn Marino    *  @brief  Find the first element in a sequence for which a
795*e4b17023SJohn Marino    *          predicate is false.
796*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
797*e4b17023SJohn Marino    *  @param  __first  An input iterator.
798*e4b17023SJohn Marino    *  @param  __last   An input iterator.
799*e4b17023SJohn Marino    *  @param  __pred   A predicate.
800*e4b17023SJohn Marino    *  @return   The first iterator @c i in the range @p [__first,__last)
801*e4b17023SJohn Marino    *  such that @p __pred(*i) is false, or @p __last if no such iterator exists.
802*e4b17023SJohn Marino   */
803*e4b17023SJohn Marino   template<typename _InputIterator, typename _Predicate>
804*e4b17023SJohn Marino     inline _InputIterator
805*e4b17023SJohn Marino     find_if_not(_InputIterator __first, _InputIterator __last,
806*e4b17023SJohn Marino 		_Predicate __pred)
807*e4b17023SJohn Marino     {
808*e4b17023SJohn Marino       // concept requirements
809*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
810*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
811*e4b17023SJohn Marino 	      typename iterator_traits<_InputIterator>::value_type>)
812*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
813*e4b17023SJohn Marino       return std::__find_if_not(__first, __last, __pred);
814*e4b17023SJohn Marino     }
815*e4b17023SJohn Marino 
816*e4b17023SJohn Marino   /**
817*e4b17023SJohn Marino    *  @brief  Checks whether the sequence is partitioned.
818*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
819*e4b17023SJohn Marino    *  @param  __first  An input iterator.
820*e4b17023SJohn Marino    *  @param  __last   An input iterator.
821*e4b17023SJohn Marino    *  @param  __pred   A predicate.
822*e4b17023SJohn Marino    *  @return  True if the range @p [__first,__last) is partioned by @p __pred,
823*e4b17023SJohn Marino    *  i.e. if all elements that satisfy @p __pred appear before those that
824*e4b17023SJohn Marino    *  do not.
825*e4b17023SJohn Marino   */
826*e4b17023SJohn Marino   template<typename _InputIterator, typename _Predicate>
827*e4b17023SJohn Marino     inline bool
828*e4b17023SJohn Marino     is_partitioned(_InputIterator __first, _InputIterator __last,
829*e4b17023SJohn Marino 		   _Predicate __pred)
830*e4b17023SJohn Marino     {
831*e4b17023SJohn Marino       __first = std::find_if_not(__first, __last, __pred);
832*e4b17023SJohn Marino       return std::none_of(__first, __last, __pred);
833*e4b17023SJohn Marino     }
834*e4b17023SJohn Marino 
835*e4b17023SJohn Marino   /**
836*e4b17023SJohn Marino    *  @brief  Find the partition point of a partitioned range.
837*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
838*e4b17023SJohn Marino    *  @param  __first   An iterator.
839*e4b17023SJohn Marino    *  @param  __last    Another iterator.
840*e4b17023SJohn Marino    *  @param  __pred    A predicate.
841*e4b17023SJohn Marino    *  @return  An iterator @p mid such that @p all_of(__first, mid, __pred)
842*e4b17023SJohn Marino    *           and @p none_of(mid, __last, __pred) are both true.
843*e4b17023SJohn Marino   */
844*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Predicate>
845*e4b17023SJohn Marino     _ForwardIterator
846*e4b17023SJohn Marino     partition_point(_ForwardIterator __first, _ForwardIterator __last,
847*e4b17023SJohn Marino 		    _Predicate __pred)
848*e4b17023SJohn Marino     {
849*e4b17023SJohn Marino       // concept requirements
850*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
851*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
852*e4b17023SJohn Marino 	      typename iterator_traits<_ForwardIterator>::value_type>)
853*e4b17023SJohn Marino 
854*e4b17023SJohn Marino       // A specific debug-mode test will be necessary...
855*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
856*e4b17023SJohn Marino 
857*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::difference_type
858*e4b17023SJohn Marino 	_DistanceType;
859*e4b17023SJohn Marino 
860*e4b17023SJohn Marino       _DistanceType __len = std::distance(__first, __last);
861*e4b17023SJohn Marino       _DistanceType __half;
862*e4b17023SJohn Marino       _ForwardIterator __middle;
863*e4b17023SJohn Marino 
864*e4b17023SJohn Marino       while (__len > 0)
865*e4b17023SJohn Marino 	{
866*e4b17023SJohn Marino 	  __half = __len >> 1;
867*e4b17023SJohn Marino 	  __middle = __first;
868*e4b17023SJohn Marino 	  std::advance(__middle, __half);
869*e4b17023SJohn Marino 	  if (__pred(*__middle))
870*e4b17023SJohn Marino 	    {
871*e4b17023SJohn Marino 	      __first = __middle;
872*e4b17023SJohn Marino 	      ++__first;
873*e4b17023SJohn Marino 	      __len = __len - __half - 1;
874*e4b17023SJohn Marino 	    }
875*e4b17023SJohn Marino 	  else
876*e4b17023SJohn Marino 	    __len = __half;
877*e4b17023SJohn Marino 	}
878*e4b17023SJohn Marino       return __first;
879*e4b17023SJohn Marino     }
880*e4b17023SJohn Marino #endif
881*e4b17023SJohn Marino 
882*e4b17023SJohn Marino 
883*e4b17023SJohn Marino   /**
884*e4b17023SJohn Marino    *  @brief Copy a sequence, removing elements of a given value.
885*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
886*e4b17023SJohn Marino    *  @param  __first   An input iterator.
887*e4b17023SJohn Marino    *  @param  __last    An input iterator.
888*e4b17023SJohn Marino    *  @param  __result  An output iterator.
889*e4b17023SJohn Marino    *  @param  __value   The value to be removed.
890*e4b17023SJohn Marino    *  @return   An iterator designating the end of the resulting sequence.
891*e4b17023SJohn Marino    *
892*e4b17023SJohn Marino    *  Copies each element in the range @p [__first,__last) not equal
893*e4b17023SJohn Marino    *  to @p __value to the range beginning at @p __result.
894*e4b17023SJohn Marino    *  remove_copy() is stable, so the relative order of elements that
895*e4b17023SJohn Marino    *  are copied is unchanged.
896*e4b17023SJohn Marino   */
897*e4b17023SJohn Marino   template<typename _InputIterator, typename _OutputIterator, typename _Tp>
898*e4b17023SJohn Marino     _OutputIterator
899*e4b17023SJohn Marino     remove_copy(_InputIterator __first, _InputIterator __last,
900*e4b17023SJohn Marino 		_OutputIterator __result, const _Tp& __value)
901*e4b17023SJohn Marino     {
902*e4b17023SJohn Marino       // concept requirements
903*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
904*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
905*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
906*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualOpConcept<
907*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type, _Tp>)
908*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
909*e4b17023SJohn Marino 
910*e4b17023SJohn Marino       for (; __first != __last; ++__first)
911*e4b17023SJohn Marino 	if (!(*__first == __value))
912*e4b17023SJohn Marino 	  {
913*e4b17023SJohn Marino 	    *__result = *__first;
914*e4b17023SJohn Marino 	    ++__result;
915*e4b17023SJohn Marino 	  }
916*e4b17023SJohn Marino       return __result;
917*e4b17023SJohn Marino     }
918*e4b17023SJohn Marino 
919*e4b17023SJohn Marino   /**
920*e4b17023SJohn Marino    *  @brief Copy a sequence, removing elements for which a predicate is true.
921*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
922*e4b17023SJohn Marino    *  @param  __first   An input iterator.
923*e4b17023SJohn Marino    *  @param  __last    An input iterator.
924*e4b17023SJohn Marino    *  @param  __result  An output iterator.
925*e4b17023SJohn Marino    *  @param  __pred    A predicate.
926*e4b17023SJohn Marino    *  @return   An iterator designating the end of the resulting sequence.
927*e4b17023SJohn Marino    *
928*e4b17023SJohn Marino    *  Copies each element in the range @p [__first,__last) for which
929*e4b17023SJohn Marino    *  @p __pred returns false to the range beginning at @p __result.
930*e4b17023SJohn Marino    *
931*e4b17023SJohn Marino    *  remove_copy_if() is stable, so the relative order of elements that are
932*e4b17023SJohn Marino    *  copied is unchanged.
933*e4b17023SJohn Marino   */
934*e4b17023SJohn Marino   template<typename _InputIterator, typename _OutputIterator,
935*e4b17023SJohn Marino 	   typename _Predicate>
936*e4b17023SJohn Marino     _OutputIterator
937*e4b17023SJohn Marino     remove_copy_if(_InputIterator __first, _InputIterator __last,
938*e4b17023SJohn Marino 		   _OutputIterator __result, _Predicate __pred)
939*e4b17023SJohn Marino     {
940*e4b17023SJohn Marino       // concept requirements
941*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
942*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
943*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
944*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
945*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
946*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
947*e4b17023SJohn Marino 
948*e4b17023SJohn Marino       for (; __first != __last; ++__first)
949*e4b17023SJohn Marino 	if (!bool(__pred(*__first)))
950*e4b17023SJohn Marino 	  {
951*e4b17023SJohn Marino 	    *__result = *__first;
952*e4b17023SJohn Marino 	    ++__result;
953*e4b17023SJohn Marino 	  }
954*e4b17023SJohn Marino       return __result;
955*e4b17023SJohn Marino     }
956*e4b17023SJohn Marino 
957*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
958*e4b17023SJohn Marino   /**
959*e4b17023SJohn Marino    *  @brief Copy the elements of a sequence for which a predicate is true.
960*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
961*e4b17023SJohn Marino    *  @param  __first   An input iterator.
962*e4b17023SJohn Marino    *  @param  __last    An input iterator.
963*e4b17023SJohn Marino    *  @param  __result  An output iterator.
964*e4b17023SJohn Marino    *  @param  __pred    A predicate.
965*e4b17023SJohn Marino    *  @return   An iterator designating the end of the resulting sequence.
966*e4b17023SJohn Marino    *
967*e4b17023SJohn Marino    *  Copies each element in the range @p [__first,__last) for which
968*e4b17023SJohn Marino    *  @p __pred returns true to the range beginning at @p __result.
969*e4b17023SJohn Marino    *
970*e4b17023SJohn Marino    *  copy_if() is stable, so the relative order of elements that are
971*e4b17023SJohn Marino    *  copied is unchanged.
972*e4b17023SJohn Marino   */
973*e4b17023SJohn Marino   template<typename _InputIterator, typename _OutputIterator,
974*e4b17023SJohn Marino 	   typename _Predicate>
975*e4b17023SJohn Marino     _OutputIterator
976*e4b17023SJohn Marino     copy_if(_InputIterator __first, _InputIterator __last,
977*e4b17023SJohn Marino 	    _OutputIterator __result, _Predicate __pred)
978*e4b17023SJohn Marino     {
979*e4b17023SJohn Marino       // concept requirements
980*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
981*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
982*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
983*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
984*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
985*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
986*e4b17023SJohn Marino 
987*e4b17023SJohn Marino       for (; __first != __last; ++__first)
988*e4b17023SJohn Marino 	if (__pred(*__first))
989*e4b17023SJohn Marino 	  {
990*e4b17023SJohn Marino 	    *__result = *__first;
991*e4b17023SJohn Marino 	    ++__result;
992*e4b17023SJohn Marino 	  }
993*e4b17023SJohn Marino       return __result;
994*e4b17023SJohn Marino     }
995*e4b17023SJohn Marino 
996*e4b17023SJohn Marino 
997*e4b17023SJohn Marino   template<typename _InputIterator, typename _Size, typename _OutputIterator>
998*e4b17023SJohn Marino     _OutputIterator
999*e4b17023SJohn Marino     __copy_n(_InputIterator __first, _Size __n,
1000*e4b17023SJohn Marino 	     _OutputIterator __result, input_iterator_tag)
1001*e4b17023SJohn Marino     {
1002*e4b17023SJohn Marino       if (__n > 0)
1003*e4b17023SJohn Marino 	{
1004*e4b17023SJohn Marino 	  while (true)
1005*e4b17023SJohn Marino 	    {
1006*e4b17023SJohn Marino 	      *__result = *__first;
1007*e4b17023SJohn Marino 	      ++__result;
1008*e4b17023SJohn Marino 	      if (--__n > 0)
1009*e4b17023SJohn Marino 		++__first;
1010*e4b17023SJohn Marino 	      else
1011*e4b17023SJohn Marino 		break;
1012*e4b17023SJohn Marino 	    }
1013*e4b17023SJohn Marino 	}
1014*e4b17023SJohn Marino       return __result;
1015*e4b17023SJohn Marino     }
1016*e4b17023SJohn Marino 
1017*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Size,
1018*e4b17023SJohn Marino 	   typename _OutputIterator>
1019*e4b17023SJohn Marino     inline _OutputIterator
1020*e4b17023SJohn Marino     __copy_n(_RandomAccessIterator __first, _Size __n,
1021*e4b17023SJohn Marino 	     _OutputIterator __result, random_access_iterator_tag)
1022*e4b17023SJohn Marino     { return std::copy(__first, __first + __n, __result); }
1023*e4b17023SJohn Marino 
1024*e4b17023SJohn Marino   /**
1025*e4b17023SJohn Marino    *  @brief Copies the range [first,first+n) into [result,result+n).
1026*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
1027*e4b17023SJohn Marino    *  @param  __first  An input iterator.
1028*e4b17023SJohn Marino    *  @param  __n      The number of elements to copy.
1029*e4b17023SJohn Marino    *  @param  __result An output iterator.
1030*e4b17023SJohn Marino    *  @return  result+n.
1031*e4b17023SJohn Marino    *
1032*e4b17023SJohn Marino    *  This inline function will boil down to a call to @c memmove whenever
1033*e4b17023SJohn Marino    *  possible.  Failing that, if random access iterators are passed, then the
1034*e4b17023SJohn Marino    *  loop count will be known (and therefore a candidate for compiler
1035*e4b17023SJohn Marino    *  optimizations such as unrolling).
1036*e4b17023SJohn Marino   */
1037*e4b17023SJohn Marino   template<typename _InputIterator, typename _Size, typename _OutputIterator>
1038*e4b17023SJohn Marino     inline _OutputIterator
1039*e4b17023SJohn Marino     copy_n(_InputIterator __first, _Size __n, _OutputIterator __result)
1040*e4b17023SJohn Marino     {
1041*e4b17023SJohn Marino       // concept requirements
1042*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
1043*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
1044*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
1045*e4b17023SJohn Marino 
1046*e4b17023SJohn Marino       return std::__copy_n(__first, __n, __result,
1047*e4b17023SJohn Marino 			   std::__iterator_category(__first));
1048*e4b17023SJohn Marino     }
1049*e4b17023SJohn Marino 
1050*e4b17023SJohn Marino   /**
1051*e4b17023SJohn Marino    *  @brief Copy the elements of a sequence to separate output sequences
1052*e4b17023SJohn Marino    *         depending on the truth value of a predicate.
1053*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
1054*e4b17023SJohn Marino    *  @param  __first   An input iterator.
1055*e4b17023SJohn Marino    *  @param  __last    An input iterator.
1056*e4b17023SJohn Marino    *  @param  __out_true   An output iterator.
1057*e4b17023SJohn Marino    *  @param  __out_false  An output iterator.
1058*e4b17023SJohn Marino    *  @param  __pred    A predicate.
1059*e4b17023SJohn Marino    *  @return   A pair designating the ends of the resulting sequences.
1060*e4b17023SJohn Marino    *
1061*e4b17023SJohn Marino    *  Copies each element in the range @p [__first,__last) for which
1062*e4b17023SJohn Marino    *  @p __pred returns true to the range beginning at @p out_true
1063*e4b17023SJohn Marino    *  and each element for which @p __pred returns false to @p __out_false.
1064*e4b17023SJohn Marino   */
1065*e4b17023SJohn Marino   template<typename _InputIterator, typename _OutputIterator1,
1066*e4b17023SJohn Marino 	   typename _OutputIterator2, typename _Predicate>
1067*e4b17023SJohn Marino     pair<_OutputIterator1, _OutputIterator2>
1068*e4b17023SJohn Marino     partition_copy(_InputIterator __first, _InputIterator __last,
1069*e4b17023SJohn Marino 		   _OutputIterator1 __out_true, _OutputIterator2 __out_false,
1070*e4b17023SJohn Marino 		   _Predicate __pred)
1071*e4b17023SJohn Marino     {
1072*e4b17023SJohn Marino       // concept requirements
1073*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
1074*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator1,
1075*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
1076*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator2,
1077*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
1078*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
1079*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
1080*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
1081*e4b17023SJohn Marino 
1082*e4b17023SJohn Marino       for (; __first != __last; ++__first)
1083*e4b17023SJohn Marino 	if (__pred(*__first))
1084*e4b17023SJohn Marino 	  {
1085*e4b17023SJohn Marino 	    *__out_true = *__first;
1086*e4b17023SJohn Marino 	    ++__out_true;
1087*e4b17023SJohn Marino 	  }
1088*e4b17023SJohn Marino 	else
1089*e4b17023SJohn Marino 	  {
1090*e4b17023SJohn Marino 	    *__out_false = *__first;
1091*e4b17023SJohn Marino 	    ++__out_false;
1092*e4b17023SJohn Marino 	  }
1093*e4b17023SJohn Marino 
1094*e4b17023SJohn Marino       return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
1095*e4b17023SJohn Marino     }
1096*e4b17023SJohn Marino #endif
1097*e4b17023SJohn Marino 
1098*e4b17023SJohn Marino   /**
1099*e4b17023SJohn Marino    *  @brief Remove elements from a sequence.
1100*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
1101*e4b17023SJohn Marino    *  @param  __first  An input iterator.
1102*e4b17023SJohn Marino    *  @param  __last   An input iterator.
1103*e4b17023SJohn Marino    *  @param  __value  The value to be removed.
1104*e4b17023SJohn Marino    *  @return   An iterator designating the end of the resulting sequence.
1105*e4b17023SJohn Marino    *
1106*e4b17023SJohn Marino    *  All elements equal to @p __value are removed from the range
1107*e4b17023SJohn Marino    *  @p [__first,__last).
1108*e4b17023SJohn Marino    *
1109*e4b17023SJohn Marino    *  remove() is stable, so the relative order of elements that are
1110*e4b17023SJohn Marino    *  not removed is unchanged.
1111*e4b17023SJohn Marino    *
1112*e4b17023SJohn Marino    *  Elements between the end of the resulting sequence and @p __last
1113*e4b17023SJohn Marino    *  are still present, but their value is unspecified.
1114*e4b17023SJohn Marino   */
1115*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Tp>
1116*e4b17023SJohn Marino     _ForwardIterator
1117*e4b17023SJohn Marino     remove(_ForwardIterator __first, _ForwardIterator __last,
1118*e4b17023SJohn Marino 	   const _Tp& __value)
1119*e4b17023SJohn Marino     {
1120*e4b17023SJohn Marino       // concept requirements
1121*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1122*e4b17023SJohn Marino 				  _ForwardIterator>)
1123*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualOpConcept<
1124*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
1125*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
1126*e4b17023SJohn Marino 
1127*e4b17023SJohn Marino       __first = _GLIBCXX_STD_A::find(__first, __last, __value);
1128*e4b17023SJohn Marino       if(__first == __last)
1129*e4b17023SJohn Marino         return __first;
1130*e4b17023SJohn Marino       _ForwardIterator __result = __first;
1131*e4b17023SJohn Marino       ++__first;
1132*e4b17023SJohn Marino       for(; __first != __last; ++__first)
1133*e4b17023SJohn Marino         if(!(*__first == __value))
1134*e4b17023SJohn Marino           {
1135*e4b17023SJohn Marino             *__result = _GLIBCXX_MOVE(*__first);
1136*e4b17023SJohn Marino             ++__result;
1137*e4b17023SJohn Marino           }
1138*e4b17023SJohn Marino       return __result;
1139*e4b17023SJohn Marino     }
1140*e4b17023SJohn Marino 
1141*e4b17023SJohn Marino   /**
1142*e4b17023SJohn Marino    *  @brief Remove elements from a sequence using a predicate.
1143*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
1144*e4b17023SJohn Marino    *  @param  __first  A forward iterator.
1145*e4b17023SJohn Marino    *  @param  __last   A forward iterator.
1146*e4b17023SJohn Marino    *  @param  __pred   A predicate.
1147*e4b17023SJohn Marino    *  @return   An iterator designating the end of the resulting sequence.
1148*e4b17023SJohn Marino    *
1149*e4b17023SJohn Marino    *  All elements for which @p __pred returns true are removed from the range
1150*e4b17023SJohn Marino    *  @p [__first,__last).
1151*e4b17023SJohn Marino    *
1152*e4b17023SJohn Marino    *  remove_if() is stable, so the relative order of elements that are
1153*e4b17023SJohn Marino    *  not removed is unchanged.
1154*e4b17023SJohn Marino    *
1155*e4b17023SJohn Marino    *  Elements between the end of the resulting sequence and @p __last
1156*e4b17023SJohn Marino    *  are still present, but their value is unspecified.
1157*e4b17023SJohn Marino   */
1158*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Predicate>
1159*e4b17023SJohn Marino     _ForwardIterator
1160*e4b17023SJohn Marino     remove_if(_ForwardIterator __first, _ForwardIterator __last,
1161*e4b17023SJohn Marino 	      _Predicate __pred)
1162*e4b17023SJohn Marino     {
1163*e4b17023SJohn Marino       // concept requirements
1164*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1165*e4b17023SJohn Marino 				  _ForwardIterator>)
1166*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
1167*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
1168*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
1169*e4b17023SJohn Marino 
1170*e4b17023SJohn Marino       __first = _GLIBCXX_STD_A::find_if(__first, __last, __pred);
1171*e4b17023SJohn Marino       if(__first == __last)
1172*e4b17023SJohn Marino         return __first;
1173*e4b17023SJohn Marino       _ForwardIterator __result = __first;
1174*e4b17023SJohn Marino       ++__first;
1175*e4b17023SJohn Marino       for(; __first != __last; ++__first)
1176*e4b17023SJohn Marino         if(!bool(__pred(*__first)))
1177*e4b17023SJohn Marino           {
1178*e4b17023SJohn Marino             *__result = _GLIBCXX_MOVE(*__first);
1179*e4b17023SJohn Marino             ++__result;
1180*e4b17023SJohn Marino           }
1181*e4b17023SJohn Marino       return __result;
1182*e4b17023SJohn Marino     }
1183*e4b17023SJohn Marino 
1184*e4b17023SJohn Marino   /**
1185*e4b17023SJohn Marino    *  @brief Remove consecutive duplicate values from a sequence.
1186*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
1187*e4b17023SJohn Marino    *  @param  __first  A forward iterator.
1188*e4b17023SJohn Marino    *  @param  __last   A forward iterator.
1189*e4b17023SJohn Marino    *  @return  An iterator designating the end of the resulting sequence.
1190*e4b17023SJohn Marino    *
1191*e4b17023SJohn Marino    *  Removes all but the first element from each group of consecutive
1192*e4b17023SJohn Marino    *  values that compare equal.
1193*e4b17023SJohn Marino    *  unique() is stable, so the relative order of elements that are
1194*e4b17023SJohn Marino    *  not removed is unchanged.
1195*e4b17023SJohn Marino    *  Elements between the end of the resulting sequence and @p __last
1196*e4b17023SJohn Marino    *  are still present, but their value is unspecified.
1197*e4b17023SJohn Marino   */
1198*e4b17023SJohn Marino   template<typename _ForwardIterator>
1199*e4b17023SJohn Marino     _ForwardIterator
1200*e4b17023SJohn Marino     unique(_ForwardIterator __first, _ForwardIterator __last)
1201*e4b17023SJohn Marino     {
1202*e4b17023SJohn Marino       // concept requirements
1203*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1204*e4b17023SJohn Marino 				  _ForwardIterator>)
1205*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualityComparableConcept<
1206*e4b17023SJohn Marino 		     typename iterator_traits<_ForwardIterator>::value_type>)
1207*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
1208*e4b17023SJohn Marino 
1209*e4b17023SJohn Marino       // Skip the beginning, if already unique.
1210*e4b17023SJohn Marino       __first = _GLIBCXX_STD_A::adjacent_find(__first, __last);
1211*e4b17023SJohn Marino       if (__first == __last)
1212*e4b17023SJohn Marino 	return __last;
1213*e4b17023SJohn Marino 
1214*e4b17023SJohn Marino       // Do the real copy work.
1215*e4b17023SJohn Marino       _ForwardIterator __dest = __first;
1216*e4b17023SJohn Marino       ++__first;
1217*e4b17023SJohn Marino       while (++__first != __last)
1218*e4b17023SJohn Marino 	if (!(*__dest == *__first))
1219*e4b17023SJohn Marino 	  *++__dest = _GLIBCXX_MOVE(*__first);
1220*e4b17023SJohn Marino       return ++__dest;
1221*e4b17023SJohn Marino     }
1222*e4b17023SJohn Marino 
1223*e4b17023SJohn Marino   /**
1224*e4b17023SJohn Marino    *  @brief Remove consecutive values from a sequence using a predicate.
1225*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
1226*e4b17023SJohn Marino    *  @param  __first        A forward iterator.
1227*e4b17023SJohn Marino    *  @param  __last         A forward iterator.
1228*e4b17023SJohn Marino    *  @param  __binary_pred  A binary predicate.
1229*e4b17023SJohn Marino    *  @return  An iterator designating the end of the resulting sequence.
1230*e4b17023SJohn Marino    *
1231*e4b17023SJohn Marino    *  Removes all but the first element from each group of consecutive
1232*e4b17023SJohn Marino    *  values for which @p __binary_pred returns true.
1233*e4b17023SJohn Marino    *  unique() is stable, so the relative order of elements that are
1234*e4b17023SJohn Marino    *  not removed is unchanged.
1235*e4b17023SJohn Marino    *  Elements between the end of the resulting sequence and @p __last
1236*e4b17023SJohn Marino    *  are still present, but their value is unspecified.
1237*e4b17023SJohn Marino   */
1238*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _BinaryPredicate>
1239*e4b17023SJohn Marino     _ForwardIterator
1240*e4b17023SJohn Marino     unique(_ForwardIterator __first, _ForwardIterator __last,
1241*e4b17023SJohn Marino            _BinaryPredicate __binary_pred)
1242*e4b17023SJohn Marino     {
1243*e4b17023SJohn Marino       // concept requirements
1244*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1245*e4b17023SJohn Marino 				  _ForwardIterator>)
1246*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
1247*e4b17023SJohn Marino 		typename iterator_traits<_ForwardIterator>::value_type,
1248*e4b17023SJohn Marino 		typename iterator_traits<_ForwardIterator>::value_type>)
1249*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
1250*e4b17023SJohn Marino 
1251*e4b17023SJohn Marino       // Skip the beginning, if already unique.
1252*e4b17023SJohn Marino       __first = _GLIBCXX_STD_A::adjacent_find(__first, __last, __binary_pred);
1253*e4b17023SJohn Marino       if (__first == __last)
1254*e4b17023SJohn Marino 	return __last;
1255*e4b17023SJohn Marino 
1256*e4b17023SJohn Marino       // Do the real copy work.
1257*e4b17023SJohn Marino       _ForwardIterator __dest = __first;
1258*e4b17023SJohn Marino       ++__first;
1259*e4b17023SJohn Marino       while (++__first != __last)
1260*e4b17023SJohn Marino 	if (!bool(__binary_pred(*__dest, *__first)))
1261*e4b17023SJohn Marino 	  *++__dest = _GLIBCXX_MOVE(*__first);
1262*e4b17023SJohn Marino       return ++__dest;
1263*e4b17023SJohn Marino     }
1264*e4b17023SJohn Marino 
1265*e4b17023SJohn Marino   /**
1266*e4b17023SJohn Marino    *  This is an uglified unique_copy(_InputIterator, _InputIterator,
1267*e4b17023SJohn Marino    *                                  _OutputIterator)
1268*e4b17023SJohn Marino    *  overloaded for forward iterators and output iterator as result.
1269*e4b17023SJohn Marino   */
1270*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _OutputIterator>
1271*e4b17023SJohn Marino     _OutputIterator
1272*e4b17023SJohn Marino     __unique_copy(_ForwardIterator __first, _ForwardIterator __last,
1273*e4b17023SJohn Marino 		  _OutputIterator __result,
1274*e4b17023SJohn Marino 		  forward_iterator_tag, output_iterator_tag)
1275*e4b17023SJohn Marino     {
1276*e4b17023SJohn Marino       // concept requirements -- taken care of in dispatching function
1277*e4b17023SJohn Marino       _ForwardIterator __next = __first;
1278*e4b17023SJohn Marino       *__result = *__first;
1279*e4b17023SJohn Marino       while (++__next != __last)
1280*e4b17023SJohn Marino 	if (!(*__first == *__next))
1281*e4b17023SJohn Marino 	  {
1282*e4b17023SJohn Marino 	    __first = __next;
1283*e4b17023SJohn Marino 	    *++__result = *__first;
1284*e4b17023SJohn Marino 	  }
1285*e4b17023SJohn Marino       return ++__result;
1286*e4b17023SJohn Marino     }
1287*e4b17023SJohn Marino 
1288*e4b17023SJohn Marino   /**
1289*e4b17023SJohn Marino    *  This is an uglified unique_copy(_InputIterator, _InputIterator,
1290*e4b17023SJohn Marino    *                                  _OutputIterator)
1291*e4b17023SJohn Marino    *  overloaded for input iterators and output iterator as result.
1292*e4b17023SJohn Marino   */
1293*e4b17023SJohn Marino   template<typename _InputIterator, typename _OutputIterator>
1294*e4b17023SJohn Marino     _OutputIterator
1295*e4b17023SJohn Marino     __unique_copy(_InputIterator __first, _InputIterator __last,
1296*e4b17023SJohn Marino 		  _OutputIterator __result,
1297*e4b17023SJohn Marino 		  input_iterator_tag, output_iterator_tag)
1298*e4b17023SJohn Marino     {
1299*e4b17023SJohn Marino       // concept requirements -- taken care of in dispatching function
1300*e4b17023SJohn Marino       typename iterator_traits<_InputIterator>::value_type __value = *__first;
1301*e4b17023SJohn Marino       *__result = __value;
1302*e4b17023SJohn Marino       while (++__first != __last)
1303*e4b17023SJohn Marino 	if (!(__value == *__first))
1304*e4b17023SJohn Marino 	  {
1305*e4b17023SJohn Marino 	    __value = *__first;
1306*e4b17023SJohn Marino 	    *++__result = __value;
1307*e4b17023SJohn Marino 	  }
1308*e4b17023SJohn Marino       return ++__result;
1309*e4b17023SJohn Marino     }
1310*e4b17023SJohn Marino 
1311*e4b17023SJohn Marino   /**
1312*e4b17023SJohn Marino    *  This is an uglified unique_copy(_InputIterator, _InputIterator,
1313*e4b17023SJohn Marino    *                                  _OutputIterator)
1314*e4b17023SJohn Marino    *  overloaded for input iterators and forward iterator as result.
1315*e4b17023SJohn Marino   */
1316*e4b17023SJohn Marino   template<typename _InputIterator, typename _ForwardIterator>
1317*e4b17023SJohn Marino     _ForwardIterator
1318*e4b17023SJohn Marino     __unique_copy(_InputIterator __first, _InputIterator __last,
1319*e4b17023SJohn Marino 		  _ForwardIterator __result,
1320*e4b17023SJohn Marino 		  input_iterator_tag, forward_iterator_tag)
1321*e4b17023SJohn Marino     {
1322*e4b17023SJohn Marino       // concept requirements -- taken care of in dispatching function
1323*e4b17023SJohn Marino       *__result = *__first;
1324*e4b17023SJohn Marino       while (++__first != __last)
1325*e4b17023SJohn Marino 	if (!(*__result == *__first))
1326*e4b17023SJohn Marino 	  *++__result = *__first;
1327*e4b17023SJohn Marino       return ++__result;
1328*e4b17023SJohn Marino     }
1329*e4b17023SJohn Marino 
1330*e4b17023SJohn Marino   /**
1331*e4b17023SJohn Marino    *  This is an uglified
1332*e4b17023SJohn Marino    *  unique_copy(_InputIterator, _InputIterator, _OutputIterator,
1333*e4b17023SJohn Marino    *              _BinaryPredicate)
1334*e4b17023SJohn Marino    *  overloaded for forward iterators and output iterator as result.
1335*e4b17023SJohn Marino   */
1336*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _OutputIterator,
1337*e4b17023SJohn Marino 	   typename _BinaryPredicate>
1338*e4b17023SJohn Marino     _OutputIterator
1339*e4b17023SJohn Marino     __unique_copy(_ForwardIterator __first, _ForwardIterator __last,
1340*e4b17023SJohn Marino 		  _OutputIterator __result, _BinaryPredicate __binary_pred,
1341*e4b17023SJohn Marino 		  forward_iterator_tag, output_iterator_tag)
1342*e4b17023SJohn Marino     {
1343*e4b17023SJohn Marino       // concept requirements -- iterators already checked
1344*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
1345*e4b17023SJohn Marino 	  typename iterator_traits<_ForwardIterator>::value_type,
1346*e4b17023SJohn Marino 	  typename iterator_traits<_ForwardIterator>::value_type>)
1347*e4b17023SJohn Marino 
1348*e4b17023SJohn Marino       _ForwardIterator __next = __first;
1349*e4b17023SJohn Marino       *__result = *__first;
1350*e4b17023SJohn Marino       while (++__next != __last)
1351*e4b17023SJohn Marino 	if (!bool(__binary_pred(*__first, *__next)))
1352*e4b17023SJohn Marino 	  {
1353*e4b17023SJohn Marino 	    __first = __next;
1354*e4b17023SJohn Marino 	    *++__result = *__first;
1355*e4b17023SJohn Marino 	  }
1356*e4b17023SJohn Marino       return ++__result;
1357*e4b17023SJohn Marino     }
1358*e4b17023SJohn Marino 
1359*e4b17023SJohn Marino   /**
1360*e4b17023SJohn Marino    *  This is an uglified
1361*e4b17023SJohn Marino    *  unique_copy(_InputIterator, _InputIterator, _OutputIterator,
1362*e4b17023SJohn Marino    *              _BinaryPredicate)
1363*e4b17023SJohn Marino    *  overloaded for input iterators and output iterator as result.
1364*e4b17023SJohn Marino   */
1365*e4b17023SJohn Marino   template<typename _InputIterator, typename _OutputIterator,
1366*e4b17023SJohn Marino 	   typename _BinaryPredicate>
1367*e4b17023SJohn Marino     _OutputIterator
1368*e4b17023SJohn Marino     __unique_copy(_InputIterator __first, _InputIterator __last,
1369*e4b17023SJohn Marino 		  _OutputIterator __result, _BinaryPredicate __binary_pred,
1370*e4b17023SJohn Marino 		  input_iterator_tag, output_iterator_tag)
1371*e4b17023SJohn Marino     {
1372*e4b17023SJohn Marino       // concept requirements -- iterators already checked
1373*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
1374*e4b17023SJohn Marino 	  typename iterator_traits<_InputIterator>::value_type,
1375*e4b17023SJohn Marino 	  typename iterator_traits<_InputIterator>::value_type>)
1376*e4b17023SJohn Marino 
1377*e4b17023SJohn Marino       typename iterator_traits<_InputIterator>::value_type __value = *__first;
1378*e4b17023SJohn Marino       *__result = __value;
1379*e4b17023SJohn Marino       while (++__first != __last)
1380*e4b17023SJohn Marino 	if (!bool(__binary_pred(__value, *__first)))
1381*e4b17023SJohn Marino 	  {
1382*e4b17023SJohn Marino 	    __value = *__first;
1383*e4b17023SJohn Marino 	    *++__result = __value;
1384*e4b17023SJohn Marino 	  }
1385*e4b17023SJohn Marino       return ++__result;
1386*e4b17023SJohn Marino     }
1387*e4b17023SJohn Marino 
1388*e4b17023SJohn Marino   /**
1389*e4b17023SJohn Marino    *  This is an uglified
1390*e4b17023SJohn Marino    *  unique_copy(_InputIterator, _InputIterator, _OutputIterator,
1391*e4b17023SJohn Marino    *              _BinaryPredicate)
1392*e4b17023SJohn Marino    *  overloaded for input iterators and forward iterator as result.
1393*e4b17023SJohn Marino   */
1394*e4b17023SJohn Marino   template<typename _InputIterator, typename _ForwardIterator,
1395*e4b17023SJohn Marino 	   typename _BinaryPredicate>
1396*e4b17023SJohn Marino     _ForwardIterator
1397*e4b17023SJohn Marino     __unique_copy(_InputIterator __first, _InputIterator __last,
1398*e4b17023SJohn Marino 		  _ForwardIterator __result, _BinaryPredicate __binary_pred,
1399*e4b17023SJohn Marino 		  input_iterator_tag, forward_iterator_tag)
1400*e4b17023SJohn Marino     {
1401*e4b17023SJohn Marino       // concept requirements -- iterators already checked
1402*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
1403*e4b17023SJohn Marino 	  typename iterator_traits<_ForwardIterator>::value_type,
1404*e4b17023SJohn Marino 	  typename iterator_traits<_InputIterator>::value_type>)
1405*e4b17023SJohn Marino 
1406*e4b17023SJohn Marino       *__result = *__first;
1407*e4b17023SJohn Marino       while (++__first != __last)
1408*e4b17023SJohn Marino 	if (!bool(__binary_pred(*__result, *__first)))
1409*e4b17023SJohn Marino 	  *++__result = *__first;
1410*e4b17023SJohn Marino       return ++__result;
1411*e4b17023SJohn Marino     }
1412*e4b17023SJohn Marino 
1413*e4b17023SJohn Marino   /**
1414*e4b17023SJohn Marino    *  This is an uglified reverse(_BidirectionalIterator,
1415*e4b17023SJohn Marino    *                              _BidirectionalIterator)
1416*e4b17023SJohn Marino    *  overloaded for bidirectional iterators.
1417*e4b17023SJohn Marino   */
1418*e4b17023SJohn Marino   template<typename _BidirectionalIterator>
1419*e4b17023SJohn Marino     void
1420*e4b17023SJohn Marino     __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last,
1421*e4b17023SJohn Marino 	      bidirectional_iterator_tag)
1422*e4b17023SJohn Marino     {
1423*e4b17023SJohn Marino       while (true)
1424*e4b17023SJohn Marino 	if (__first == __last || __first == --__last)
1425*e4b17023SJohn Marino 	  return;
1426*e4b17023SJohn Marino 	else
1427*e4b17023SJohn Marino 	  {
1428*e4b17023SJohn Marino 	    std::iter_swap(__first, __last);
1429*e4b17023SJohn Marino 	    ++__first;
1430*e4b17023SJohn Marino 	  }
1431*e4b17023SJohn Marino     }
1432*e4b17023SJohn Marino 
1433*e4b17023SJohn Marino   /**
1434*e4b17023SJohn Marino    *  This is an uglified reverse(_BidirectionalIterator,
1435*e4b17023SJohn Marino    *                              _BidirectionalIterator)
1436*e4b17023SJohn Marino    *  overloaded for random access iterators.
1437*e4b17023SJohn Marino   */
1438*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
1439*e4b17023SJohn Marino     void
1440*e4b17023SJohn Marino     __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last,
1441*e4b17023SJohn Marino 	      random_access_iterator_tag)
1442*e4b17023SJohn Marino     {
1443*e4b17023SJohn Marino       if (__first == __last)
1444*e4b17023SJohn Marino 	return;
1445*e4b17023SJohn Marino       --__last;
1446*e4b17023SJohn Marino       while (__first < __last)
1447*e4b17023SJohn Marino 	{
1448*e4b17023SJohn Marino 	  std::iter_swap(__first, __last);
1449*e4b17023SJohn Marino 	  ++__first;
1450*e4b17023SJohn Marino 	  --__last;
1451*e4b17023SJohn Marino 	}
1452*e4b17023SJohn Marino     }
1453*e4b17023SJohn Marino 
1454*e4b17023SJohn Marino   /**
1455*e4b17023SJohn Marino    *  @brief Reverse a sequence.
1456*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
1457*e4b17023SJohn Marino    *  @param  __first  A bidirectional iterator.
1458*e4b17023SJohn Marino    *  @param  __last   A bidirectional iterator.
1459*e4b17023SJohn Marino    *  @return   reverse() returns no value.
1460*e4b17023SJohn Marino    *
1461*e4b17023SJohn Marino    *  Reverses the order of the elements in the range @p [__first,__last),
1462*e4b17023SJohn Marino    *  so that the first element becomes the last etc.
1463*e4b17023SJohn Marino    *  For every @c i such that @p 0<=i<=(__last-__first)/2), @p reverse()
1464*e4b17023SJohn Marino    *  swaps @p *(__first+i) and @p *(__last-(i+1))
1465*e4b17023SJohn Marino   */
1466*e4b17023SJohn Marino   template<typename _BidirectionalIterator>
1467*e4b17023SJohn Marino     inline void
1468*e4b17023SJohn Marino     reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
1469*e4b17023SJohn Marino     {
1470*e4b17023SJohn Marino       // concept requirements
1471*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
1472*e4b17023SJohn Marino 				  _BidirectionalIterator>)
1473*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
1474*e4b17023SJohn Marino       std::__reverse(__first, __last, std::__iterator_category(__first));
1475*e4b17023SJohn Marino     }
1476*e4b17023SJohn Marino 
1477*e4b17023SJohn Marino   /**
1478*e4b17023SJohn Marino    *  @brief Copy a sequence, reversing its elements.
1479*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
1480*e4b17023SJohn Marino    *  @param  __first   A bidirectional iterator.
1481*e4b17023SJohn Marino    *  @param  __last    A bidirectional iterator.
1482*e4b17023SJohn Marino    *  @param  __result  An output iterator.
1483*e4b17023SJohn Marino    *  @return  An iterator designating the end of the resulting sequence.
1484*e4b17023SJohn Marino    *
1485*e4b17023SJohn Marino    *  Copies the elements in the range @p [__first,__last) to the
1486*e4b17023SJohn Marino    *  range @p [__result,__result+(__last-__first)) such that the
1487*e4b17023SJohn Marino    *  order of the elements is reversed.  For every @c i such that @p
1488*e4b17023SJohn Marino    *  0<=i<=(__last-__first), @p reverse_copy() performs the
1489*e4b17023SJohn Marino    *  assignment @p *(__result+(__last-__first)-i) = *(__first+i).
1490*e4b17023SJohn Marino    *  The ranges @p [__first,__last) and @p
1491*e4b17023SJohn Marino    *  [__result,__result+(__last-__first)) must not overlap.
1492*e4b17023SJohn Marino   */
1493*e4b17023SJohn Marino   template<typename _BidirectionalIterator, typename _OutputIterator>
1494*e4b17023SJohn Marino     _OutputIterator
1495*e4b17023SJohn Marino     reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last,
1496*e4b17023SJohn Marino 		 _OutputIterator __result)
1497*e4b17023SJohn Marino     {
1498*e4b17023SJohn Marino       // concept requirements
1499*e4b17023SJohn Marino       __glibcxx_function_requires(_BidirectionalIteratorConcept<
1500*e4b17023SJohn Marino 				  _BidirectionalIterator>)
1501*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
1502*e4b17023SJohn Marino 		typename iterator_traits<_BidirectionalIterator>::value_type>)
1503*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
1504*e4b17023SJohn Marino 
1505*e4b17023SJohn Marino       while (__first != __last)
1506*e4b17023SJohn Marino 	{
1507*e4b17023SJohn Marino 	  --__last;
1508*e4b17023SJohn Marino 	  *__result = *__last;
1509*e4b17023SJohn Marino 	  ++__result;
1510*e4b17023SJohn Marino 	}
1511*e4b17023SJohn Marino       return __result;
1512*e4b17023SJohn Marino     }
1513*e4b17023SJohn Marino 
1514*e4b17023SJohn Marino   /**
1515*e4b17023SJohn Marino    *  This is a helper function for the rotate algorithm specialized on RAIs.
1516*e4b17023SJohn Marino    *  It returns the greatest common divisor of two integer values.
1517*e4b17023SJohn Marino   */
1518*e4b17023SJohn Marino   template<typename _EuclideanRingElement>
1519*e4b17023SJohn Marino     _EuclideanRingElement
1520*e4b17023SJohn Marino     __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n)
1521*e4b17023SJohn Marino     {
1522*e4b17023SJohn Marino       while (__n != 0)
1523*e4b17023SJohn Marino 	{
1524*e4b17023SJohn Marino 	  _EuclideanRingElement __t = __m % __n;
1525*e4b17023SJohn Marino 	  __m = __n;
1526*e4b17023SJohn Marino 	  __n = __t;
1527*e4b17023SJohn Marino 	}
1528*e4b17023SJohn Marino       return __m;
1529*e4b17023SJohn Marino     }
1530*e4b17023SJohn Marino 
1531*e4b17023SJohn Marino   /// This is a helper function for the rotate algorithm.
1532*e4b17023SJohn Marino   template<typename _ForwardIterator>
1533*e4b17023SJohn Marino     void
1534*e4b17023SJohn Marino     __rotate(_ForwardIterator __first,
1535*e4b17023SJohn Marino 	     _ForwardIterator __middle,
1536*e4b17023SJohn Marino 	     _ForwardIterator __last,
1537*e4b17023SJohn Marino 	     forward_iterator_tag)
1538*e4b17023SJohn Marino     {
1539*e4b17023SJohn Marino       if (__first == __middle || __last  == __middle)
1540*e4b17023SJohn Marino 	return;
1541*e4b17023SJohn Marino 
1542*e4b17023SJohn Marino       _ForwardIterator __first2 = __middle;
1543*e4b17023SJohn Marino       do
1544*e4b17023SJohn Marino 	{
1545*e4b17023SJohn Marino 	  std::iter_swap(__first, __first2);
1546*e4b17023SJohn Marino 	  ++__first;
1547*e4b17023SJohn Marino 	  ++__first2;
1548*e4b17023SJohn Marino 	  if (__first == __middle)
1549*e4b17023SJohn Marino 	    __middle = __first2;
1550*e4b17023SJohn Marino 	}
1551*e4b17023SJohn Marino       while (__first2 != __last);
1552*e4b17023SJohn Marino 
1553*e4b17023SJohn Marino       __first2 = __middle;
1554*e4b17023SJohn Marino 
1555*e4b17023SJohn Marino       while (__first2 != __last)
1556*e4b17023SJohn Marino 	{
1557*e4b17023SJohn Marino 	  std::iter_swap(__first, __first2);
1558*e4b17023SJohn Marino 	  ++__first;
1559*e4b17023SJohn Marino 	  ++__first2;
1560*e4b17023SJohn Marino 	  if (__first == __middle)
1561*e4b17023SJohn Marino 	    __middle = __first2;
1562*e4b17023SJohn Marino 	  else if (__first2 == __last)
1563*e4b17023SJohn Marino 	    __first2 = __middle;
1564*e4b17023SJohn Marino 	}
1565*e4b17023SJohn Marino     }
1566*e4b17023SJohn Marino 
1567*e4b17023SJohn Marino    /// This is a helper function for the rotate algorithm.
1568*e4b17023SJohn Marino   template<typename _BidirectionalIterator>
1569*e4b17023SJohn Marino     void
1570*e4b17023SJohn Marino     __rotate(_BidirectionalIterator __first,
1571*e4b17023SJohn Marino 	     _BidirectionalIterator __middle,
1572*e4b17023SJohn Marino 	     _BidirectionalIterator __last,
1573*e4b17023SJohn Marino 	      bidirectional_iterator_tag)
1574*e4b17023SJohn Marino     {
1575*e4b17023SJohn Marino       // concept requirements
1576*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
1577*e4b17023SJohn Marino 				  _BidirectionalIterator>)
1578*e4b17023SJohn Marino 
1579*e4b17023SJohn Marino       if (__first == __middle || __last  == __middle)
1580*e4b17023SJohn Marino 	return;
1581*e4b17023SJohn Marino 
1582*e4b17023SJohn Marino       std::__reverse(__first,  __middle, bidirectional_iterator_tag());
1583*e4b17023SJohn Marino       std::__reverse(__middle, __last,   bidirectional_iterator_tag());
1584*e4b17023SJohn Marino 
1585*e4b17023SJohn Marino       while (__first != __middle && __middle != __last)
1586*e4b17023SJohn Marino 	{
1587*e4b17023SJohn Marino 	  std::iter_swap(__first, --__last);
1588*e4b17023SJohn Marino 	  ++__first;
1589*e4b17023SJohn Marino 	}
1590*e4b17023SJohn Marino 
1591*e4b17023SJohn Marino       if (__first == __middle)
1592*e4b17023SJohn Marino 	std::__reverse(__middle, __last,   bidirectional_iterator_tag());
1593*e4b17023SJohn Marino       else
1594*e4b17023SJohn Marino 	std::__reverse(__first,  __middle, bidirectional_iterator_tag());
1595*e4b17023SJohn Marino     }
1596*e4b17023SJohn Marino 
1597*e4b17023SJohn Marino   /// This is a helper function for the rotate algorithm.
1598*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
1599*e4b17023SJohn Marino     void
1600*e4b17023SJohn Marino     __rotate(_RandomAccessIterator __first,
1601*e4b17023SJohn Marino 	     _RandomAccessIterator __middle,
1602*e4b17023SJohn Marino 	     _RandomAccessIterator __last,
1603*e4b17023SJohn Marino 	     random_access_iterator_tag)
1604*e4b17023SJohn Marino     {
1605*e4b17023SJohn Marino       // concept requirements
1606*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
1607*e4b17023SJohn Marino 				  _RandomAccessIterator>)
1608*e4b17023SJohn Marino 
1609*e4b17023SJohn Marino       if (__first == __middle || __last  == __middle)
1610*e4b17023SJohn Marino 	return;
1611*e4b17023SJohn Marino 
1612*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
1613*e4b17023SJohn Marino 	_Distance;
1614*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
1615*e4b17023SJohn Marino 	_ValueType;
1616*e4b17023SJohn Marino 
1617*e4b17023SJohn Marino       _Distance __n = __last   - __first;
1618*e4b17023SJohn Marino       _Distance __k = __middle - __first;
1619*e4b17023SJohn Marino 
1620*e4b17023SJohn Marino       if (__k == __n - __k)
1621*e4b17023SJohn Marino 	{
1622*e4b17023SJohn Marino 	  std::swap_ranges(__first, __middle, __middle);
1623*e4b17023SJohn Marino 	  return;
1624*e4b17023SJohn Marino 	}
1625*e4b17023SJohn Marino 
1626*e4b17023SJohn Marino       _RandomAccessIterator __p = __first;
1627*e4b17023SJohn Marino 
1628*e4b17023SJohn Marino       for (;;)
1629*e4b17023SJohn Marino 	{
1630*e4b17023SJohn Marino 	  if (__k < __n - __k)
1631*e4b17023SJohn Marino 	    {
1632*e4b17023SJohn Marino 	      if (__is_pod(_ValueType) && __k == 1)
1633*e4b17023SJohn Marino 		{
1634*e4b17023SJohn Marino 		  _ValueType __t = _GLIBCXX_MOVE(*__p);
1635*e4b17023SJohn Marino 		  _GLIBCXX_MOVE3(__p + 1, __p + __n, __p);
1636*e4b17023SJohn Marino 		  *(__p + __n - 1) = _GLIBCXX_MOVE(__t);
1637*e4b17023SJohn Marino 		  return;
1638*e4b17023SJohn Marino 		}
1639*e4b17023SJohn Marino 	      _RandomAccessIterator __q = __p + __k;
1640*e4b17023SJohn Marino 	      for (_Distance __i = 0; __i < __n - __k; ++ __i)
1641*e4b17023SJohn Marino 		{
1642*e4b17023SJohn Marino 		  std::iter_swap(__p, __q);
1643*e4b17023SJohn Marino 		  ++__p;
1644*e4b17023SJohn Marino 		  ++__q;
1645*e4b17023SJohn Marino 		}
1646*e4b17023SJohn Marino 	      __n %= __k;
1647*e4b17023SJohn Marino 	      if (__n == 0)
1648*e4b17023SJohn Marino 		return;
1649*e4b17023SJohn Marino 	      std::swap(__n, __k);
1650*e4b17023SJohn Marino 	      __k = __n - __k;
1651*e4b17023SJohn Marino 	    }
1652*e4b17023SJohn Marino 	  else
1653*e4b17023SJohn Marino 	    {
1654*e4b17023SJohn Marino 	      __k = __n - __k;
1655*e4b17023SJohn Marino 	      if (__is_pod(_ValueType) && __k == 1)
1656*e4b17023SJohn Marino 		{
1657*e4b17023SJohn Marino 		  _ValueType __t = _GLIBCXX_MOVE(*(__p + __n - 1));
1658*e4b17023SJohn Marino 		  _GLIBCXX_MOVE_BACKWARD3(__p, __p + __n - 1, __p + __n);
1659*e4b17023SJohn Marino 		  *__p = _GLIBCXX_MOVE(__t);
1660*e4b17023SJohn Marino 		  return;
1661*e4b17023SJohn Marino 		}
1662*e4b17023SJohn Marino 	      _RandomAccessIterator __q = __p + __n;
1663*e4b17023SJohn Marino 	      __p = __q - __k;
1664*e4b17023SJohn Marino 	      for (_Distance __i = 0; __i < __n - __k; ++ __i)
1665*e4b17023SJohn Marino 		{
1666*e4b17023SJohn Marino 		  --__p;
1667*e4b17023SJohn Marino 		  --__q;
1668*e4b17023SJohn Marino 		  std::iter_swap(__p, __q);
1669*e4b17023SJohn Marino 		}
1670*e4b17023SJohn Marino 	      __n %= __k;
1671*e4b17023SJohn Marino 	      if (__n == 0)
1672*e4b17023SJohn Marino 		return;
1673*e4b17023SJohn Marino 	      std::swap(__n, __k);
1674*e4b17023SJohn Marino 	    }
1675*e4b17023SJohn Marino 	}
1676*e4b17023SJohn Marino     }
1677*e4b17023SJohn Marino 
1678*e4b17023SJohn Marino   /**
1679*e4b17023SJohn Marino    *  @brief Rotate the elements of a sequence.
1680*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
1681*e4b17023SJohn Marino    *  @param  __first   A forward iterator.
1682*e4b17023SJohn Marino    *  @param  __middle  A forward iterator.
1683*e4b17023SJohn Marino    *  @param  __last    A forward iterator.
1684*e4b17023SJohn Marino    *  @return  Nothing.
1685*e4b17023SJohn Marino    *
1686*e4b17023SJohn Marino    *  Rotates the elements of the range @p [__first,__last) by
1687*e4b17023SJohn Marino    *  @p (__middle - __first) positions so that the element at @p __middle
1688*e4b17023SJohn Marino    *  is moved to @p __first, the element at @p __middle+1 is moved to
1689*e4b17023SJohn Marino    *  @p __first+1 and so on for each element in the range
1690*e4b17023SJohn Marino    *  @p [__first,__last).
1691*e4b17023SJohn Marino    *
1692*e4b17023SJohn Marino    *  This effectively swaps the ranges @p [__first,__middle) and
1693*e4b17023SJohn Marino    *  @p [__middle,__last).
1694*e4b17023SJohn Marino    *
1695*e4b17023SJohn Marino    *  Performs
1696*e4b17023SJohn Marino    *   @p *(__first+(n+(__last-__middle))%(__last-__first))=*(__first+n)
1697*e4b17023SJohn Marino    *  for each @p n in the range @p [0,__last-__first).
1698*e4b17023SJohn Marino   */
1699*e4b17023SJohn Marino   template<typename _ForwardIterator>
1700*e4b17023SJohn Marino     inline void
1701*e4b17023SJohn Marino     rotate(_ForwardIterator __first, _ForwardIterator __middle,
1702*e4b17023SJohn Marino 	   _ForwardIterator __last)
1703*e4b17023SJohn Marino     {
1704*e4b17023SJohn Marino       // concept requirements
1705*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1706*e4b17023SJohn Marino 				  _ForwardIterator>)
1707*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __middle);
1708*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__middle, __last);
1709*e4b17023SJohn Marino 
1710*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::iterator_category
1711*e4b17023SJohn Marino 	_IterType;
1712*e4b17023SJohn Marino       std::__rotate(__first, __middle, __last, _IterType());
1713*e4b17023SJohn Marino     }
1714*e4b17023SJohn Marino 
1715*e4b17023SJohn Marino   /**
1716*e4b17023SJohn Marino    *  @brief Copy a sequence, rotating its elements.
1717*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
1718*e4b17023SJohn Marino    *  @param  __first   A forward iterator.
1719*e4b17023SJohn Marino    *  @param  __middle  A forward iterator.
1720*e4b17023SJohn Marino    *  @param  __last    A forward iterator.
1721*e4b17023SJohn Marino    *  @param  __result  An output iterator.
1722*e4b17023SJohn Marino    *  @return   An iterator designating the end of the resulting sequence.
1723*e4b17023SJohn Marino    *
1724*e4b17023SJohn Marino    *  Copies the elements of the range @p [__first,__last) to the
1725*e4b17023SJohn Marino    *  range beginning at @result, rotating the copied elements by
1726*e4b17023SJohn Marino    *  @p (__middle-__first) positions so that the element at @p __middle
1727*e4b17023SJohn Marino    *  is moved to @p __result, the element at @p __middle+1 is moved
1728*e4b17023SJohn Marino    *  to @p __result+1 and so on for each element in the range @p
1729*e4b17023SJohn Marino    *  [__first,__last).
1730*e4b17023SJohn Marino    *
1731*e4b17023SJohn Marino    *  Performs
1732*e4b17023SJohn Marino    *  @p *(__result+(n+(__last-__middle))%(__last-__first))=*(__first+n)
1733*e4b17023SJohn Marino    *  for each @p n in the range @p [0,__last-__first).
1734*e4b17023SJohn Marino   */
1735*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _OutputIterator>
1736*e4b17023SJohn Marino     _OutputIterator
1737*e4b17023SJohn Marino     rotate_copy(_ForwardIterator __first, _ForwardIterator __middle,
1738*e4b17023SJohn Marino                 _ForwardIterator __last, _OutputIterator __result)
1739*e4b17023SJohn Marino     {
1740*e4b17023SJohn Marino       // concept requirements
1741*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1742*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
1743*e4b17023SJohn Marino 		typename iterator_traits<_ForwardIterator>::value_type>)
1744*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __middle);
1745*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__middle, __last);
1746*e4b17023SJohn Marino 
1747*e4b17023SJohn Marino       return std::copy(__first, __middle,
1748*e4b17023SJohn Marino                        std::copy(__middle, __last, __result));
1749*e4b17023SJohn Marino     }
1750*e4b17023SJohn Marino 
1751*e4b17023SJohn Marino   /// This is a helper function...
1752*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Predicate>
1753*e4b17023SJohn Marino     _ForwardIterator
1754*e4b17023SJohn Marino     __partition(_ForwardIterator __first, _ForwardIterator __last,
1755*e4b17023SJohn Marino 		_Predicate __pred, forward_iterator_tag)
1756*e4b17023SJohn Marino     {
1757*e4b17023SJohn Marino       if (__first == __last)
1758*e4b17023SJohn Marino 	return __first;
1759*e4b17023SJohn Marino 
1760*e4b17023SJohn Marino       while (__pred(*__first))
1761*e4b17023SJohn Marino 	if (++__first == __last)
1762*e4b17023SJohn Marino 	  return __first;
1763*e4b17023SJohn Marino 
1764*e4b17023SJohn Marino       _ForwardIterator __next = __first;
1765*e4b17023SJohn Marino 
1766*e4b17023SJohn Marino       while (++__next != __last)
1767*e4b17023SJohn Marino 	if (__pred(*__next))
1768*e4b17023SJohn Marino 	  {
1769*e4b17023SJohn Marino 	    std::iter_swap(__first, __next);
1770*e4b17023SJohn Marino 	    ++__first;
1771*e4b17023SJohn Marino 	  }
1772*e4b17023SJohn Marino 
1773*e4b17023SJohn Marino       return __first;
1774*e4b17023SJohn Marino     }
1775*e4b17023SJohn Marino 
1776*e4b17023SJohn Marino   /// This is a helper function...
1777*e4b17023SJohn Marino   template<typename _BidirectionalIterator, typename _Predicate>
1778*e4b17023SJohn Marino     _BidirectionalIterator
1779*e4b17023SJohn Marino     __partition(_BidirectionalIterator __first, _BidirectionalIterator __last,
1780*e4b17023SJohn Marino 		_Predicate __pred, bidirectional_iterator_tag)
1781*e4b17023SJohn Marino     {
1782*e4b17023SJohn Marino       while (true)
1783*e4b17023SJohn Marino 	{
1784*e4b17023SJohn Marino 	  while (true)
1785*e4b17023SJohn Marino 	    if (__first == __last)
1786*e4b17023SJohn Marino 	      return __first;
1787*e4b17023SJohn Marino 	    else if (__pred(*__first))
1788*e4b17023SJohn Marino 	      ++__first;
1789*e4b17023SJohn Marino 	    else
1790*e4b17023SJohn Marino 	      break;
1791*e4b17023SJohn Marino 	  --__last;
1792*e4b17023SJohn Marino 	  while (true)
1793*e4b17023SJohn Marino 	    if (__first == __last)
1794*e4b17023SJohn Marino 	      return __first;
1795*e4b17023SJohn Marino 	    else if (!bool(__pred(*__last)))
1796*e4b17023SJohn Marino 	      --__last;
1797*e4b17023SJohn Marino 	    else
1798*e4b17023SJohn Marino 	      break;
1799*e4b17023SJohn Marino 	  std::iter_swap(__first, __last);
1800*e4b17023SJohn Marino 	  ++__first;
1801*e4b17023SJohn Marino 	}
1802*e4b17023SJohn Marino     }
1803*e4b17023SJohn Marino 
1804*e4b17023SJohn Marino   // partition
1805*e4b17023SJohn Marino 
1806*e4b17023SJohn Marino   /// This is a helper function...
1807*e4b17023SJohn Marino   /// Requires __len != 0 and !__pred(*__first),
1808*e4b17023SJohn Marino   /// same as __stable_partition_adaptive.
1809*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Predicate, typename _Distance>
1810*e4b17023SJohn Marino     _ForwardIterator
1811*e4b17023SJohn Marino     __inplace_stable_partition(_ForwardIterator __first,
1812*e4b17023SJohn Marino 			       _Predicate __pred, _Distance __len)
1813*e4b17023SJohn Marino     {
1814*e4b17023SJohn Marino       if (__len == 1)
1815*e4b17023SJohn Marino 	return __first;
1816*e4b17023SJohn Marino       _ForwardIterator __middle = __first;
1817*e4b17023SJohn Marino       std::advance(__middle, __len / 2);
1818*e4b17023SJohn Marino       _ForwardIterator __left_split =
1819*e4b17023SJohn Marino 	std::__inplace_stable_partition(__first, __pred, __len / 2);
1820*e4b17023SJohn Marino       // Advance past true-predicate values to satisfy this
1821*e4b17023SJohn Marino       // function's preconditions.
1822*e4b17023SJohn Marino       _Distance __right_len = __len - __len / 2;
1823*e4b17023SJohn Marino       _ForwardIterator __right_split =
1824*e4b17023SJohn Marino 	std::__find_if_not_n(__middle, __right_len, __pred);
1825*e4b17023SJohn Marino       if (__right_len)
1826*e4b17023SJohn Marino 	__right_split = std::__inplace_stable_partition(__middle,
1827*e4b17023SJohn Marino 							__pred,
1828*e4b17023SJohn Marino 							__right_len);
1829*e4b17023SJohn Marino       std::rotate(__left_split, __middle, __right_split);
1830*e4b17023SJohn Marino       std::advance(__left_split, std::distance(__middle, __right_split));
1831*e4b17023SJohn Marino       return __left_split;
1832*e4b17023SJohn Marino     }
1833*e4b17023SJohn Marino 
1834*e4b17023SJohn Marino   /// This is a helper function...
1835*e4b17023SJohn Marino   /// Requires __first != __last and !__pred(*__first)
1836*e4b17023SJohn Marino   /// and __len == distance(__first, __last).
1837*e4b17023SJohn Marino   ///
1838*e4b17023SJohn Marino   /// !__pred(*__first) allows us to guarantee that we don't
1839*e4b17023SJohn Marino   /// move-assign an element onto itself.
1840*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Pointer, typename _Predicate,
1841*e4b17023SJohn Marino 	   typename _Distance>
1842*e4b17023SJohn Marino     _ForwardIterator
1843*e4b17023SJohn Marino     __stable_partition_adaptive(_ForwardIterator __first,
1844*e4b17023SJohn Marino 				_ForwardIterator __last,
1845*e4b17023SJohn Marino 				_Predicate __pred, _Distance __len,
1846*e4b17023SJohn Marino 				_Pointer __buffer,
1847*e4b17023SJohn Marino 				_Distance __buffer_size)
1848*e4b17023SJohn Marino     {
1849*e4b17023SJohn Marino       if (__len <= __buffer_size)
1850*e4b17023SJohn Marino 	{
1851*e4b17023SJohn Marino 	  _ForwardIterator __result1 = __first;
1852*e4b17023SJohn Marino 	  _Pointer __result2 = __buffer;
1853*e4b17023SJohn Marino 	  // The precondition guarantees that !__pred(*__first), so
1854*e4b17023SJohn Marino 	  // move that element to the buffer before starting the loop.
1855*e4b17023SJohn Marino 	  // This ensures that we only call __pred once per element.
1856*e4b17023SJohn Marino 	  *__result2 = _GLIBCXX_MOVE(*__first);
1857*e4b17023SJohn Marino 	  ++__result2;
1858*e4b17023SJohn Marino 	  ++__first;
1859*e4b17023SJohn Marino 	  for (; __first != __last; ++__first)
1860*e4b17023SJohn Marino 	    if (__pred(*__first))
1861*e4b17023SJohn Marino 	      {
1862*e4b17023SJohn Marino 		*__result1 = _GLIBCXX_MOVE(*__first);
1863*e4b17023SJohn Marino 		++__result1;
1864*e4b17023SJohn Marino 	      }
1865*e4b17023SJohn Marino 	    else
1866*e4b17023SJohn Marino 	      {
1867*e4b17023SJohn Marino 		*__result2 = _GLIBCXX_MOVE(*__first);
1868*e4b17023SJohn Marino 		++__result2;
1869*e4b17023SJohn Marino 	      }
1870*e4b17023SJohn Marino 	  _GLIBCXX_MOVE3(__buffer, __result2, __result1);
1871*e4b17023SJohn Marino 	  return __result1;
1872*e4b17023SJohn Marino 	}
1873*e4b17023SJohn Marino       else
1874*e4b17023SJohn Marino 	{
1875*e4b17023SJohn Marino 	  _ForwardIterator __middle = __first;
1876*e4b17023SJohn Marino 	  std::advance(__middle, __len / 2);
1877*e4b17023SJohn Marino 	  _ForwardIterator __left_split =
1878*e4b17023SJohn Marino 	    std::__stable_partition_adaptive(__first, __middle, __pred,
1879*e4b17023SJohn Marino 					     __len / 2, __buffer,
1880*e4b17023SJohn Marino 					     __buffer_size);
1881*e4b17023SJohn Marino 	  // Advance past true-predicate values to satisfy this
1882*e4b17023SJohn Marino 	  // function's preconditions.
1883*e4b17023SJohn Marino 	  _Distance __right_len = __len - __len / 2;
1884*e4b17023SJohn Marino 	  _ForwardIterator __right_split =
1885*e4b17023SJohn Marino 	    std::__find_if_not_n(__middle, __right_len, __pred);
1886*e4b17023SJohn Marino 	  if (__right_len)
1887*e4b17023SJohn Marino 	    __right_split =
1888*e4b17023SJohn Marino 	      std::__stable_partition_adaptive(__right_split, __last, __pred,
1889*e4b17023SJohn Marino 					       __right_len,
1890*e4b17023SJohn Marino 					       __buffer, __buffer_size);
1891*e4b17023SJohn Marino 	  std::rotate(__left_split, __middle, __right_split);
1892*e4b17023SJohn Marino 	  std::advance(__left_split, std::distance(__middle, __right_split));
1893*e4b17023SJohn Marino 	  return __left_split;
1894*e4b17023SJohn Marino 	}
1895*e4b17023SJohn Marino     }
1896*e4b17023SJohn Marino 
1897*e4b17023SJohn Marino   /**
1898*e4b17023SJohn Marino    *  @brief Move elements for which a predicate is true to the beginning
1899*e4b17023SJohn Marino    *         of a sequence, preserving relative ordering.
1900*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
1901*e4b17023SJohn Marino    *  @param  __first   A forward iterator.
1902*e4b17023SJohn Marino    *  @param  __last    A forward iterator.
1903*e4b17023SJohn Marino    *  @param  __pred    A predicate functor.
1904*e4b17023SJohn Marino    *  @return  An iterator @p middle such that @p __pred(i) is true for each
1905*e4b17023SJohn Marino    *  iterator @p i in the range @p [first,middle) and false for each @p i
1906*e4b17023SJohn Marino    *  in the range @p [middle,last).
1907*e4b17023SJohn Marino    *
1908*e4b17023SJohn Marino    *  Performs the same function as @p partition() with the additional
1909*e4b17023SJohn Marino    *  guarantee that the relative ordering of elements in each group is
1910*e4b17023SJohn Marino    *  preserved, so any two elements @p x and @p y in the range
1911*e4b17023SJohn Marino    *  @p [__first,__last) such that @p __pred(x)==__pred(y) will have the same
1912*e4b17023SJohn Marino    *  relative ordering after calling @p stable_partition().
1913*e4b17023SJohn Marino   */
1914*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Predicate>
1915*e4b17023SJohn Marino     _ForwardIterator
1916*e4b17023SJohn Marino     stable_partition(_ForwardIterator __first, _ForwardIterator __last,
1917*e4b17023SJohn Marino 		     _Predicate __pred)
1918*e4b17023SJohn Marino     {
1919*e4b17023SJohn Marino       // concept requirements
1920*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1921*e4b17023SJohn Marino 				  _ForwardIterator>)
1922*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
1923*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
1924*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
1925*e4b17023SJohn Marino 
1926*e4b17023SJohn Marino       __first = std::__find_if_not(__first, __last, __pred);
1927*e4b17023SJohn Marino 
1928*e4b17023SJohn Marino       if (__first == __last)
1929*e4b17023SJohn Marino 	return __first;
1930*e4b17023SJohn Marino       else
1931*e4b17023SJohn Marino 	{
1932*e4b17023SJohn Marino 	  typedef typename iterator_traits<_ForwardIterator>::value_type
1933*e4b17023SJohn Marino 	    _ValueType;
1934*e4b17023SJohn Marino 	  typedef typename iterator_traits<_ForwardIterator>::difference_type
1935*e4b17023SJohn Marino 	    _DistanceType;
1936*e4b17023SJohn Marino 
1937*e4b17023SJohn Marino 	  _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first,
1938*e4b17023SJohn Marino 								__last);
1939*e4b17023SJohn Marino 	if (__buf.size() > 0)
1940*e4b17023SJohn Marino 	  return
1941*e4b17023SJohn Marino 	    std::__stable_partition_adaptive(__first, __last, __pred,
1942*e4b17023SJohn Marino 					  _DistanceType(__buf.requested_size()),
1943*e4b17023SJohn Marino 					  __buf.begin(),
1944*e4b17023SJohn Marino 					  _DistanceType(__buf.size()));
1945*e4b17023SJohn Marino 	else
1946*e4b17023SJohn Marino 	  return
1947*e4b17023SJohn Marino 	    std::__inplace_stable_partition(__first, __pred,
1948*e4b17023SJohn Marino 					 _DistanceType(__buf.requested_size()));
1949*e4b17023SJohn Marino 	}
1950*e4b17023SJohn Marino     }
1951*e4b17023SJohn Marino 
1952*e4b17023SJohn Marino   /// This is a helper function for the sort routines.
1953*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
1954*e4b17023SJohn Marino     void
1955*e4b17023SJohn Marino     __heap_select(_RandomAccessIterator __first,
1956*e4b17023SJohn Marino 		  _RandomAccessIterator __middle,
1957*e4b17023SJohn Marino 		  _RandomAccessIterator __last)
1958*e4b17023SJohn Marino     {
1959*e4b17023SJohn Marino       std::make_heap(__first, __middle);
1960*e4b17023SJohn Marino       for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
1961*e4b17023SJohn Marino 	if (*__i < *__first)
1962*e4b17023SJohn Marino 	  std::__pop_heap(__first, __middle, __i);
1963*e4b17023SJohn Marino     }
1964*e4b17023SJohn Marino 
1965*e4b17023SJohn Marino   /// This is a helper function for the sort routines.
1966*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Compare>
1967*e4b17023SJohn Marino     void
1968*e4b17023SJohn Marino     __heap_select(_RandomAccessIterator __first,
1969*e4b17023SJohn Marino 		  _RandomAccessIterator __middle,
1970*e4b17023SJohn Marino 		  _RandomAccessIterator __last, _Compare __comp)
1971*e4b17023SJohn Marino     {
1972*e4b17023SJohn Marino       std::make_heap(__first, __middle, __comp);
1973*e4b17023SJohn Marino       for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
1974*e4b17023SJohn Marino 	if (__comp(*__i, *__first))
1975*e4b17023SJohn Marino 	  std::__pop_heap(__first, __middle, __i, __comp);
1976*e4b17023SJohn Marino     }
1977*e4b17023SJohn Marino 
1978*e4b17023SJohn Marino   // partial_sort
1979*e4b17023SJohn Marino 
1980*e4b17023SJohn Marino   /**
1981*e4b17023SJohn Marino    *  @brief Copy the smallest elements of a sequence.
1982*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
1983*e4b17023SJohn Marino    *  @param  __first   An iterator.
1984*e4b17023SJohn Marino    *  @param  __last    Another iterator.
1985*e4b17023SJohn Marino    *  @param  __result_first   A random-access iterator.
1986*e4b17023SJohn Marino    *  @param  __result_last    Another random-access iterator.
1987*e4b17023SJohn Marino    *  @return   An iterator indicating the end of the resulting sequence.
1988*e4b17023SJohn Marino    *
1989*e4b17023SJohn Marino    *  Copies and sorts the smallest N values from the range @p [__first,__last)
1990*e4b17023SJohn Marino    *  to the range beginning at @p __result_first, where the number of
1991*e4b17023SJohn Marino    *  elements to be copied, @p N, is the smaller of @p (__last-__first) and
1992*e4b17023SJohn Marino    *  @p (__result_last-__result_first).
1993*e4b17023SJohn Marino    *  After the sort if @e i and @e j are iterators in the range
1994*e4b17023SJohn Marino    *  @p [__result_first,__result_first+N) such that i precedes j then
1995*e4b17023SJohn Marino    *  *j<*i is false.
1996*e4b17023SJohn Marino    *  The value returned is @p __result_first+N.
1997*e4b17023SJohn Marino   */
1998*e4b17023SJohn Marino   template<typename _InputIterator, typename _RandomAccessIterator>
1999*e4b17023SJohn Marino     _RandomAccessIterator
2000*e4b17023SJohn Marino     partial_sort_copy(_InputIterator __first, _InputIterator __last,
2001*e4b17023SJohn Marino 		      _RandomAccessIterator __result_first,
2002*e4b17023SJohn Marino 		      _RandomAccessIterator __result_last)
2003*e4b17023SJohn Marino     {
2004*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator>::value_type
2005*e4b17023SJohn Marino 	_InputValueType;
2006*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
2007*e4b17023SJohn Marino 	_OutputValueType;
2008*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
2009*e4b17023SJohn Marino 	_DistanceType;
2010*e4b17023SJohn Marino 
2011*e4b17023SJohn Marino       // concept requirements
2012*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
2013*e4b17023SJohn Marino       __glibcxx_function_requires(_ConvertibleConcept<_InputValueType,
2014*e4b17023SJohn Marino 				  _OutputValueType>)
2015*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_InputValueType,
2016*e4b17023SJohn Marino 				                     _OutputValueType>)
2017*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>)
2018*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
2019*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__result_first, __result_last);
2020*e4b17023SJohn Marino 
2021*e4b17023SJohn Marino       if (__result_first == __result_last)
2022*e4b17023SJohn Marino 	return __result_last;
2023*e4b17023SJohn Marino       _RandomAccessIterator __result_real_last = __result_first;
2024*e4b17023SJohn Marino       while(__first != __last && __result_real_last != __result_last)
2025*e4b17023SJohn Marino 	{
2026*e4b17023SJohn Marino 	  *__result_real_last = *__first;
2027*e4b17023SJohn Marino 	  ++__result_real_last;
2028*e4b17023SJohn Marino 	  ++__first;
2029*e4b17023SJohn Marino 	}
2030*e4b17023SJohn Marino       std::make_heap(__result_first, __result_real_last);
2031*e4b17023SJohn Marino       while (__first != __last)
2032*e4b17023SJohn Marino 	{
2033*e4b17023SJohn Marino 	  if (*__first < *__result_first)
2034*e4b17023SJohn Marino 	    std::__adjust_heap(__result_first, _DistanceType(0),
2035*e4b17023SJohn Marino 			       _DistanceType(__result_real_last
2036*e4b17023SJohn Marino 					     - __result_first),
2037*e4b17023SJohn Marino 			       _InputValueType(*__first));
2038*e4b17023SJohn Marino 	  ++__first;
2039*e4b17023SJohn Marino 	}
2040*e4b17023SJohn Marino       std::sort_heap(__result_first, __result_real_last);
2041*e4b17023SJohn Marino       return __result_real_last;
2042*e4b17023SJohn Marino     }
2043*e4b17023SJohn Marino 
2044*e4b17023SJohn Marino   /**
2045*e4b17023SJohn Marino    *  @brief Copy the smallest elements of a sequence using a predicate for
2046*e4b17023SJohn Marino    *         comparison.
2047*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
2048*e4b17023SJohn Marino    *  @param  __first   An input iterator.
2049*e4b17023SJohn Marino    *  @param  __last    Another input iterator.
2050*e4b17023SJohn Marino    *  @param  __result_first   A random-access iterator.
2051*e4b17023SJohn Marino    *  @param  __result_last    Another random-access iterator.
2052*e4b17023SJohn Marino    *  @param  __comp    A comparison functor.
2053*e4b17023SJohn Marino    *  @return   An iterator indicating the end of the resulting sequence.
2054*e4b17023SJohn Marino    *
2055*e4b17023SJohn Marino    *  Copies and sorts the smallest N values from the range @p [__first,__last)
2056*e4b17023SJohn Marino    *  to the range beginning at @p result_first, where the number of
2057*e4b17023SJohn Marino    *  elements to be copied, @p N, is the smaller of @p (__last-__first) and
2058*e4b17023SJohn Marino    *  @p (__result_last-__result_first).
2059*e4b17023SJohn Marino    *  After the sort if @e i and @e j are iterators in the range
2060*e4b17023SJohn Marino    *  @p [__result_first,__result_first+N) such that i precedes j then
2061*e4b17023SJohn Marino    *  @p __comp(*j,*i) is false.
2062*e4b17023SJohn Marino    *  The value returned is @p __result_first+N.
2063*e4b17023SJohn Marino   */
2064*e4b17023SJohn Marino   template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare>
2065*e4b17023SJohn Marino     _RandomAccessIterator
2066*e4b17023SJohn Marino     partial_sort_copy(_InputIterator __first, _InputIterator __last,
2067*e4b17023SJohn Marino 		      _RandomAccessIterator __result_first,
2068*e4b17023SJohn Marino 		      _RandomAccessIterator __result_last,
2069*e4b17023SJohn Marino 		      _Compare __comp)
2070*e4b17023SJohn Marino     {
2071*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator>::value_type
2072*e4b17023SJohn Marino 	_InputValueType;
2073*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
2074*e4b17023SJohn Marino 	_OutputValueType;
2075*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
2076*e4b17023SJohn Marino 	_DistanceType;
2077*e4b17023SJohn Marino 
2078*e4b17023SJohn Marino       // concept requirements
2079*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
2080*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
2081*e4b17023SJohn Marino 				  _RandomAccessIterator>)
2082*e4b17023SJohn Marino       __glibcxx_function_requires(_ConvertibleConcept<_InputValueType,
2083*e4b17023SJohn Marino 				  _OutputValueType>)
2084*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2085*e4b17023SJohn Marino 				  _InputValueType, _OutputValueType>)
2086*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2087*e4b17023SJohn Marino 				  _OutputValueType, _OutputValueType>)
2088*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
2089*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__result_first, __result_last);
2090*e4b17023SJohn Marino 
2091*e4b17023SJohn Marino       if (__result_first == __result_last)
2092*e4b17023SJohn Marino 	return __result_last;
2093*e4b17023SJohn Marino       _RandomAccessIterator __result_real_last = __result_first;
2094*e4b17023SJohn Marino       while(__first != __last && __result_real_last != __result_last)
2095*e4b17023SJohn Marino 	{
2096*e4b17023SJohn Marino 	  *__result_real_last = *__first;
2097*e4b17023SJohn Marino 	  ++__result_real_last;
2098*e4b17023SJohn Marino 	  ++__first;
2099*e4b17023SJohn Marino 	}
2100*e4b17023SJohn Marino       std::make_heap(__result_first, __result_real_last, __comp);
2101*e4b17023SJohn Marino       while (__first != __last)
2102*e4b17023SJohn Marino 	{
2103*e4b17023SJohn Marino 	  if (__comp(*__first, *__result_first))
2104*e4b17023SJohn Marino 	    std::__adjust_heap(__result_first, _DistanceType(0),
2105*e4b17023SJohn Marino 			       _DistanceType(__result_real_last
2106*e4b17023SJohn Marino 					     - __result_first),
2107*e4b17023SJohn Marino 			       _InputValueType(*__first),
2108*e4b17023SJohn Marino 			       __comp);
2109*e4b17023SJohn Marino 	  ++__first;
2110*e4b17023SJohn Marino 	}
2111*e4b17023SJohn Marino       std::sort_heap(__result_first, __result_real_last, __comp);
2112*e4b17023SJohn Marino       return __result_real_last;
2113*e4b17023SJohn Marino     }
2114*e4b17023SJohn Marino 
2115*e4b17023SJohn Marino   /// This is a helper function for the sort routine.
2116*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
2117*e4b17023SJohn Marino     void
2118*e4b17023SJohn Marino     __unguarded_linear_insert(_RandomAccessIterator __last)
2119*e4b17023SJohn Marino     {
2120*e4b17023SJohn Marino       typename iterator_traits<_RandomAccessIterator>::value_type
2121*e4b17023SJohn Marino 	__val = _GLIBCXX_MOVE(*__last);
2122*e4b17023SJohn Marino       _RandomAccessIterator __next = __last;
2123*e4b17023SJohn Marino       --__next;
2124*e4b17023SJohn Marino       while (__val < *__next)
2125*e4b17023SJohn Marino 	{
2126*e4b17023SJohn Marino 	  *__last = _GLIBCXX_MOVE(*__next);
2127*e4b17023SJohn Marino 	  __last = __next;
2128*e4b17023SJohn Marino 	  --__next;
2129*e4b17023SJohn Marino 	}
2130*e4b17023SJohn Marino       *__last = _GLIBCXX_MOVE(__val);
2131*e4b17023SJohn Marino     }
2132*e4b17023SJohn Marino 
2133*e4b17023SJohn Marino   /// This is a helper function for the sort routine.
2134*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Compare>
2135*e4b17023SJohn Marino     void
2136*e4b17023SJohn Marino     __unguarded_linear_insert(_RandomAccessIterator __last,
2137*e4b17023SJohn Marino 			      _Compare __comp)
2138*e4b17023SJohn Marino     {
2139*e4b17023SJohn Marino       typename iterator_traits<_RandomAccessIterator>::value_type
2140*e4b17023SJohn Marino 	__val = _GLIBCXX_MOVE(*__last);
2141*e4b17023SJohn Marino       _RandomAccessIterator __next = __last;
2142*e4b17023SJohn Marino       --__next;
2143*e4b17023SJohn Marino       while (__comp(__val, *__next))
2144*e4b17023SJohn Marino 	{
2145*e4b17023SJohn Marino 	  *__last = _GLIBCXX_MOVE(*__next);
2146*e4b17023SJohn Marino 	  __last = __next;
2147*e4b17023SJohn Marino 	  --__next;
2148*e4b17023SJohn Marino 	}
2149*e4b17023SJohn Marino       *__last = _GLIBCXX_MOVE(__val);
2150*e4b17023SJohn Marino     }
2151*e4b17023SJohn Marino 
2152*e4b17023SJohn Marino   /// This is a helper function for the sort routine.
2153*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
2154*e4b17023SJohn Marino     void
2155*e4b17023SJohn Marino     __insertion_sort(_RandomAccessIterator __first,
2156*e4b17023SJohn Marino 		     _RandomAccessIterator __last)
2157*e4b17023SJohn Marino     {
2158*e4b17023SJohn Marino       if (__first == __last)
2159*e4b17023SJohn Marino 	return;
2160*e4b17023SJohn Marino 
2161*e4b17023SJohn Marino       for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
2162*e4b17023SJohn Marino 	{
2163*e4b17023SJohn Marino 	  if (*__i < *__first)
2164*e4b17023SJohn Marino 	    {
2165*e4b17023SJohn Marino 	      typename iterator_traits<_RandomAccessIterator>::value_type
2166*e4b17023SJohn Marino 		__val = _GLIBCXX_MOVE(*__i);
2167*e4b17023SJohn Marino 	      _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1);
2168*e4b17023SJohn Marino 	      *__first = _GLIBCXX_MOVE(__val);
2169*e4b17023SJohn Marino 	    }
2170*e4b17023SJohn Marino 	  else
2171*e4b17023SJohn Marino 	    std::__unguarded_linear_insert(__i);
2172*e4b17023SJohn Marino 	}
2173*e4b17023SJohn Marino     }
2174*e4b17023SJohn Marino 
2175*e4b17023SJohn Marino   /// This is a helper function for the sort routine.
2176*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Compare>
2177*e4b17023SJohn Marino     void
2178*e4b17023SJohn Marino     __insertion_sort(_RandomAccessIterator __first,
2179*e4b17023SJohn Marino 		     _RandomAccessIterator __last, _Compare __comp)
2180*e4b17023SJohn Marino     {
2181*e4b17023SJohn Marino       if (__first == __last) return;
2182*e4b17023SJohn Marino 
2183*e4b17023SJohn Marino       for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
2184*e4b17023SJohn Marino 	{
2185*e4b17023SJohn Marino 	  if (__comp(*__i, *__first))
2186*e4b17023SJohn Marino 	    {
2187*e4b17023SJohn Marino 	      typename iterator_traits<_RandomAccessIterator>::value_type
2188*e4b17023SJohn Marino 		__val = _GLIBCXX_MOVE(*__i);
2189*e4b17023SJohn Marino 	      _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1);
2190*e4b17023SJohn Marino 	      *__first = _GLIBCXX_MOVE(__val);
2191*e4b17023SJohn Marino 	    }
2192*e4b17023SJohn Marino 	  else
2193*e4b17023SJohn Marino 	    std::__unguarded_linear_insert(__i, __comp);
2194*e4b17023SJohn Marino 	}
2195*e4b17023SJohn Marino     }
2196*e4b17023SJohn Marino 
2197*e4b17023SJohn Marino   /// This is a helper function for the sort routine.
2198*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
2199*e4b17023SJohn Marino     inline void
2200*e4b17023SJohn Marino     __unguarded_insertion_sort(_RandomAccessIterator __first,
2201*e4b17023SJohn Marino 			       _RandomAccessIterator __last)
2202*e4b17023SJohn Marino     {
2203*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
2204*e4b17023SJohn Marino 	_ValueType;
2205*e4b17023SJohn Marino 
2206*e4b17023SJohn Marino       for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
2207*e4b17023SJohn Marino 	std::__unguarded_linear_insert(__i);
2208*e4b17023SJohn Marino     }
2209*e4b17023SJohn Marino 
2210*e4b17023SJohn Marino   /// This is a helper function for the sort routine.
2211*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Compare>
2212*e4b17023SJohn Marino     inline void
2213*e4b17023SJohn Marino     __unguarded_insertion_sort(_RandomAccessIterator __first,
2214*e4b17023SJohn Marino 			       _RandomAccessIterator __last, _Compare __comp)
2215*e4b17023SJohn Marino     {
2216*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
2217*e4b17023SJohn Marino 	_ValueType;
2218*e4b17023SJohn Marino 
2219*e4b17023SJohn Marino       for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
2220*e4b17023SJohn Marino 	std::__unguarded_linear_insert(__i, __comp);
2221*e4b17023SJohn Marino     }
2222*e4b17023SJohn Marino 
2223*e4b17023SJohn Marino   /**
2224*e4b17023SJohn Marino    *  @doctodo
2225*e4b17023SJohn Marino    *  This controls some aspect of the sort routines.
2226*e4b17023SJohn Marino   */
2227*e4b17023SJohn Marino   enum { _S_threshold = 16 };
2228*e4b17023SJohn Marino 
2229*e4b17023SJohn Marino   /// This is a helper function for the sort routine.
2230*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
2231*e4b17023SJohn Marino     void
2232*e4b17023SJohn Marino     __final_insertion_sort(_RandomAccessIterator __first,
2233*e4b17023SJohn Marino 			   _RandomAccessIterator __last)
2234*e4b17023SJohn Marino     {
2235*e4b17023SJohn Marino       if (__last - __first > int(_S_threshold))
2236*e4b17023SJohn Marino 	{
2237*e4b17023SJohn Marino 	  std::__insertion_sort(__first, __first + int(_S_threshold));
2238*e4b17023SJohn Marino 	  std::__unguarded_insertion_sort(__first + int(_S_threshold), __last);
2239*e4b17023SJohn Marino 	}
2240*e4b17023SJohn Marino       else
2241*e4b17023SJohn Marino 	std::__insertion_sort(__first, __last);
2242*e4b17023SJohn Marino     }
2243*e4b17023SJohn Marino 
2244*e4b17023SJohn Marino   /// This is a helper function for the sort routine.
2245*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Compare>
2246*e4b17023SJohn Marino     void
2247*e4b17023SJohn Marino     __final_insertion_sort(_RandomAccessIterator __first,
2248*e4b17023SJohn Marino 			   _RandomAccessIterator __last, _Compare __comp)
2249*e4b17023SJohn Marino     {
2250*e4b17023SJohn Marino       if (__last - __first > int(_S_threshold))
2251*e4b17023SJohn Marino 	{
2252*e4b17023SJohn Marino 	  std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
2253*e4b17023SJohn Marino 	  std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
2254*e4b17023SJohn Marino 					  __comp);
2255*e4b17023SJohn Marino 	}
2256*e4b17023SJohn Marino       else
2257*e4b17023SJohn Marino 	std::__insertion_sort(__first, __last, __comp);
2258*e4b17023SJohn Marino     }
2259*e4b17023SJohn Marino 
2260*e4b17023SJohn Marino   /// This is a helper function...
2261*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Tp>
2262*e4b17023SJohn Marino     _RandomAccessIterator
2263*e4b17023SJohn Marino     __unguarded_partition(_RandomAccessIterator __first,
2264*e4b17023SJohn Marino 			  _RandomAccessIterator __last, const _Tp& __pivot)
2265*e4b17023SJohn Marino     {
2266*e4b17023SJohn Marino       while (true)
2267*e4b17023SJohn Marino 	{
2268*e4b17023SJohn Marino 	  while (*__first < __pivot)
2269*e4b17023SJohn Marino 	    ++__first;
2270*e4b17023SJohn Marino 	  --__last;
2271*e4b17023SJohn Marino 	  while (__pivot < *__last)
2272*e4b17023SJohn Marino 	    --__last;
2273*e4b17023SJohn Marino 	  if (!(__first < __last))
2274*e4b17023SJohn Marino 	    return __first;
2275*e4b17023SJohn Marino 	  std::iter_swap(__first, __last);
2276*e4b17023SJohn Marino 	  ++__first;
2277*e4b17023SJohn Marino 	}
2278*e4b17023SJohn Marino     }
2279*e4b17023SJohn Marino 
2280*e4b17023SJohn Marino   /// This is a helper function...
2281*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
2282*e4b17023SJohn Marino     _RandomAccessIterator
2283*e4b17023SJohn Marino     __unguarded_partition(_RandomAccessIterator __first,
2284*e4b17023SJohn Marino 			  _RandomAccessIterator __last,
2285*e4b17023SJohn Marino 			  const _Tp& __pivot, _Compare __comp)
2286*e4b17023SJohn Marino     {
2287*e4b17023SJohn Marino       while (true)
2288*e4b17023SJohn Marino 	{
2289*e4b17023SJohn Marino 	  while (__comp(*__first, __pivot))
2290*e4b17023SJohn Marino 	    ++__first;
2291*e4b17023SJohn Marino 	  --__last;
2292*e4b17023SJohn Marino 	  while (__comp(__pivot, *__last))
2293*e4b17023SJohn Marino 	    --__last;
2294*e4b17023SJohn Marino 	  if (!(__first < __last))
2295*e4b17023SJohn Marino 	    return __first;
2296*e4b17023SJohn Marino 	  std::iter_swap(__first, __last);
2297*e4b17023SJohn Marino 	  ++__first;
2298*e4b17023SJohn Marino 	}
2299*e4b17023SJohn Marino     }
2300*e4b17023SJohn Marino 
2301*e4b17023SJohn Marino   /// This is a helper function...
2302*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
2303*e4b17023SJohn Marino     inline _RandomAccessIterator
2304*e4b17023SJohn Marino     __unguarded_partition_pivot(_RandomAccessIterator __first,
2305*e4b17023SJohn Marino 				_RandomAccessIterator __last)
2306*e4b17023SJohn Marino     {
2307*e4b17023SJohn Marino       _RandomAccessIterator __mid = __first + (__last - __first) / 2;
2308*e4b17023SJohn Marino       std::__move_median_first(__first, __mid, (__last - 1));
2309*e4b17023SJohn Marino       return std::__unguarded_partition(__first + 1, __last, *__first);
2310*e4b17023SJohn Marino     }
2311*e4b17023SJohn Marino 
2312*e4b17023SJohn Marino 
2313*e4b17023SJohn Marino   /// This is a helper function...
2314*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Compare>
2315*e4b17023SJohn Marino     inline _RandomAccessIterator
2316*e4b17023SJohn Marino     __unguarded_partition_pivot(_RandomAccessIterator __first,
2317*e4b17023SJohn Marino 				_RandomAccessIterator __last, _Compare __comp)
2318*e4b17023SJohn Marino     {
2319*e4b17023SJohn Marino       _RandomAccessIterator __mid = __first + (__last - __first) / 2;
2320*e4b17023SJohn Marino       std::__move_median_first(__first, __mid, (__last - 1), __comp);
2321*e4b17023SJohn Marino       return std::__unguarded_partition(__first + 1, __last, *__first, __comp);
2322*e4b17023SJohn Marino     }
2323*e4b17023SJohn Marino 
2324*e4b17023SJohn Marino   /// This is a helper function for the sort routine.
2325*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Size>
2326*e4b17023SJohn Marino     void
2327*e4b17023SJohn Marino     __introsort_loop(_RandomAccessIterator __first,
2328*e4b17023SJohn Marino 		     _RandomAccessIterator __last,
2329*e4b17023SJohn Marino 		     _Size __depth_limit)
2330*e4b17023SJohn Marino     {
2331*e4b17023SJohn Marino       while (__last - __first > int(_S_threshold))
2332*e4b17023SJohn Marino 	{
2333*e4b17023SJohn Marino 	  if (__depth_limit == 0)
2334*e4b17023SJohn Marino 	    {
2335*e4b17023SJohn Marino 	      _GLIBCXX_STD_A::partial_sort(__first, __last, __last);
2336*e4b17023SJohn Marino 	      return;
2337*e4b17023SJohn Marino 	    }
2338*e4b17023SJohn Marino 	  --__depth_limit;
2339*e4b17023SJohn Marino 	  _RandomAccessIterator __cut =
2340*e4b17023SJohn Marino 	    std::__unguarded_partition_pivot(__first, __last);
2341*e4b17023SJohn Marino 	  std::__introsort_loop(__cut, __last, __depth_limit);
2342*e4b17023SJohn Marino 	  __last = __cut;
2343*e4b17023SJohn Marino 	}
2344*e4b17023SJohn Marino     }
2345*e4b17023SJohn Marino 
2346*e4b17023SJohn Marino   /// This is a helper function for the sort routine.
2347*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Size, typename _Compare>
2348*e4b17023SJohn Marino     void
2349*e4b17023SJohn Marino     __introsort_loop(_RandomAccessIterator __first,
2350*e4b17023SJohn Marino 		     _RandomAccessIterator __last,
2351*e4b17023SJohn Marino 		     _Size __depth_limit, _Compare __comp)
2352*e4b17023SJohn Marino     {
2353*e4b17023SJohn Marino       while (__last - __first > int(_S_threshold))
2354*e4b17023SJohn Marino 	{
2355*e4b17023SJohn Marino 	  if (__depth_limit == 0)
2356*e4b17023SJohn Marino 	    {
2357*e4b17023SJohn Marino 	      _GLIBCXX_STD_A::partial_sort(__first, __last, __last, __comp);
2358*e4b17023SJohn Marino 	      return;
2359*e4b17023SJohn Marino 	    }
2360*e4b17023SJohn Marino 	  --__depth_limit;
2361*e4b17023SJohn Marino 	  _RandomAccessIterator __cut =
2362*e4b17023SJohn Marino 	    std::__unguarded_partition_pivot(__first, __last, __comp);
2363*e4b17023SJohn Marino 	  std::__introsort_loop(__cut, __last, __depth_limit, __comp);
2364*e4b17023SJohn Marino 	  __last = __cut;
2365*e4b17023SJohn Marino 	}
2366*e4b17023SJohn Marino     }
2367*e4b17023SJohn Marino 
2368*e4b17023SJohn Marino   // sort
2369*e4b17023SJohn Marino 
2370*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Size>
2371*e4b17023SJohn Marino     void
2372*e4b17023SJohn Marino     __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth,
2373*e4b17023SJohn Marino 		  _RandomAccessIterator __last, _Size __depth_limit)
2374*e4b17023SJohn Marino     {
2375*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
2376*e4b17023SJohn Marino 	_ValueType;
2377*e4b17023SJohn Marino 
2378*e4b17023SJohn Marino       while (__last - __first > 3)
2379*e4b17023SJohn Marino 	{
2380*e4b17023SJohn Marino 	  if (__depth_limit == 0)
2381*e4b17023SJohn Marino 	    {
2382*e4b17023SJohn Marino 	      std::__heap_select(__first, __nth + 1, __last);
2383*e4b17023SJohn Marino 
2384*e4b17023SJohn Marino 	      // Place the nth largest element in its final position.
2385*e4b17023SJohn Marino 	      std::iter_swap(__first, __nth);
2386*e4b17023SJohn Marino 	      return;
2387*e4b17023SJohn Marino 	    }
2388*e4b17023SJohn Marino 	  --__depth_limit;
2389*e4b17023SJohn Marino 	  _RandomAccessIterator __cut =
2390*e4b17023SJohn Marino 	    std::__unguarded_partition_pivot(__first, __last);
2391*e4b17023SJohn Marino 	  if (__cut <= __nth)
2392*e4b17023SJohn Marino 	    __first = __cut;
2393*e4b17023SJohn Marino 	  else
2394*e4b17023SJohn Marino 	    __last = __cut;
2395*e4b17023SJohn Marino 	}
2396*e4b17023SJohn Marino       std::__insertion_sort(__first, __last);
2397*e4b17023SJohn Marino     }
2398*e4b17023SJohn Marino 
2399*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Size, typename _Compare>
2400*e4b17023SJohn Marino     void
2401*e4b17023SJohn Marino     __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth,
2402*e4b17023SJohn Marino 		  _RandomAccessIterator __last, _Size __depth_limit,
2403*e4b17023SJohn Marino 		  _Compare __comp)
2404*e4b17023SJohn Marino     {
2405*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
2406*e4b17023SJohn Marino 	_ValueType;
2407*e4b17023SJohn Marino 
2408*e4b17023SJohn Marino       while (__last - __first > 3)
2409*e4b17023SJohn Marino 	{
2410*e4b17023SJohn Marino 	  if (__depth_limit == 0)
2411*e4b17023SJohn Marino 	    {
2412*e4b17023SJohn Marino 	      std::__heap_select(__first, __nth + 1, __last, __comp);
2413*e4b17023SJohn Marino 	      // Place the nth largest element in its final position.
2414*e4b17023SJohn Marino 	      std::iter_swap(__first, __nth);
2415*e4b17023SJohn Marino 	      return;
2416*e4b17023SJohn Marino 	    }
2417*e4b17023SJohn Marino 	  --__depth_limit;
2418*e4b17023SJohn Marino 	  _RandomAccessIterator __cut =
2419*e4b17023SJohn Marino 	    std::__unguarded_partition_pivot(__first, __last, __comp);
2420*e4b17023SJohn Marino 	  if (__cut <= __nth)
2421*e4b17023SJohn Marino 	    __first = __cut;
2422*e4b17023SJohn Marino 	  else
2423*e4b17023SJohn Marino 	    __last = __cut;
2424*e4b17023SJohn Marino 	}
2425*e4b17023SJohn Marino       std::__insertion_sort(__first, __last, __comp);
2426*e4b17023SJohn Marino     }
2427*e4b17023SJohn Marino 
2428*e4b17023SJohn Marino   // nth_element
2429*e4b17023SJohn Marino 
2430*e4b17023SJohn Marino   // lower_bound moved to stl_algobase.h
2431*e4b17023SJohn Marino 
2432*e4b17023SJohn Marino   /**
2433*e4b17023SJohn Marino    *  @brief Finds the first position in which @p __val could be inserted
2434*e4b17023SJohn Marino    *         without changing the ordering.
2435*e4b17023SJohn Marino    *  @ingroup binary_search_algorithms
2436*e4b17023SJohn Marino    *  @param  __first   An iterator.
2437*e4b17023SJohn Marino    *  @param  __last    Another iterator.
2438*e4b17023SJohn Marino    *  @param  __val     The search term.
2439*e4b17023SJohn Marino    *  @param  __comp    A functor to use for comparisons.
2440*e4b17023SJohn Marino    *  @return An iterator pointing to the first element <em>not less
2441*e4b17023SJohn Marino    *           than</em> @p __val, or end() if every element is less
2442*e4b17023SJohn Marino    *           than @p __val.
2443*e4b17023SJohn Marino    *  @ingroup binary_search_algorithms
2444*e4b17023SJohn Marino    *
2445*e4b17023SJohn Marino    *  The comparison function should have the same effects on ordering as
2446*e4b17023SJohn Marino    *  the function used for the initial sort.
2447*e4b17023SJohn Marino   */
2448*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Tp, typename _Compare>
2449*e4b17023SJohn Marino     _ForwardIterator
2450*e4b17023SJohn Marino     lower_bound(_ForwardIterator __first, _ForwardIterator __last,
2451*e4b17023SJohn Marino 		const _Tp& __val, _Compare __comp)
2452*e4b17023SJohn Marino     {
2453*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::value_type
2454*e4b17023SJohn Marino 	_ValueType;
2455*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::difference_type
2456*e4b17023SJohn Marino 	_DistanceType;
2457*e4b17023SJohn Marino 
2458*e4b17023SJohn Marino       // concept requirements
2459*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2460*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2461*e4b17023SJohn Marino 				  _ValueType, _Tp>)
2462*e4b17023SJohn Marino       __glibcxx_requires_partitioned_lower_pred(__first, __last,
2463*e4b17023SJohn Marino 						__val, __comp);
2464*e4b17023SJohn Marino 
2465*e4b17023SJohn Marino       _DistanceType __len = std::distance(__first, __last);
2466*e4b17023SJohn Marino 
2467*e4b17023SJohn Marino       while (__len > 0)
2468*e4b17023SJohn Marino 	{
2469*e4b17023SJohn Marino 	  _DistanceType __half = __len >> 1;
2470*e4b17023SJohn Marino 	  _ForwardIterator __middle = __first;
2471*e4b17023SJohn Marino 	  std::advance(__middle, __half);
2472*e4b17023SJohn Marino 	  if (__comp(*__middle, __val))
2473*e4b17023SJohn Marino 	    {
2474*e4b17023SJohn Marino 	      __first = __middle;
2475*e4b17023SJohn Marino 	      ++__first;
2476*e4b17023SJohn Marino 	      __len = __len - __half - 1;
2477*e4b17023SJohn Marino 	    }
2478*e4b17023SJohn Marino 	  else
2479*e4b17023SJohn Marino 	    __len = __half;
2480*e4b17023SJohn Marino 	}
2481*e4b17023SJohn Marino       return __first;
2482*e4b17023SJohn Marino     }
2483*e4b17023SJohn Marino 
2484*e4b17023SJohn Marino   /**
2485*e4b17023SJohn Marino    *  @brief Finds the last position in which @p __val could be inserted
2486*e4b17023SJohn Marino    *         without changing the ordering.
2487*e4b17023SJohn Marino    *  @ingroup binary_search_algorithms
2488*e4b17023SJohn Marino    *  @param  __first   An iterator.
2489*e4b17023SJohn Marino    *  @param  __last    Another iterator.
2490*e4b17023SJohn Marino    *  @param  __val     The search term.
2491*e4b17023SJohn Marino    *  @return  An iterator pointing to the first element greater than @p __val,
2492*e4b17023SJohn Marino    *           or end() if no elements are greater than @p __val.
2493*e4b17023SJohn Marino    *  @ingroup binary_search_algorithms
2494*e4b17023SJohn Marino   */
2495*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Tp>
2496*e4b17023SJohn Marino     _ForwardIterator
2497*e4b17023SJohn Marino     upper_bound(_ForwardIterator __first, _ForwardIterator __last,
2498*e4b17023SJohn Marino 		const _Tp& __val)
2499*e4b17023SJohn Marino     {
2500*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::value_type
2501*e4b17023SJohn Marino 	_ValueType;
2502*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::difference_type
2503*e4b17023SJohn Marino 	_DistanceType;
2504*e4b17023SJohn Marino 
2505*e4b17023SJohn Marino       // concept requirements
2506*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2507*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
2508*e4b17023SJohn Marino       __glibcxx_requires_partitioned_upper(__first, __last, __val);
2509*e4b17023SJohn Marino 
2510*e4b17023SJohn Marino       _DistanceType __len = std::distance(__first, __last);
2511*e4b17023SJohn Marino 
2512*e4b17023SJohn Marino       while (__len > 0)
2513*e4b17023SJohn Marino 	{
2514*e4b17023SJohn Marino 	  _DistanceType __half = __len >> 1;
2515*e4b17023SJohn Marino 	  _ForwardIterator __middle = __first;
2516*e4b17023SJohn Marino 	  std::advance(__middle, __half);
2517*e4b17023SJohn Marino 	  if (__val < *__middle)
2518*e4b17023SJohn Marino 	    __len = __half;
2519*e4b17023SJohn Marino 	  else
2520*e4b17023SJohn Marino 	    {
2521*e4b17023SJohn Marino 	      __first = __middle;
2522*e4b17023SJohn Marino 	      ++__first;
2523*e4b17023SJohn Marino 	      __len = __len - __half - 1;
2524*e4b17023SJohn Marino 	    }
2525*e4b17023SJohn Marino 	}
2526*e4b17023SJohn Marino       return __first;
2527*e4b17023SJohn Marino     }
2528*e4b17023SJohn Marino 
2529*e4b17023SJohn Marino   /**
2530*e4b17023SJohn Marino    *  @brief Finds the last position in which @p __val could be inserted
2531*e4b17023SJohn Marino    *         without changing the ordering.
2532*e4b17023SJohn Marino    *  @ingroup binary_search_algorithms
2533*e4b17023SJohn Marino    *  @param  __first   An iterator.
2534*e4b17023SJohn Marino    *  @param  __last    Another iterator.
2535*e4b17023SJohn Marino    *  @param  __val     The search term.
2536*e4b17023SJohn Marino    *  @param  __comp    A functor to use for comparisons.
2537*e4b17023SJohn Marino    *  @return  An iterator pointing to the first element greater than @p __val,
2538*e4b17023SJohn Marino    *           or end() if no elements are greater than @p __val.
2539*e4b17023SJohn Marino    *  @ingroup binary_search_algorithms
2540*e4b17023SJohn Marino    *
2541*e4b17023SJohn Marino    *  The comparison function should have the same effects on ordering as
2542*e4b17023SJohn Marino    *  the function used for the initial sort.
2543*e4b17023SJohn Marino   */
2544*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Tp, typename _Compare>
2545*e4b17023SJohn Marino     _ForwardIterator
2546*e4b17023SJohn Marino     upper_bound(_ForwardIterator __first, _ForwardIterator __last,
2547*e4b17023SJohn Marino 		const _Tp& __val, _Compare __comp)
2548*e4b17023SJohn Marino     {
2549*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::value_type
2550*e4b17023SJohn Marino 	_ValueType;
2551*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::difference_type
2552*e4b17023SJohn Marino 	_DistanceType;
2553*e4b17023SJohn Marino 
2554*e4b17023SJohn Marino       // concept requirements
2555*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2556*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2557*e4b17023SJohn Marino 				  _Tp, _ValueType>)
2558*e4b17023SJohn Marino       __glibcxx_requires_partitioned_upper_pred(__first, __last,
2559*e4b17023SJohn Marino 						__val, __comp);
2560*e4b17023SJohn Marino 
2561*e4b17023SJohn Marino       _DistanceType __len = std::distance(__first, __last);
2562*e4b17023SJohn Marino 
2563*e4b17023SJohn Marino       while (__len > 0)
2564*e4b17023SJohn Marino 	{
2565*e4b17023SJohn Marino 	  _DistanceType __half = __len >> 1;
2566*e4b17023SJohn Marino 	  _ForwardIterator __middle = __first;
2567*e4b17023SJohn Marino 	  std::advance(__middle, __half);
2568*e4b17023SJohn Marino 	  if (__comp(__val, *__middle))
2569*e4b17023SJohn Marino 	    __len = __half;
2570*e4b17023SJohn Marino 	  else
2571*e4b17023SJohn Marino 	    {
2572*e4b17023SJohn Marino 	      __first = __middle;
2573*e4b17023SJohn Marino 	      ++__first;
2574*e4b17023SJohn Marino 	      __len = __len - __half - 1;
2575*e4b17023SJohn Marino 	    }
2576*e4b17023SJohn Marino 	}
2577*e4b17023SJohn Marino       return __first;
2578*e4b17023SJohn Marino     }
2579*e4b17023SJohn Marino 
2580*e4b17023SJohn Marino   /**
2581*e4b17023SJohn Marino    *  @brief Finds the largest subrange in which @p __val could be inserted
2582*e4b17023SJohn Marino    *         at any place in it without changing the ordering.
2583*e4b17023SJohn Marino    *  @ingroup binary_search_algorithms
2584*e4b17023SJohn Marino    *  @param  __first   An iterator.
2585*e4b17023SJohn Marino    *  @param  __last    Another iterator.
2586*e4b17023SJohn Marino    *  @param  __val     The search term.
2587*e4b17023SJohn Marino    *  @return  An pair of iterators defining the subrange.
2588*e4b17023SJohn Marino    *  @ingroup binary_search_algorithms
2589*e4b17023SJohn Marino    *
2590*e4b17023SJohn Marino    *  This is equivalent to
2591*e4b17023SJohn Marino    *  @code
2592*e4b17023SJohn Marino    *    std::make_pair(lower_bound(__first, __last, __val),
2593*e4b17023SJohn Marino    *                   upper_bound(__first, __last, __val))
2594*e4b17023SJohn Marino    *  @endcode
2595*e4b17023SJohn Marino    *  but does not actually call those functions.
2596*e4b17023SJohn Marino   */
2597*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Tp>
2598*e4b17023SJohn Marino     pair<_ForwardIterator, _ForwardIterator>
2599*e4b17023SJohn Marino     equal_range(_ForwardIterator __first, _ForwardIterator __last,
2600*e4b17023SJohn Marino 		const _Tp& __val)
2601*e4b17023SJohn Marino     {
2602*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::value_type
2603*e4b17023SJohn Marino 	_ValueType;
2604*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::difference_type
2605*e4b17023SJohn Marino 	_DistanceType;
2606*e4b17023SJohn Marino 
2607*e4b17023SJohn Marino       // concept requirements
2608*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2609*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
2610*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
2611*e4b17023SJohn Marino       __glibcxx_requires_partitioned_lower(__first, __last, __val);
2612*e4b17023SJohn Marino       __glibcxx_requires_partitioned_upper(__first, __last, __val);
2613*e4b17023SJohn Marino 
2614*e4b17023SJohn Marino       _DistanceType __len = std::distance(__first, __last);
2615*e4b17023SJohn Marino 
2616*e4b17023SJohn Marino       while (__len > 0)
2617*e4b17023SJohn Marino 	{
2618*e4b17023SJohn Marino 	  _DistanceType __half = __len >> 1;
2619*e4b17023SJohn Marino 	  _ForwardIterator __middle = __first;
2620*e4b17023SJohn Marino 	  std::advance(__middle, __half);
2621*e4b17023SJohn Marino 	  if (*__middle < __val)
2622*e4b17023SJohn Marino 	    {
2623*e4b17023SJohn Marino 	      __first = __middle;
2624*e4b17023SJohn Marino 	      ++__first;
2625*e4b17023SJohn Marino 	      __len = __len - __half - 1;
2626*e4b17023SJohn Marino 	    }
2627*e4b17023SJohn Marino 	  else if (__val < *__middle)
2628*e4b17023SJohn Marino 	    __len = __half;
2629*e4b17023SJohn Marino 	  else
2630*e4b17023SJohn Marino 	    {
2631*e4b17023SJohn Marino 	      _ForwardIterator __left = std::lower_bound(__first, __middle,
2632*e4b17023SJohn Marino 							 __val);
2633*e4b17023SJohn Marino 	      std::advance(__first, __len);
2634*e4b17023SJohn Marino 	      _ForwardIterator __right = std::upper_bound(++__middle, __first,
2635*e4b17023SJohn Marino 							  __val);
2636*e4b17023SJohn Marino 	      return pair<_ForwardIterator, _ForwardIterator>(__left, __right);
2637*e4b17023SJohn Marino 	    }
2638*e4b17023SJohn Marino 	}
2639*e4b17023SJohn Marino       return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
2640*e4b17023SJohn Marino     }
2641*e4b17023SJohn Marino 
2642*e4b17023SJohn Marino   /**
2643*e4b17023SJohn Marino    *  @brief Finds the largest subrange in which @p __val could be inserted
2644*e4b17023SJohn Marino    *         at any place in it without changing the ordering.
2645*e4b17023SJohn Marino    *  @param  __first   An iterator.
2646*e4b17023SJohn Marino    *  @param  __last    Another iterator.
2647*e4b17023SJohn Marino    *  @param  __val     The search term.
2648*e4b17023SJohn Marino    *  @param  __comp    A functor to use for comparisons.
2649*e4b17023SJohn Marino    *  @return  An pair of iterators defining the subrange.
2650*e4b17023SJohn Marino    *  @ingroup binary_search_algorithms
2651*e4b17023SJohn Marino    *
2652*e4b17023SJohn Marino    *  This is equivalent to
2653*e4b17023SJohn Marino    *  @code
2654*e4b17023SJohn Marino    *    std::make_pair(lower_bound(__first, __last, __val, __comp),
2655*e4b17023SJohn Marino    *                   upper_bound(__first, __last, __val, __comp))
2656*e4b17023SJohn Marino    *  @endcode
2657*e4b17023SJohn Marino    *  but does not actually call those functions.
2658*e4b17023SJohn Marino   */
2659*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Tp, typename _Compare>
2660*e4b17023SJohn Marino     pair<_ForwardIterator, _ForwardIterator>
2661*e4b17023SJohn Marino     equal_range(_ForwardIterator __first, _ForwardIterator __last,
2662*e4b17023SJohn Marino 		const _Tp& __val, _Compare __comp)
2663*e4b17023SJohn Marino     {
2664*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::value_type
2665*e4b17023SJohn Marino 	_ValueType;
2666*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::difference_type
2667*e4b17023SJohn Marino 	_DistanceType;
2668*e4b17023SJohn Marino 
2669*e4b17023SJohn Marino       // concept requirements
2670*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2671*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2672*e4b17023SJohn Marino 				  _ValueType, _Tp>)
2673*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2674*e4b17023SJohn Marino 				  _Tp, _ValueType>)
2675*e4b17023SJohn Marino       __glibcxx_requires_partitioned_lower_pred(__first, __last,
2676*e4b17023SJohn Marino 						__val, __comp);
2677*e4b17023SJohn Marino       __glibcxx_requires_partitioned_upper_pred(__first, __last,
2678*e4b17023SJohn Marino 						__val, __comp);
2679*e4b17023SJohn Marino 
2680*e4b17023SJohn Marino       _DistanceType __len = std::distance(__first, __last);
2681*e4b17023SJohn Marino 
2682*e4b17023SJohn Marino       while (__len > 0)
2683*e4b17023SJohn Marino 	{
2684*e4b17023SJohn Marino 	  _DistanceType __half = __len >> 1;
2685*e4b17023SJohn Marino 	  _ForwardIterator __middle = __first;
2686*e4b17023SJohn Marino 	  std::advance(__middle, __half);
2687*e4b17023SJohn Marino 	  if (__comp(*__middle, __val))
2688*e4b17023SJohn Marino 	    {
2689*e4b17023SJohn Marino 	      __first = __middle;
2690*e4b17023SJohn Marino 	      ++__first;
2691*e4b17023SJohn Marino 	      __len = __len - __half - 1;
2692*e4b17023SJohn Marino 	    }
2693*e4b17023SJohn Marino 	  else if (__comp(__val, *__middle))
2694*e4b17023SJohn Marino 	    __len = __half;
2695*e4b17023SJohn Marino 	  else
2696*e4b17023SJohn Marino 	    {
2697*e4b17023SJohn Marino 	      _ForwardIterator __left = std::lower_bound(__first, __middle,
2698*e4b17023SJohn Marino 							 __val, __comp);
2699*e4b17023SJohn Marino 	      std::advance(__first, __len);
2700*e4b17023SJohn Marino 	      _ForwardIterator __right = std::upper_bound(++__middle, __first,
2701*e4b17023SJohn Marino 							  __val, __comp);
2702*e4b17023SJohn Marino 	      return pair<_ForwardIterator, _ForwardIterator>(__left, __right);
2703*e4b17023SJohn Marino 	    }
2704*e4b17023SJohn Marino 	}
2705*e4b17023SJohn Marino       return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
2706*e4b17023SJohn Marino     }
2707*e4b17023SJohn Marino 
2708*e4b17023SJohn Marino   /**
2709*e4b17023SJohn Marino    *  @brief Determines whether an element exists in a range.
2710*e4b17023SJohn Marino    *  @ingroup binary_search_algorithms
2711*e4b17023SJohn Marino    *  @param  __first   An iterator.
2712*e4b17023SJohn Marino    *  @param  __last    Another iterator.
2713*e4b17023SJohn Marino    *  @param  __val     The search term.
2714*e4b17023SJohn Marino    *  @return True if @p __val (or its equivalent) is in [@p
2715*e4b17023SJohn Marino    *  __first,@p __last ].
2716*e4b17023SJohn Marino    *
2717*e4b17023SJohn Marino    *  Note that this does not actually return an iterator to @p __val.  For
2718*e4b17023SJohn Marino    *  that, use std::find or a container's specialized find member functions.
2719*e4b17023SJohn Marino   */
2720*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Tp>
2721*e4b17023SJohn Marino     bool
2722*e4b17023SJohn Marino     binary_search(_ForwardIterator __first, _ForwardIterator __last,
2723*e4b17023SJohn Marino                   const _Tp& __val)
2724*e4b17023SJohn Marino     {
2725*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::value_type
2726*e4b17023SJohn Marino 	_ValueType;
2727*e4b17023SJohn Marino 
2728*e4b17023SJohn Marino       // concept requirements
2729*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2730*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
2731*e4b17023SJohn Marino       __glibcxx_requires_partitioned_lower(__first, __last, __val);
2732*e4b17023SJohn Marino       __glibcxx_requires_partitioned_upper(__first, __last, __val);
2733*e4b17023SJohn Marino 
2734*e4b17023SJohn Marino       _ForwardIterator __i = std::lower_bound(__first, __last, __val);
2735*e4b17023SJohn Marino       return __i != __last && !(__val < *__i);
2736*e4b17023SJohn Marino     }
2737*e4b17023SJohn Marino 
2738*e4b17023SJohn Marino   /**
2739*e4b17023SJohn Marino    *  @brief Determines whether an element exists in a range.
2740*e4b17023SJohn Marino    *  @ingroup binary_search_algorithms
2741*e4b17023SJohn Marino    *  @param  __first   An iterator.
2742*e4b17023SJohn Marino    *  @param  __last    Another iterator.
2743*e4b17023SJohn Marino    *  @param  __val     The search term.
2744*e4b17023SJohn Marino    *  @param  __comp    A functor to use for comparisons.
2745*e4b17023SJohn Marino    *  @return  True if @p __val (or its equivalent) is in @p [__first,__last].
2746*e4b17023SJohn Marino    *
2747*e4b17023SJohn Marino    *  Note that this does not actually return an iterator to @p __val.  For
2748*e4b17023SJohn Marino    *  that, use std::find or a container's specialized find member functions.
2749*e4b17023SJohn Marino    *
2750*e4b17023SJohn Marino    *  The comparison function should have the same effects on ordering as
2751*e4b17023SJohn Marino    *  the function used for the initial sort.
2752*e4b17023SJohn Marino   */
2753*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Tp, typename _Compare>
2754*e4b17023SJohn Marino     bool
2755*e4b17023SJohn Marino     binary_search(_ForwardIterator __first, _ForwardIterator __last,
2756*e4b17023SJohn Marino                   const _Tp& __val, _Compare __comp)
2757*e4b17023SJohn Marino     {
2758*e4b17023SJohn Marino       typedef typename iterator_traits<_ForwardIterator>::value_type
2759*e4b17023SJohn Marino 	_ValueType;
2760*e4b17023SJohn Marino 
2761*e4b17023SJohn Marino       // concept requirements
2762*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2763*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2764*e4b17023SJohn Marino 				  _Tp, _ValueType>)
2765*e4b17023SJohn Marino       __glibcxx_requires_partitioned_lower_pred(__first, __last,
2766*e4b17023SJohn Marino 						__val, __comp);
2767*e4b17023SJohn Marino       __glibcxx_requires_partitioned_upper_pred(__first, __last,
2768*e4b17023SJohn Marino 						__val, __comp);
2769*e4b17023SJohn Marino 
2770*e4b17023SJohn Marino       _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp);
2771*e4b17023SJohn Marino       return __i != __last && !bool(__comp(__val, *__i));
2772*e4b17023SJohn Marino     }
2773*e4b17023SJohn Marino 
2774*e4b17023SJohn Marino   // merge
2775*e4b17023SJohn Marino 
2776*e4b17023SJohn Marino   /// This is a helper function for the __merge_adaptive routines.
2777*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
2778*e4b17023SJohn Marino 	   typename _OutputIterator>
2779*e4b17023SJohn Marino     void
2780*e4b17023SJohn Marino     __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1,
2781*e4b17023SJohn Marino 			  _InputIterator2 __first2, _InputIterator2 __last2,
2782*e4b17023SJohn Marino 			  _OutputIterator __result)
2783*e4b17023SJohn Marino     {
2784*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
2785*e4b17023SJohn Marino 	{
2786*e4b17023SJohn Marino 	  if (*__first2 < *__first1)
2787*e4b17023SJohn Marino 	    {
2788*e4b17023SJohn Marino 	      *__result = _GLIBCXX_MOVE(*__first2);
2789*e4b17023SJohn Marino 	      ++__first2;
2790*e4b17023SJohn Marino 	    }
2791*e4b17023SJohn Marino 	  else
2792*e4b17023SJohn Marino 	    {
2793*e4b17023SJohn Marino 	      *__result = _GLIBCXX_MOVE(*__first1);
2794*e4b17023SJohn Marino 	      ++__first1;
2795*e4b17023SJohn Marino 	    }
2796*e4b17023SJohn Marino 	  ++__result;
2797*e4b17023SJohn Marino 	}
2798*e4b17023SJohn Marino       if (__first1 != __last1)
2799*e4b17023SJohn Marino 	_GLIBCXX_MOVE3(__first1, __last1, __result);
2800*e4b17023SJohn Marino     }
2801*e4b17023SJohn Marino 
2802*e4b17023SJohn Marino   /// This is a helper function for the __merge_adaptive routines.
2803*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
2804*e4b17023SJohn Marino 	   typename _OutputIterator, typename _Compare>
2805*e4b17023SJohn Marino     void
2806*e4b17023SJohn Marino     __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1,
2807*e4b17023SJohn Marino 			  _InputIterator2 __first2, _InputIterator2 __last2,
2808*e4b17023SJohn Marino 			  _OutputIterator __result, _Compare __comp)
2809*e4b17023SJohn Marino     {
2810*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
2811*e4b17023SJohn Marino 	{
2812*e4b17023SJohn Marino 	  if (__comp(*__first2, *__first1))
2813*e4b17023SJohn Marino 	    {
2814*e4b17023SJohn Marino 	      *__result = _GLIBCXX_MOVE(*__first2);
2815*e4b17023SJohn Marino 	      ++__first2;
2816*e4b17023SJohn Marino 	    }
2817*e4b17023SJohn Marino 	  else
2818*e4b17023SJohn Marino 	    {
2819*e4b17023SJohn Marino 	      *__result = _GLIBCXX_MOVE(*__first1);
2820*e4b17023SJohn Marino 	      ++__first1;
2821*e4b17023SJohn Marino 	    }
2822*e4b17023SJohn Marino 	  ++__result;
2823*e4b17023SJohn Marino 	}
2824*e4b17023SJohn Marino       if (__first1 != __last1)
2825*e4b17023SJohn Marino 	_GLIBCXX_MOVE3(__first1, __last1, __result);
2826*e4b17023SJohn Marino     }
2827*e4b17023SJohn Marino 
2828*e4b17023SJohn Marino   /// This is a helper function for the __merge_adaptive routines.
2829*e4b17023SJohn Marino   template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
2830*e4b17023SJohn Marino 	   typename _BidirectionalIterator3>
2831*e4b17023SJohn Marino     void
2832*e4b17023SJohn Marino     __move_merge_adaptive_backward(_BidirectionalIterator1 __first1,
2833*e4b17023SJohn Marino 				   _BidirectionalIterator1 __last1,
2834*e4b17023SJohn Marino 				   _BidirectionalIterator2 __first2,
2835*e4b17023SJohn Marino 				   _BidirectionalIterator2 __last2,
2836*e4b17023SJohn Marino 				   _BidirectionalIterator3 __result)
2837*e4b17023SJohn Marino     {
2838*e4b17023SJohn Marino       if (__first1 == __last1)
2839*e4b17023SJohn Marino 	{
2840*e4b17023SJohn Marino 	  _GLIBCXX_MOVE_BACKWARD3(__first2, __last2, __result);
2841*e4b17023SJohn Marino 	  return;
2842*e4b17023SJohn Marino 	}
2843*e4b17023SJohn Marino       else if (__first2 == __last2)
2844*e4b17023SJohn Marino 	return;
2845*e4b17023SJohn Marino 
2846*e4b17023SJohn Marino       --__last1;
2847*e4b17023SJohn Marino       --__last2;
2848*e4b17023SJohn Marino       while (true)
2849*e4b17023SJohn Marino 	{
2850*e4b17023SJohn Marino 	  if (*__last2 < *__last1)
2851*e4b17023SJohn Marino 	    {
2852*e4b17023SJohn Marino 	      *--__result = _GLIBCXX_MOVE(*__last1);
2853*e4b17023SJohn Marino 	      if (__first1 == __last1)
2854*e4b17023SJohn Marino 		{
2855*e4b17023SJohn Marino 		  _GLIBCXX_MOVE_BACKWARD3(__first2, ++__last2, __result);
2856*e4b17023SJohn Marino 		  return;
2857*e4b17023SJohn Marino 		}
2858*e4b17023SJohn Marino 	      --__last1;
2859*e4b17023SJohn Marino 	    }
2860*e4b17023SJohn Marino 	  else
2861*e4b17023SJohn Marino 	    {
2862*e4b17023SJohn Marino 	      *--__result = _GLIBCXX_MOVE(*__last2);
2863*e4b17023SJohn Marino 	      if (__first2 == __last2)
2864*e4b17023SJohn Marino 		return;
2865*e4b17023SJohn Marino 	      --__last2;
2866*e4b17023SJohn Marino 	    }
2867*e4b17023SJohn Marino 	}
2868*e4b17023SJohn Marino     }
2869*e4b17023SJohn Marino 
2870*e4b17023SJohn Marino   /// This is a helper function for the __merge_adaptive routines.
2871*e4b17023SJohn Marino   template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
2872*e4b17023SJohn Marino 	   typename _BidirectionalIterator3, typename _Compare>
2873*e4b17023SJohn Marino     void
2874*e4b17023SJohn Marino     __move_merge_adaptive_backward(_BidirectionalIterator1 __first1,
2875*e4b17023SJohn Marino 				   _BidirectionalIterator1 __last1,
2876*e4b17023SJohn Marino 				   _BidirectionalIterator2 __first2,
2877*e4b17023SJohn Marino 				   _BidirectionalIterator2 __last2,
2878*e4b17023SJohn Marino 				   _BidirectionalIterator3 __result,
2879*e4b17023SJohn Marino 				   _Compare __comp)
2880*e4b17023SJohn Marino     {
2881*e4b17023SJohn Marino       if (__first1 == __last1)
2882*e4b17023SJohn Marino 	{
2883*e4b17023SJohn Marino 	  _GLIBCXX_MOVE_BACKWARD3(__first2, __last2, __result);
2884*e4b17023SJohn Marino 	  return;
2885*e4b17023SJohn Marino 	}
2886*e4b17023SJohn Marino       else if (__first2 == __last2)
2887*e4b17023SJohn Marino 	return;
2888*e4b17023SJohn Marino 
2889*e4b17023SJohn Marino       --__last1;
2890*e4b17023SJohn Marino       --__last2;
2891*e4b17023SJohn Marino       while (true)
2892*e4b17023SJohn Marino 	{
2893*e4b17023SJohn Marino 	  if (__comp(*__last2, *__last1))
2894*e4b17023SJohn Marino 	    {
2895*e4b17023SJohn Marino 	      *--__result = _GLIBCXX_MOVE(*__last1);
2896*e4b17023SJohn Marino 	      if (__first1 == __last1)
2897*e4b17023SJohn Marino 		{
2898*e4b17023SJohn Marino 		  _GLIBCXX_MOVE_BACKWARD3(__first2, ++__last2, __result);
2899*e4b17023SJohn Marino 		  return;
2900*e4b17023SJohn Marino 		}
2901*e4b17023SJohn Marino 	      --__last1;
2902*e4b17023SJohn Marino 	    }
2903*e4b17023SJohn Marino 	  else
2904*e4b17023SJohn Marino 	    {
2905*e4b17023SJohn Marino 	      *--__result = _GLIBCXX_MOVE(*__last2);
2906*e4b17023SJohn Marino 	      if (__first2 == __last2)
2907*e4b17023SJohn Marino 		return;
2908*e4b17023SJohn Marino 	      --__last2;
2909*e4b17023SJohn Marino 	    }
2910*e4b17023SJohn Marino 	}
2911*e4b17023SJohn Marino     }
2912*e4b17023SJohn Marino 
2913*e4b17023SJohn Marino   /// This is a helper function for the merge routines.
2914*e4b17023SJohn Marino   template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
2915*e4b17023SJohn Marino 	   typename _Distance>
2916*e4b17023SJohn Marino     _BidirectionalIterator1
2917*e4b17023SJohn Marino     __rotate_adaptive(_BidirectionalIterator1 __first,
2918*e4b17023SJohn Marino 		      _BidirectionalIterator1 __middle,
2919*e4b17023SJohn Marino 		      _BidirectionalIterator1 __last,
2920*e4b17023SJohn Marino 		      _Distance __len1, _Distance __len2,
2921*e4b17023SJohn Marino 		      _BidirectionalIterator2 __buffer,
2922*e4b17023SJohn Marino 		      _Distance __buffer_size)
2923*e4b17023SJohn Marino     {
2924*e4b17023SJohn Marino       _BidirectionalIterator2 __buffer_end;
2925*e4b17023SJohn Marino       if (__len1 > __len2 && __len2 <= __buffer_size)
2926*e4b17023SJohn Marino 	{
2927*e4b17023SJohn Marino 	  if (__len2)
2928*e4b17023SJohn Marino 	    {
2929*e4b17023SJohn Marino 	      __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer);
2930*e4b17023SJohn Marino 	      _GLIBCXX_MOVE_BACKWARD3(__first, __middle, __last);
2931*e4b17023SJohn Marino 	      return _GLIBCXX_MOVE3(__buffer, __buffer_end, __first);
2932*e4b17023SJohn Marino 	    }
2933*e4b17023SJohn Marino 	  else
2934*e4b17023SJohn Marino 	    return __first;
2935*e4b17023SJohn Marino 	}
2936*e4b17023SJohn Marino       else if (__len1 <= __buffer_size)
2937*e4b17023SJohn Marino 	{
2938*e4b17023SJohn Marino 	  if (__len1)
2939*e4b17023SJohn Marino 	    {
2940*e4b17023SJohn Marino 	      __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer);
2941*e4b17023SJohn Marino 	      _GLIBCXX_MOVE3(__middle, __last, __first);
2942*e4b17023SJohn Marino 	      return _GLIBCXX_MOVE_BACKWARD3(__buffer, __buffer_end, __last);
2943*e4b17023SJohn Marino 	    }
2944*e4b17023SJohn Marino 	  else
2945*e4b17023SJohn Marino 	    return __last;
2946*e4b17023SJohn Marino 	}
2947*e4b17023SJohn Marino       else
2948*e4b17023SJohn Marino 	{
2949*e4b17023SJohn Marino 	  std::rotate(__first, __middle, __last);
2950*e4b17023SJohn Marino 	  std::advance(__first, std::distance(__middle, __last));
2951*e4b17023SJohn Marino 	  return __first;
2952*e4b17023SJohn Marino 	}
2953*e4b17023SJohn Marino     }
2954*e4b17023SJohn Marino 
2955*e4b17023SJohn Marino   /// This is a helper function for the merge routines.
2956*e4b17023SJohn Marino   template<typename _BidirectionalIterator, typename _Distance,
2957*e4b17023SJohn Marino 	   typename _Pointer>
2958*e4b17023SJohn Marino     void
2959*e4b17023SJohn Marino     __merge_adaptive(_BidirectionalIterator __first,
2960*e4b17023SJohn Marino                      _BidirectionalIterator __middle,
2961*e4b17023SJohn Marino 		     _BidirectionalIterator __last,
2962*e4b17023SJohn Marino 		     _Distance __len1, _Distance __len2,
2963*e4b17023SJohn Marino 		     _Pointer __buffer, _Distance __buffer_size)
2964*e4b17023SJohn Marino     {
2965*e4b17023SJohn Marino       if (__len1 <= __len2 && __len1 <= __buffer_size)
2966*e4b17023SJohn Marino 	{
2967*e4b17023SJohn Marino 	  _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer);
2968*e4b17023SJohn Marino 	  std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last,
2969*e4b17023SJohn Marino 				     __first);
2970*e4b17023SJohn Marino 	}
2971*e4b17023SJohn Marino       else if (__len2 <= __buffer_size)
2972*e4b17023SJohn Marino 	{
2973*e4b17023SJohn Marino 	  _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer);
2974*e4b17023SJohn Marino 	  std::__move_merge_adaptive_backward(__first, __middle, __buffer,
2975*e4b17023SJohn Marino 					      __buffer_end, __last);
2976*e4b17023SJohn Marino 	}
2977*e4b17023SJohn Marino       else
2978*e4b17023SJohn Marino 	{
2979*e4b17023SJohn Marino 	  _BidirectionalIterator __first_cut = __first;
2980*e4b17023SJohn Marino 	  _BidirectionalIterator __second_cut = __middle;
2981*e4b17023SJohn Marino 	  _Distance __len11 = 0;
2982*e4b17023SJohn Marino 	  _Distance __len22 = 0;
2983*e4b17023SJohn Marino 	  if (__len1 > __len2)
2984*e4b17023SJohn Marino 	    {
2985*e4b17023SJohn Marino 	      __len11 = __len1 / 2;
2986*e4b17023SJohn Marino 	      std::advance(__first_cut, __len11);
2987*e4b17023SJohn Marino 	      __second_cut = std::lower_bound(__middle, __last,
2988*e4b17023SJohn Marino 					      *__first_cut);
2989*e4b17023SJohn Marino 	      __len22 = std::distance(__middle, __second_cut);
2990*e4b17023SJohn Marino 	    }
2991*e4b17023SJohn Marino 	  else
2992*e4b17023SJohn Marino 	    {
2993*e4b17023SJohn Marino 	      __len22 = __len2 / 2;
2994*e4b17023SJohn Marino 	      std::advance(__second_cut, __len22);
2995*e4b17023SJohn Marino 	      __first_cut = std::upper_bound(__first, __middle,
2996*e4b17023SJohn Marino 					     *__second_cut);
2997*e4b17023SJohn Marino 	      __len11 = std::distance(__first, __first_cut);
2998*e4b17023SJohn Marino 	    }
2999*e4b17023SJohn Marino 	  _BidirectionalIterator __new_middle =
3000*e4b17023SJohn Marino 	    std::__rotate_adaptive(__first_cut, __middle, __second_cut,
3001*e4b17023SJohn Marino 				   __len1 - __len11, __len22, __buffer,
3002*e4b17023SJohn Marino 				   __buffer_size);
3003*e4b17023SJohn Marino 	  std::__merge_adaptive(__first, __first_cut, __new_middle, __len11,
3004*e4b17023SJohn Marino 				__len22, __buffer, __buffer_size);
3005*e4b17023SJohn Marino 	  std::__merge_adaptive(__new_middle, __second_cut, __last,
3006*e4b17023SJohn Marino 				__len1 - __len11,
3007*e4b17023SJohn Marino 				__len2 - __len22, __buffer, __buffer_size);
3008*e4b17023SJohn Marino 	}
3009*e4b17023SJohn Marino     }
3010*e4b17023SJohn Marino 
3011*e4b17023SJohn Marino   /// This is a helper function for the merge routines.
3012*e4b17023SJohn Marino   template<typename _BidirectionalIterator, typename _Distance,
3013*e4b17023SJohn Marino 	   typename _Pointer, typename _Compare>
3014*e4b17023SJohn Marino     void
3015*e4b17023SJohn Marino     __merge_adaptive(_BidirectionalIterator __first,
3016*e4b17023SJohn Marino                      _BidirectionalIterator __middle,
3017*e4b17023SJohn Marino 		     _BidirectionalIterator __last,
3018*e4b17023SJohn Marino 		     _Distance __len1, _Distance __len2,
3019*e4b17023SJohn Marino 		     _Pointer __buffer, _Distance __buffer_size,
3020*e4b17023SJohn Marino 		     _Compare __comp)
3021*e4b17023SJohn Marino     {
3022*e4b17023SJohn Marino       if (__len1 <= __len2 && __len1 <= __buffer_size)
3023*e4b17023SJohn Marino 	{
3024*e4b17023SJohn Marino 	  _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer);
3025*e4b17023SJohn Marino 	  std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last,
3026*e4b17023SJohn Marino 				     __first, __comp);
3027*e4b17023SJohn Marino 	}
3028*e4b17023SJohn Marino       else if (__len2 <= __buffer_size)
3029*e4b17023SJohn Marino 	{
3030*e4b17023SJohn Marino 	  _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer);
3031*e4b17023SJohn Marino 	  std::__move_merge_adaptive_backward(__first, __middle, __buffer,
3032*e4b17023SJohn Marino 					      __buffer_end, __last, __comp);
3033*e4b17023SJohn Marino 	}
3034*e4b17023SJohn Marino       else
3035*e4b17023SJohn Marino 	{
3036*e4b17023SJohn Marino 	  _BidirectionalIterator __first_cut = __first;
3037*e4b17023SJohn Marino 	  _BidirectionalIterator __second_cut = __middle;
3038*e4b17023SJohn Marino 	  _Distance __len11 = 0;
3039*e4b17023SJohn Marino 	  _Distance __len22 = 0;
3040*e4b17023SJohn Marino 	  if (__len1 > __len2)
3041*e4b17023SJohn Marino 	    {
3042*e4b17023SJohn Marino 	      __len11 = __len1 / 2;
3043*e4b17023SJohn Marino 	      std::advance(__first_cut, __len11);
3044*e4b17023SJohn Marino 	      __second_cut = std::lower_bound(__middle, __last, *__first_cut,
3045*e4b17023SJohn Marino 					      __comp);
3046*e4b17023SJohn Marino 	      __len22 = std::distance(__middle, __second_cut);
3047*e4b17023SJohn Marino 	    }
3048*e4b17023SJohn Marino 	  else
3049*e4b17023SJohn Marino 	    {
3050*e4b17023SJohn Marino 	      __len22 = __len2 / 2;
3051*e4b17023SJohn Marino 	      std::advance(__second_cut, __len22);
3052*e4b17023SJohn Marino 	      __first_cut = std::upper_bound(__first, __middle, *__second_cut,
3053*e4b17023SJohn Marino 					     __comp);
3054*e4b17023SJohn Marino 	      __len11 = std::distance(__first, __first_cut);
3055*e4b17023SJohn Marino 	    }
3056*e4b17023SJohn Marino 	  _BidirectionalIterator __new_middle =
3057*e4b17023SJohn Marino 	    std::__rotate_adaptive(__first_cut, __middle, __second_cut,
3058*e4b17023SJohn Marino 				   __len1 - __len11, __len22, __buffer,
3059*e4b17023SJohn Marino 				   __buffer_size);
3060*e4b17023SJohn Marino 	  std::__merge_adaptive(__first, __first_cut, __new_middle, __len11,
3061*e4b17023SJohn Marino 				__len22, __buffer, __buffer_size, __comp);
3062*e4b17023SJohn Marino 	  std::__merge_adaptive(__new_middle, __second_cut, __last,
3063*e4b17023SJohn Marino 				__len1 - __len11,
3064*e4b17023SJohn Marino 				__len2 - __len22, __buffer,
3065*e4b17023SJohn Marino 				__buffer_size, __comp);
3066*e4b17023SJohn Marino 	}
3067*e4b17023SJohn Marino     }
3068*e4b17023SJohn Marino 
3069*e4b17023SJohn Marino   /// This is a helper function for the merge routines.
3070*e4b17023SJohn Marino   template<typename _BidirectionalIterator, typename _Distance>
3071*e4b17023SJohn Marino     void
3072*e4b17023SJohn Marino     __merge_without_buffer(_BidirectionalIterator __first,
3073*e4b17023SJohn Marino 			   _BidirectionalIterator __middle,
3074*e4b17023SJohn Marino 			   _BidirectionalIterator __last,
3075*e4b17023SJohn Marino 			   _Distance __len1, _Distance __len2)
3076*e4b17023SJohn Marino     {
3077*e4b17023SJohn Marino       if (__len1 == 0 || __len2 == 0)
3078*e4b17023SJohn Marino 	return;
3079*e4b17023SJohn Marino       if (__len1 + __len2 == 2)
3080*e4b17023SJohn Marino 	{
3081*e4b17023SJohn Marino 	  if (*__middle < *__first)
3082*e4b17023SJohn Marino 	    std::iter_swap(__first, __middle);
3083*e4b17023SJohn Marino 	  return;
3084*e4b17023SJohn Marino 	}
3085*e4b17023SJohn Marino       _BidirectionalIterator __first_cut = __first;
3086*e4b17023SJohn Marino       _BidirectionalIterator __second_cut = __middle;
3087*e4b17023SJohn Marino       _Distance __len11 = 0;
3088*e4b17023SJohn Marino       _Distance __len22 = 0;
3089*e4b17023SJohn Marino       if (__len1 > __len2)
3090*e4b17023SJohn Marino 	{
3091*e4b17023SJohn Marino 	  __len11 = __len1 / 2;
3092*e4b17023SJohn Marino 	  std::advance(__first_cut, __len11);
3093*e4b17023SJohn Marino 	  __second_cut = std::lower_bound(__middle, __last, *__first_cut);
3094*e4b17023SJohn Marino 	  __len22 = std::distance(__middle, __second_cut);
3095*e4b17023SJohn Marino 	}
3096*e4b17023SJohn Marino       else
3097*e4b17023SJohn Marino 	{
3098*e4b17023SJohn Marino 	  __len22 = __len2 / 2;
3099*e4b17023SJohn Marino 	  std::advance(__second_cut, __len22);
3100*e4b17023SJohn Marino 	  __first_cut = std::upper_bound(__first, __middle, *__second_cut);
3101*e4b17023SJohn Marino 	  __len11 = std::distance(__first, __first_cut);
3102*e4b17023SJohn Marino 	}
3103*e4b17023SJohn Marino       std::rotate(__first_cut, __middle, __second_cut);
3104*e4b17023SJohn Marino       _BidirectionalIterator __new_middle = __first_cut;
3105*e4b17023SJohn Marino       std::advance(__new_middle, std::distance(__middle, __second_cut));
3106*e4b17023SJohn Marino       std::__merge_without_buffer(__first, __first_cut, __new_middle,
3107*e4b17023SJohn Marino 				  __len11, __len22);
3108*e4b17023SJohn Marino       std::__merge_without_buffer(__new_middle, __second_cut, __last,
3109*e4b17023SJohn Marino 				  __len1 - __len11, __len2 - __len22);
3110*e4b17023SJohn Marino     }
3111*e4b17023SJohn Marino 
3112*e4b17023SJohn Marino   /// This is a helper function for the merge routines.
3113*e4b17023SJohn Marino   template<typename _BidirectionalIterator, typename _Distance,
3114*e4b17023SJohn Marino 	   typename _Compare>
3115*e4b17023SJohn Marino     void
3116*e4b17023SJohn Marino     __merge_without_buffer(_BidirectionalIterator __first,
3117*e4b17023SJohn Marino                            _BidirectionalIterator __middle,
3118*e4b17023SJohn Marino 			   _BidirectionalIterator __last,
3119*e4b17023SJohn Marino 			   _Distance __len1, _Distance __len2,
3120*e4b17023SJohn Marino 			   _Compare __comp)
3121*e4b17023SJohn Marino     {
3122*e4b17023SJohn Marino       if (__len1 == 0 || __len2 == 0)
3123*e4b17023SJohn Marino 	return;
3124*e4b17023SJohn Marino       if (__len1 + __len2 == 2)
3125*e4b17023SJohn Marino 	{
3126*e4b17023SJohn Marino 	  if (__comp(*__middle, *__first))
3127*e4b17023SJohn Marino 	    std::iter_swap(__first, __middle);
3128*e4b17023SJohn Marino 	  return;
3129*e4b17023SJohn Marino 	}
3130*e4b17023SJohn Marino       _BidirectionalIterator __first_cut = __first;
3131*e4b17023SJohn Marino       _BidirectionalIterator __second_cut = __middle;
3132*e4b17023SJohn Marino       _Distance __len11 = 0;
3133*e4b17023SJohn Marino       _Distance __len22 = 0;
3134*e4b17023SJohn Marino       if (__len1 > __len2)
3135*e4b17023SJohn Marino 	{
3136*e4b17023SJohn Marino 	  __len11 = __len1 / 2;
3137*e4b17023SJohn Marino 	  std::advance(__first_cut, __len11);
3138*e4b17023SJohn Marino 	  __second_cut = std::lower_bound(__middle, __last, *__first_cut,
3139*e4b17023SJohn Marino 					  __comp);
3140*e4b17023SJohn Marino 	  __len22 = std::distance(__middle, __second_cut);
3141*e4b17023SJohn Marino 	}
3142*e4b17023SJohn Marino       else
3143*e4b17023SJohn Marino 	{
3144*e4b17023SJohn Marino 	  __len22 = __len2 / 2;
3145*e4b17023SJohn Marino 	  std::advance(__second_cut, __len22);
3146*e4b17023SJohn Marino 	  __first_cut = std::upper_bound(__first, __middle, *__second_cut,
3147*e4b17023SJohn Marino 					 __comp);
3148*e4b17023SJohn Marino 	  __len11 = std::distance(__first, __first_cut);
3149*e4b17023SJohn Marino 	}
3150*e4b17023SJohn Marino       std::rotate(__first_cut, __middle, __second_cut);
3151*e4b17023SJohn Marino       _BidirectionalIterator __new_middle = __first_cut;
3152*e4b17023SJohn Marino       std::advance(__new_middle, std::distance(__middle, __second_cut));
3153*e4b17023SJohn Marino       std::__merge_without_buffer(__first, __first_cut, __new_middle,
3154*e4b17023SJohn Marino 				  __len11, __len22, __comp);
3155*e4b17023SJohn Marino       std::__merge_without_buffer(__new_middle, __second_cut, __last,
3156*e4b17023SJohn Marino 				  __len1 - __len11, __len2 - __len22, __comp);
3157*e4b17023SJohn Marino     }
3158*e4b17023SJohn Marino 
3159*e4b17023SJohn Marino   /**
3160*e4b17023SJohn Marino    *  @brief Merges two sorted ranges in place.
3161*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
3162*e4b17023SJohn Marino    *  @param  __first   An iterator.
3163*e4b17023SJohn Marino    *  @param  __middle  Another iterator.
3164*e4b17023SJohn Marino    *  @param  __last    Another iterator.
3165*e4b17023SJohn Marino    *  @return  Nothing.
3166*e4b17023SJohn Marino    *
3167*e4b17023SJohn Marino    *  Merges two sorted and consecutive ranges, [__first,__middle) and
3168*e4b17023SJohn Marino    *  [__middle,__last), and puts the result in [__first,__last).  The
3169*e4b17023SJohn Marino    *  output will be sorted.  The sort is @e stable, that is, for
3170*e4b17023SJohn Marino    *  equivalent elements in the two ranges, elements from the first
3171*e4b17023SJohn Marino    *  range will always come before elements from the second.
3172*e4b17023SJohn Marino    *
3173*e4b17023SJohn Marino    *  If enough additional memory is available, this takes (__last-__first)-1
3174*e4b17023SJohn Marino    *  comparisons.  Otherwise an NlogN algorithm is used, where N is
3175*e4b17023SJohn Marino    *  distance(__first,__last).
3176*e4b17023SJohn Marino   */
3177*e4b17023SJohn Marino   template<typename _BidirectionalIterator>
3178*e4b17023SJohn Marino     void
3179*e4b17023SJohn Marino     inplace_merge(_BidirectionalIterator __first,
3180*e4b17023SJohn Marino 		  _BidirectionalIterator __middle,
3181*e4b17023SJohn Marino 		  _BidirectionalIterator __last)
3182*e4b17023SJohn Marino     {
3183*e4b17023SJohn Marino       typedef typename iterator_traits<_BidirectionalIterator>::value_type
3184*e4b17023SJohn Marino           _ValueType;
3185*e4b17023SJohn Marino       typedef typename iterator_traits<_BidirectionalIterator>::difference_type
3186*e4b17023SJohn Marino           _DistanceType;
3187*e4b17023SJohn Marino 
3188*e4b17023SJohn Marino       // concept requirements
3189*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
3190*e4b17023SJohn Marino 	    _BidirectionalIterator>)
3191*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
3192*e4b17023SJohn Marino       __glibcxx_requires_sorted(__first, __middle);
3193*e4b17023SJohn Marino       __glibcxx_requires_sorted(__middle, __last);
3194*e4b17023SJohn Marino 
3195*e4b17023SJohn Marino       if (__first == __middle || __middle == __last)
3196*e4b17023SJohn Marino 	return;
3197*e4b17023SJohn Marino 
3198*e4b17023SJohn Marino       _DistanceType __len1 = std::distance(__first, __middle);
3199*e4b17023SJohn Marino       _DistanceType __len2 = std::distance(__middle, __last);
3200*e4b17023SJohn Marino 
3201*e4b17023SJohn Marino       _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first,
3202*e4b17023SJohn Marino 								  __last);
3203*e4b17023SJohn Marino       if (__buf.begin() == 0)
3204*e4b17023SJohn Marino 	std::__merge_without_buffer(__first, __middle, __last, __len1, __len2);
3205*e4b17023SJohn Marino       else
3206*e4b17023SJohn Marino 	std::__merge_adaptive(__first, __middle, __last, __len1, __len2,
3207*e4b17023SJohn Marino 			      __buf.begin(), _DistanceType(__buf.size()));
3208*e4b17023SJohn Marino     }
3209*e4b17023SJohn Marino 
3210*e4b17023SJohn Marino   /**
3211*e4b17023SJohn Marino    *  @brief Merges two sorted ranges in place.
3212*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
3213*e4b17023SJohn Marino    *  @param  __first   An iterator.
3214*e4b17023SJohn Marino    *  @param  __middle  Another iterator.
3215*e4b17023SJohn Marino    *  @param  __last    Another iterator.
3216*e4b17023SJohn Marino    *  @param  __comp    A functor to use for comparisons.
3217*e4b17023SJohn Marino    *  @return  Nothing.
3218*e4b17023SJohn Marino    *
3219*e4b17023SJohn Marino    *  Merges two sorted and consecutive ranges, [__first,__middle) and
3220*e4b17023SJohn Marino    *  [middle,last), and puts the result in [__first,__last).  The output will
3221*e4b17023SJohn Marino    *  be sorted.  The sort is @e stable, that is, for equivalent
3222*e4b17023SJohn Marino    *  elements in the two ranges, elements from the first range will always
3223*e4b17023SJohn Marino    *  come before elements from the second.
3224*e4b17023SJohn Marino    *
3225*e4b17023SJohn Marino    *  If enough additional memory is available, this takes (__last-__first)-1
3226*e4b17023SJohn Marino    *  comparisons.  Otherwise an NlogN algorithm is used, where N is
3227*e4b17023SJohn Marino    *  distance(__first,__last).
3228*e4b17023SJohn Marino    *
3229*e4b17023SJohn Marino    *  The comparison function should have the same effects on ordering as
3230*e4b17023SJohn Marino    *  the function used for the initial sort.
3231*e4b17023SJohn Marino   */
3232*e4b17023SJohn Marino   template<typename _BidirectionalIterator, typename _Compare>
3233*e4b17023SJohn Marino     void
3234*e4b17023SJohn Marino     inplace_merge(_BidirectionalIterator __first,
3235*e4b17023SJohn Marino 		  _BidirectionalIterator __middle,
3236*e4b17023SJohn Marino 		  _BidirectionalIterator __last,
3237*e4b17023SJohn Marino 		  _Compare __comp)
3238*e4b17023SJohn Marino     {
3239*e4b17023SJohn Marino       typedef typename iterator_traits<_BidirectionalIterator>::value_type
3240*e4b17023SJohn Marino           _ValueType;
3241*e4b17023SJohn Marino       typedef typename iterator_traits<_BidirectionalIterator>::difference_type
3242*e4b17023SJohn Marino           _DistanceType;
3243*e4b17023SJohn Marino 
3244*e4b17023SJohn Marino       // concept requirements
3245*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
3246*e4b17023SJohn Marino 	    _BidirectionalIterator>)
3247*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
3248*e4b17023SJohn Marino 	    _ValueType, _ValueType>)
3249*e4b17023SJohn Marino       __glibcxx_requires_sorted_pred(__first, __middle, __comp);
3250*e4b17023SJohn Marino       __glibcxx_requires_sorted_pred(__middle, __last, __comp);
3251*e4b17023SJohn Marino 
3252*e4b17023SJohn Marino       if (__first == __middle || __middle == __last)
3253*e4b17023SJohn Marino 	return;
3254*e4b17023SJohn Marino 
3255*e4b17023SJohn Marino       const _DistanceType __len1 = std::distance(__first, __middle);
3256*e4b17023SJohn Marino       const _DistanceType __len2 = std::distance(__middle, __last);
3257*e4b17023SJohn Marino 
3258*e4b17023SJohn Marino       _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first,
3259*e4b17023SJohn Marino 								  __last);
3260*e4b17023SJohn Marino       if (__buf.begin() == 0)
3261*e4b17023SJohn Marino 	std::__merge_without_buffer(__first, __middle, __last, __len1,
3262*e4b17023SJohn Marino 				    __len2, __comp);
3263*e4b17023SJohn Marino       else
3264*e4b17023SJohn Marino 	std::__merge_adaptive(__first, __middle, __last, __len1, __len2,
3265*e4b17023SJohn Marino 			      __buf.begin(), _DistanceType(__buf.size()),
3266*e4b17023SJohn Marino 			      __comp);
3267*e4b17023SJohn Marino     }
3268*e4b17023SJohn Marino 
3269*e4b17023SJohn Marino 
3270*e4b17023SJohn Marino   /// This is a helper function for the __merge_sort_loop routines.
3271*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
3272*e4b17023SJohn Marino 	   typename _OutputIterator>
3273*e4b17023SJohn Marino     _OutputIterator
3274*e4b17023SJohn Marino     __move_merge(_InputIterator1 __first1, _InputIterator1 __last1,
3275*e4b17023SJohn Marino 		 _InputIterator2 __first2, _InputIterator2 __last2,
3276*e4b17023SJohn Marino 		 _OutputIterator __result)
3277*e4b17023SJohn Marino     {
3278*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
3279*e4b17023SJohn Marino 	{
3280*e4b17023SJohn Marino 	  if (*__first2 < *__first1)
3281*e4b17023SJohn Marino 	    {
3282*e4b17023SJohn Marino 	      *__result = _GLIBCXX_MOVE(*__first2);
3283*e4b17023SJohn Marino 	      ++__first2;
3284*e4b17023SJohn Marino 	    }
3285*e4b17023SJohn Marino 	  else
3286*e4b17023SJohn Marino 	    {
3287*e4b17023SJohn Marino 	      *__result = _GLIBCXX_MOVE(*__first1);
3288*e4b17023SJohn Marino 	      ++__first1;
3289*e4b17023SJohn Marino 	    }
3290*e4b17023SJohn Marino 	  ++__result;
3291*e4b17023SJohn Marino 	}
3292*e4b17023SJohn Marino       return _GLIBCXX_MOVE3(__first2, __last2,
3293*e4b17023SJohn Marino 			    _GLIBCXX_MOVE3(__first1, __last1,
3294*e4b17023SJohn Marino 					   __result));
3295*e4b17023SJohn Marino     }
3296*e4b17023SJohn Marino 
3297*e4b17023SJohn Marino   /// This is a helper function for the __merge_sort_loop routines.
3298*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
3299*e4b17023SJohn Marino 	   typename _OutputIterator, typename _Compare>
3300*e4b17023SJohn Marino     _OutputIterator
3301*e4b17023SJohn Marino     __move_merge(_InputIterator1 __first1, _InputIterator1 __last1,
3302*e4b17023SJohn Marino 		 _InputIterator2 __first2, _InputIterator2 __last2,
3303*e4b17023SJohn Marino 		 _OutputIterator __result, _Compare __comp)
3304*e4b17023SJohn Marino     {
3305*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
3306*e4b17023SJohn Marino 	{
3307*e4b17023SJohn Marino 	  if (__comp(*__first2, *__first1))
3308*e4b17023SJohn Marino 	    {
3309*e4b17023SJohn Marino 	      *__result = _GLIBCXX_MOVE(*__first2);
3310*e4b17023SJohn Marino 	      ++__first2;
3311*e4b17023SJohn Marino 	    }
3312*e4b17023SJohn Marino 	  else
3313*e4b17023SJohn Marino 	    {
3314*e4b17023SJohn Marino 	      *__result = _GLIBCXX_MOVE(*__first1);
3315*e4b17023SJohn Marino 	      ++__first1;
3316*e4b17023SJohn Marino 	    }
3317*e4b17023SJohn Marino 	  ++__result;
3318*e4b17023SJohn Marino 	}
3319*e4b17023SJohn Marino       return _GLIBCXX_MOVE3(__first2, __last2,
3320*e4b17023SJohn Marino 			    _GLIBCXX_MOVE3(__first1, __last1,
3321*e4b17023SJohn Marino 					   __result));
3322*e4b17023SJohn Marino     }
3323*e4b17023SJohn Marino 
3324*e4b17023SJohn Marino   template<typename _RandomAccessIterator1, typename _RandomAccessIterator2,
3325*e4b17023SJohn Marino 	   typename _Distance>
3326*e4b17023SJohn Marino     void
3327*e4b17023SJohn Marino     __merge_sort_loop(_RandomAccessIterator1 __first,
3328*e4b17023SJohn Marino 		      _RandomAccessIterator1 __last,
3329*e4b17023SJohn Marino 		      _RandomAccessIterator2 __result,
3330*e4b17023SJohn Marino 		      _Distance __step_size)
3331*e4b17023SJohn Marino     {
3332*e4b17023SJohn Marino       const _Distance __two_step = 2 * __step_size;
3333*e4b17023SJohn Marino 
3334*e4b17023SJohn Marino       while (__last - __first >= __two_step)
3335*e4b17023SJohn Marino 	{
3336*e4b17023SJohn Marino 	  __result = std::__move_merge(__first, __first + __step_size,
3337*e4b17023SJohn Marino 				       __first + __step_size,
3338*e4b17023SJohn Marino 				       __first + __two_step, __result);
3339*e4b17023SJohn Marino 	  __first += __two_step;
3340*e4b17023SJohn Marino 	}
3341*e4b17023SJohn Marino 
3342*e4b17023SJohn Marino       __step_size = std::min(_Distance(__last - __first), __step_size);
3343*e4b17023SJohn Marino       std::__move_merge(__first, __first + __step_size,
3344*e4b17023SJohn Marino 			__first + __step_size, __last, __result);
3345*e4b17023SJohn Marino     }
3346*e4b17023SJohn Marino 
3347*e4b17023SJohn Marino   template<typename _RandomAccessIterator1, typename _RandomAccessIterator2,
3348*e4b17023SJohn Marino 	   typename _Distance, typename _Compare>
3349*e4b17023SJohn Marino     void
3350*e4b17023SJohn Marino     __merge_sort_loop(_RandomAccessIterator1 __first,
3351*e4b17023SJohn Marino 		      _RandomAccessIterator1 __last,
3352*e4b17023SJohn Marino 		      _RandomAccessIterator2 __result, _Distance __step_size,
3353*e4b17023SJohn Marino 		      _Compare __comp)
3354*e4b17023SJohn Marino     {
3355*e4b17023SJohn Marino       const _Distance __two_step = 2 * __step_size;
3356*e4b17023SJohn Marino 
3357*e4b17023SJohn Marino       while (__last - __first >= __two_step)
3358*e4b17023SJohn Marino 	{
3359*e4b17023SJohn Marino 	  __result = std::__move_merge(__first, __first + __step_size,
3360*e4b17023SJohn Marino 				       __first + __step_size,
3361*e4b17023SJohn Marino 				       __first + __two_step,
3362*e4b17023SJohn Marino 				       __result, __comp);
3363*e4b17023SJohn Marino 	  __first += __two_step;
3364*e4b17023SJohn Marino 	}
3365*e4b17023SJohn Marino       __step_size = std::min(_Distance(__last - __first), __step_size);
3366*e4b17023SJohn Marino 
3367*e4b17023SJohn Marino       std::__move_merge(__first,__first + __step_size,
3368*e4b17023SJohn Marino 			__first + __step_size, __last, __result, __comp);
3369*e4b17023SJohn Marino     }
3370*e4b17023SJohn Marino 
3371*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Distance>
3372*e4b17023SJohn Marino     void
3373*e4b17023SJohn Marino     __chunk_insertion_sort(_RandomAccessIterator __first,
3374*e4b17023SJohn Marino 			   _RandomAccessIterator __last,
3375*e4b17023SJohn Marino 			   _Distance __chunk_size)
3376*e4b17023SJohn Marino     {
3377*e4b17023SJohn Marino       while (__last - __first >= __chunk_size)
3378*e4b17023SJohn Marino 	{
3379*e4b17023SJohn Marino 	  std::__insertion_sort(__first, __first + __chunk_size);
3380*e4b17023SJohn Marino 	  __first += __chunk_size;
3381*e4b17023SJohn Marino 	}
3382*e4b17023SJohn Marino       std::__insertion_sort(__first, __last);
3383*e4b17023SJohn Marino     }
3384*e4b17023SJohn Marino 
3385*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Distance,
3386*e4b17023SJohn Marino 	   typename _Compare>
3387*e4b17023SJohn Marino     void
3388*e4b17023SJohn Marino     __chunk_insertion_sort(_RandomAccessIterator __first,
3389*e4b17023SJohn Marino 			   _RandomAccessIterator __last,
3390*e4b17023SJohn Marino 			   _Distance __chunk_size, _Compare __comp)
3391*e4b17023SJohn Marino     {
3392*e4b17023SJohn Marino       while (__last - __first >= __chunk_size)
3393*e4b17023SJohn Marino 	{
3394*e4b17023SJohn Marino 	  std::__insertion_sort(__first, __first + __chunk_size, __comp);
3395*e4b17023SJohn Marino 	  __first += __chunk_size;
3396*e4b17023SJohn Marino 	}
3397*e4b17023SJohn Marino       std::__insertion_sort(__first, __last, __comp);
3398*e4b17023SJohn Marino     }
3399*e4b17023SJohn Marino 
3400*e4b17023SJohn Marino   enum { _S_chunk_size = 7 };
3401*e4b17023SJohn Marino 
3402*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Pointer>
3403*e4b17023SJohn Marino     void
3404*e4b17023SJohn Marino     __merge_sort_with_buffer(_RandomAccessIterator __first,
3405*e4b17023SJohn Marino 			     _RandomAccessIterator __last,
3406*e4b17023SJohn Marino                              _Pointer __buffer)
3407*e4b17023SJohn Marino     {
3408*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
3409*e4b17023SJohn Marino 	_Distance;
3410*e4b17023SJohn Marino 
3411*e4b17023SJohn Marino       const _Distance __len = __last - __first;
3412*e4b17023SJohn Marino       const _Pointer __buffer_last = __buffer + __len;
3413*e4b17023SJohn Marino 
3414*e4b17023SJohn Marino       _Distance __step_size = _S_chunk_size;
3415*e4b17023SJohn Marino       std::__chunk_insertion_sort(__first, __last, __step_size);
3416*e4b17023SJohn Marino 
3417*e4b17023SJohn Marino       while (__step_size < __len)
3418*e4b17023SJohn Marino 	{
3419*e4b17023SJohn Marino 	  std::__merge_sort_loop(__first, __last, __buffer, __step_size);
3420*e4b17023SJohn Marino 	  __step_size *= 2;
3421*e4b17023SJohn Marino 	  std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size);
3422*e4b17023SJohn Marino 	  __step_size *= 2;
3423*e4b17023SJohn Marino 	}
3424*e4b17023SJohn Marino     }
3425*e4b17023SJohn Marino 
3426*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Pointer, typename _Compare>
3427*e4b17023SJohn Marino     void
3428*e4b17023SJohn Marino     __merge_sort_with_buffer(_RandomAccessIterator __first,
3429*e4b17023SJohn Marino 			     _RandomAccessIterator __last,
3430*e4b17023SJohn Marino                              _Pointer __buffer, _Compare __comp)
3431*e4b17023SJohn Marino     {
3432*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
3433*e4b17023SJohn Marino 	_Distance;
3434*e4b17023SJohn Marino 
3435*e4b17023SJohn Marino       const _Distance __len = __last - __first;
3436*e4b17023SJohn Marino       const _Pointer __buffer_last = __buffer + __len;
3437*e4b17023SJohn Marino 
3438*e4b17023SJohn Marino       _Distance __step_size = _S_chunk_size;
3439*e4b17023SJohn Marino       std::__chunk_insertion_sort(__first, __last, __step_size, __comp);
3440*e4b17023SJohn Marino 
3441*e4b17023SJohn Marino       while (__step_size < __len)
3442*e4b17023SJohn Marino 	{
3443*e4b17023SJohn Marino 	  std::__merge_sort_loop(__first, __last, __buffer,
3444*e4b17023SJohn Marino 				 __step_size, __comp);
3445*e4b17023SJohn Marino 	  __step_size *= 2;
3446*e4b17023SJohn Marino 	  std::__merge_sort_loop(__buffer, __buffer_last, __first,
3447*e4b17023SJohn Marino 				 __step_size, __comp);
3448*e4b17023SJohn Marino 	  __step_size *= 2;
3449*e4b17023SJohn Marino 	}
3450*e4b17023SJohn Marino     }
3451*e4b17023SJohn Marino 
3452*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Pointer,
3453*e4b17023SJohn Marino 	   typename _Distance>
3454*e4b17023SJohn Marino     void
3455*e4b17023SJohn Marino     __stable_sort_adaptive(_RandomAccessIterator __first,
3456*e4b17023SJohn Marino 			   _RandomAccessIterator __last,
3457*e4b17023SJohn Marino                            _Pointer __buffer, _Distance __buffer_size)
3458*e4b17023SJohn Marino     {
3459*e4b17023SJohn Marino       const _Distance __len = (__last - __first + 1) / 2;
3460*e4b17023SJohn Marino       const _RandomAccessIterator __middle = __first + __len;
3461*e4b17023SJohn Marino       if (__len > __buffer_size)
3462*e4b17023SJohn Marino 	{
3463*e4b17023SJohn Marino 	  std::__stable_sort_adaptive(__first, __middle,
3464*e4b17023SJohn Marino 				      __buffer, __buffer_size);
3465*e4b17023SJohn Marino 	  std::__stable_sort_adaptive(__middle, __last,
3466*e4b17023SJohn Marino 				      __buffer, __buffer_size);
3467*e4b17023SJohn Marino 	}
3468*e4b17023SJohn Marino       else
3469*e4b17023SJohn Marino 	{
3470*e4b17023SJohn Marino 	  std::__merge_sort_with_buffer(__first, __middle, __buffer);
3471*e4b17023SJohn Marino 	  std::__merge_sort_with_buffer(__middle, __last, __buffer);
3472*e4b17023SJohn Marino 	}
3473*e4b17023SJohn Marino       std::__merge_adaptive(__first, __middle, __last,
3474*e4b17023SJohn Marino 			    _Distance(__middle - __first),
3475*e4b17023SJohn Marino 			    _Distance(__last - __middle),
3476*e4b17023SJohn Marino 			    __buffer, __buffer_size);
3477*e4b17023SJohn Marino     }
3478*e4b17023SJohn Marino 
3479*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Pointer,
3480*e4b17023SJohn Marino 	   typename _Distance, typename _Compare>
3481*e4b17023SJohn Marino     void
3482*e4b17023SJohn Marino     __stable_sort_adaptive(_RandomAccessIterator __first,
3483*e4b17023SJohn Marino 			   _RandomAccessIterator __last,
3484*e4b17023SJohn Marino                            _Pointer __buffer, _Distance __buffer_size,
3485*e4b17023SJohn Marino                            _Compare __comp)
3486*e4b17023SJohn Marino     {
3487*e4b17023SJohn Marino       const _Distance __len = (__last - __first + 1) / 2;
3488*e4b17023SJohn Marino       const _RandomAccessIterator __middle = __first + __len;
3489*e4b17023SJohn Marino       if (__len > __buffer_size)
3490*e4b17023SJohn Marino 	{
3491*e4b17023SJohn Marino 	  std::__stable_sort_adaptive(__first, __middle, __buffer,
3492*e4b17023SJohn Marino 				      __buffer_size, __comp);
3493*e4b17023SJohn Marino 	  std::__stable_sort_adaptive(__middle, __last, __buffer,
3494*e4b17023SJohn Marino 				      __buffer_size, __comp);
3495*e4b17023SJohn Marino 	}
3496*e4b17023SJohn Marino       else
3497*e4b17023SJohn Marino 	{
3498*e4b17023SJohn Marino 	  std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp);
3499*e4b17023SJohn Marino 	  std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp);
3500*e4b17023SJohn Marino 	}
3501*e4b17023SJohn Marino       std::__merge_adaptive(__first, __middle, __last,
3502*e4b17023SJohn Marino 			    _Distance(__middle - __first),
3503*e4b17023SJohn Marino 			    _Distance(__last - __middle),
3504*e4b17023SJohn Marino 			    __buffer, __buffer_size,
3505*e4b17023SJohn Marino 			    __comp);
3506*e4b17023SJohn Marino     }
3507*e4b17023SJohn Marino 
3508*e4b17023SJohn Marino   /// This is a helper function for the stable sorting routines.
3509*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
3510*e4b17023SJohn Marino     void
3511*e4b17023SJohn Marino     __inplace_stable_sort(_RandomAccessIterator __first,
3512*e4b17023SJohn Marino 			  _RandomAccessIterator __last)
3513*e4b17023SJohn Marino     {
3514*e4b17023SJohn Marino       if (__last - __first < 15)
3515*e4b17023SJohn Marino 	{
3516*e4b17023SJohn Marino 	  std::__insertion_sort(__first, __last);
3517*e4b17023SJohn Marino 	  return;
3518*e4b17023SJohn Marino 	}
3519*e4b17023SJohn Marino       _RandomAccessIterator __middle = __first + (__last - __first) / 2;
3520*e4b17023SJohn Marino       std::__inplace_stable_sort(__first, __middle);
3521*e4b17023SJohn Marino       std::__inplace_stable_sort(__middle, __last);
3522*e4b17023SJohn Marino       std::__merge_without_buffer(__first, __middle, __last,
3523*e4b17023SJohn Marino 				  __middle - __first,
3524*e4b17023SJohn Marino 				  __last - __middle);
3525*e4b17023SJohn Marino     }
3526*e4b17023SJohn Marino 
3527*e4b17023SJohn Marino   /// This is a helper function for the stable sorting routines.
3528*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Compare>
3529*e4b17023SJohn Marino     void
3530*e4b17023SJohn Marino     __inplace_stable_sort(_RandomAccessIterator __first,
3531*e4b17023SJohn Marino 			  _RandomAccessIterator __last, _Compare __comp)
3532*e4b17023SJohn Marino     {
3533*e4b17023SJohn Marino       if (__last - __first < 15)
3534*e4b17023SJohn Marino 	{
3535*e4b17023SJohn Marino 	  std::__insertion_sort(__first, __last, __comp);
3536*e4b17023SJohn Marino 	  return;
3537*e4b17023SJohn Marino 	}
3538*e4b17023SJohn Marino       _RandomAccessIterator __middle = __first + (__last - __first) / 2;
3539*e4b17023SJohn Marino       std::__inplace_stable_sort(__first, __middle, __comp);
3540*e4b17023SJohn Marino       std::__inplace_stable_sort(__middle, __last, __comp);
3541*e4b17023SJohn Marino       std::__merge_without_buffer(__first, __middle, __last,
3542*e4b17023SJohn Marino 				  __middle - __first,
3543*e4b17023SJohn Marino 				  __last - __middle,
3544*e4b17023SJohn Marino 				  __comp);
3545*e4b17023SJohn Marino     }
3546*e4b17023SJohn Marino 
3547*e4b17023SJohn Marino   // stable_sort
3548*e4b17023SJohn Marino 
3549*e4b17023SJohn Marino   // Set algorithms: includes, set_union, set_intersection, set_difference,
3550*e4b17023SJohn Marino   // set_symmetric_difference.  All of these algorithms have the precondition
3551*e4b17023SJohn Marino   // that their input ranges are sorted and the postcondition that their output
3552*e4b17023SJohn Marino   // ranges are sorted.
3553*e4b17023SJohn Marino 
3554*e4b17023SJohn Marino   /**
3555*e4b17023SJohn Marino    *  @brief Determines whether all elements of a sequence exists in a range.
3556*e4b17023SJohn Marino    *  @param  __first1  Start of search range.
3557*e4b17023SJohn Marino    *  @param  __last1   End of search range.
3558*e4b17023SJohn Marino    *  @param  __first2  Start of sequence
3559*e4b17023SJohn Marino    *  @param  __last2   End of sequence.
3560*e4b17023SJohn Marino    *  @return  True if each element in [__first2,__last2) is contained in order
3561*e4b17023SJohn Marino    *  within [__first1,__last1).  False otherwise.
3562*e4b17023SJohn Marino    *  @ingroup set_algorithms
3563*e4b17023SJohn Marino    *
3564*e4b17023SJohn Marino    *  This operation expects both [__first1,__last1) and
3565*e4b17023SJohn Marino    *  [__first2,__last2) to be sorted.  Searches for the presence of
3566*e4b17023SJohn Marino    *  each element in [__first2,__last2) within [__first1,__last1).
3567*e4b17023SJohn Marino    *  The iterators over each range only move forward, so this is a
3568*e4b17023SJohn Marino    *  linear algorithm.  If an element in [__first2,__last2) is not
3569*e4b17023SJohn Marino    *  found before the search iterator reaches @p __last2, false is
3570*e4b17023SJohn Marino    *  returned.
3571*e4b17023SJohn Marino   */
3572*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2>
3573*e4b17023SJohn Marino     bool
3574*e4b17023SJohn Marino     includes(_InputIterator1 __first1, _InputIterator1 __last1,
3575*e4b17023SJohn Marino 	     _InputIterator2 __first2, _InputIterator2 __last2)
3576*e4b17023SJohn Marino     {
3577*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
3578*e4b17023SJohn Marino 	_ValueType1;
3579*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
3580*e4b17023SJohn Marino 	_ValueType2;
3581*e4b17023SJohn Marino 
3582*e4b17023SJohn Marino       // concept requirements
3583*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
3584*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
3585*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
3586*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
3587*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first1, __last1, __first2);
3588*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first2, __last2, __first1);
3589*e4b17023SJohn Marino 
3590*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
3591*e4b17023SJohn Marino 	if (*__first2 < *__first1)
3592*e4b17023SJohn Marino 	  return false;
3593*e4b17023SJohn Marino 	else if(*__first1 < *__first2)
3594*e4b17023SJohn Marino 	  ++__first1;
3595*e4b17023SJohn Marino 	else
3596*e4b17023SJohn Marino 	  ++__first1, ++__first2;
3597*e4b17023SJohn Marino 
3598*e4b17023SJohn Marino       return __first2 == __last2;
3599*e4b17023SJohn Marino     }
3600*e4b17023SJohn Marino 
3601*e4b17023SJohn Marino   /**
3602*e4b17023SJohn Marino    *  @brief Determines whether all elements of a sequence exists in a range
3603*e4b17023SJohn Marino    *  using comparison.
3604*e4b17023SJohn Marino    *  @ingroup set_algorithms
3605*e4b17023SJohn Marino    *  @param  __first1  Start of search range.
3606*e4b17023SJohn Marino    *  @param  __last1   End of search range.
3607*e4b17023SJohn Marino    *  @param  __first2  Start of sequence
3608*e4b17023SJohn Marino    *  @param  __last2   End of sequence.
3609*e4b17023SJohn Marino    *  @param  __comp    Comparison function to use.
3610*e4b17023SJohn Marino    *  @return True if each element in [__first2,__last2) is contained
3611*e4b17023SJohn Marino    *  in order within [__first1,__last1) according to comp.  False
3612*e4b17023SJohn Marino    *  otherwise.  @ingroup set_algorithms
3613*e4b17023SJohn Marino    *
3614*e4b17023SJohn Marino    *  This operation expects both [__first1,__last1) and
3615*e4b17023SJohn Marino    *  [__first2,__last2) to be sorted.  Searches for the presence of
3616*e4b17023SJohn Marino    *  each element in [__first2,__last2) within [__first1,__last1),
3617*e4b17023SJohn Marino    *  using comp to decide.  The iterators over each range only move
3618*e4b17023SJohn Marino    *  forward, so this is a linear algorithm.  If an element in
3619*e4b17023SJohn Marino    *  [__first2,__last2) is not found before the search iterator
3620*e4b17023SJohn Marino    *  reaches @p __last2, false is returned.
3621*e4b17023SJohn Marino   */
3622*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
3623*e4b17023SJohn Marino 	   typename _Compare>
3624*e4b17023SJohn Marino     bool
3625*e4b17023SJohn Marino     includes(_InputIterator1 __first1, _InputIterator1 __last1,
3626*e4b17023SJohn Marino 	     _InputIterator2 __first2, _InputIterator2 __last2,
3627*e4b17023SJohn Marino 	     _Compare __comp)
3628*e4b17023SJohn Marino     {
3629*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
3630*e4b17023SJohn Marino 	_ValueType1;
3631*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
3632*e4b17023SJohn Marino 	_ValueType2;
3633*e4b17023SJohn Marino 
3634*e4b17023SJohn Marino       // concept requirements
3635*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
3636*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
3637*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
3638*e4b17023SJohn Marino 				  _ValueType1, _ValueType2>)
3639*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
3640*e4b17023SJohn Marino 				  _ValueType2, _ValueType1>)
3641*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
3642*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
3643*e4b17023SJohn Marino 
3644*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
3645*e4b17023SJohn Marino 	if (__comp(*__first2, *__first1))
3646*e4b17023SJohn Marino 	  return false;
3647*e4b17023SJohn Marino 	else if(__comp(*__first1, *__first2))
3648*e4b17023SJohn Marino 	  ++__first1;
3649*e4b17023SJohn Marino 	else
3650*e4b17023SJohn Marino 	  ++__first1, ++__first2;
3651*e4b17023SJohn Marino 
3652*e4b17023SJohn Marino       return __first2 == __last2;
3653*e4b17023SJohn Marino     }
3654*e4b17023SJohn Marino 
3655*e4b17023SJohn Marino   // nth_element
3656*e4b17023SJohn Marino   // merge
3657*e4b17023SJohn Marino   // set_difference
3658*e4b17023SJohn Marino   // set_intersection
3659*e4b17023SJohn Marino   // set_union
3660*e4b17023SJohn Marino   // stable_sort
3661*e4b17023SJohn Marino   // set_symmetric_difference
3662*e4b17023SJohn Marino   // min_element
3663*e4b17023SJohn Marino   // max_element
3664*e4b17023SJohn Marino 
3665*e4b17023SJohn Marino   /**
3666*e4b17023SJohn Marino    *  @brief  Permute range into the next @e dictionary ordering.
3667*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
3668*e4b17023SJohn Marino    *  @param  __first  Start of range.
3669*e4b17023SJohn Marino    *  @param  __last   End of range.
3670*e4b17023SJohn Marino    *  @return  False if wrapped to first permutation, true otherwise.
3671*e4b17023SJohn Marino    *
3672*e4b17023SJohn Marino    *  Treats all permutations of the range as a set of @e dictionary sorted
3673*e4b17023SJohn Marino    *  sequences.  Permutes the current sequence into the next one of this set.
3674*e4b17023SJohn Marino    *  Returns true if there are more sequences to generate.  If the sequence
3675*e4b17023SJohn Marino    *  is the largest of the set, the smallest is generated and false returned.
3676*e4b17023SJohn Marino   */
3677*e4b17023SJohn Marino   template<typename _BidirectionalIterator>
3678*e4b17023SJohn Marino     bool
3679*e4b17023SJohn Marino     next_permutation(_BidirectionalIterator __first,
3680*e4b17023SJohn Marino 		     _BidirectionalIterator __last)
3681*e4b17023SJohn Marino     {
3682*e4b17023SJohn Marino       // concept requirements
3683*e4b17023SJohn Marino       __glibcxx_function_requires(_BidirectionalIteratorConcept<
3684*e4b17023SJohn Marino 				  _BidirectionalIterator>)
3685*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<
3686*e4b17023SJohn Marino 	    typename iterator_traits<_BidirectionalIterator>::value_type>)
3687*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
3688*e4b17023SJohn Marino 
3689*e4b17023SJohn Marino       if (__first == __last)
3690*e4b17023SJohn Marino 	return false;
3691*e4b17023SJohn Marino       _BidirectionalIterator __i = __first;
3692*e4b17023SJohn Marino       ++__i;
3693*e4b17023SJohn Marino       if (__i == __last)
3694*e4b17023SJohn Marino 	return false;
3695*e4b17023SJohn Marino       __i = __last;
3696*e4b17023SJohn Marino       --__i;
3697*e4b17023SJohn Marino 
3698*e4b17023SJohn Marino       for(;;)
3699*e4b17023SJohn Marino 	{
3700*e4b17023SJohn Marino 	  _BidirectionalIterator __ii = __i;
3701*e4b17023SJohn Marino 	  --__i;
3702*e4b17023SJohn Marino 	  if (*__i < *__ii)
3703*e4b17023SJohn Marino 	    {
3704*e4b17023SJohn Marino 	      _BidirectionalIterator __j = __last;
3705*e4b17023SJohn Marino 	      while (!(*__i < *--__j))
3706*e4b17023SJohn Marino 		{}
3707*e4b17023SJohn Marino 	      std::iter_swap(__i, __j);
3708*e4b17023SJohn Marino 	      std::reverse(__ii, __last);
3709*e4b17023SJohn Marino 	      return true;
3710*e4b17023SJohn Marino 	    }
3711*e4b17023SJohn Marino 	  if (__i == __first)
3712*e4b17023SJohn Marino 	    {
3713*e4b17023SJohn Marino 	      std::reverse(__first, __last);
3714*e4b17023SJohn Marino 	      return false;
3715*e4b17023SJohn Marino 	    }
3716*e4b17023SJohn Marino 	}
3717*e4b17023SJohn Marino     }
3718*e4b17023SJohn Marino 
3719*e4b17023SJohn Marino   /**
3720*e4b17023SJohn Marino    *  @brief  Permute range into the next @e dictionary ordering using
3721*e4b17023SJohn Marino    *          comparison functor.
3722*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
3723*e4b17023SJohn Marino    *  @param  __first  Start of range.
3724*e4b17023SJohn Marino    *  @param  __last   End of range.
3725*e4b17023SJohn Marino    *  @param  __comp   A comparison functor.
3726*e4b17023SJohn Marino    *  @return  False if wrapped to first permutation, true otherwise.
3727*e4b17023SJohn Marino    *
3728*e4b17023SJohn Marino    *  Treats all permutations of the range [__first,__last) as a set of
3729*e4b17023SJohn Marino    *  @e dictionary sorted sequences ordered by @p __comp.  Permutes the current
3730*e4b17023SJohn Marino    *  sequence into the next one of this set.  Returns true if there are more
3731*e4b17023SJohn Marino    *  sequences to generate.  If the sequence is the largest of the set, the
3732*e4b17023SJohn Marino    *  smallest is generated and false returned.
3733*e4b17023SJohn Marino   */
3734*e4b17023SJohn Marino   template<typename _BidirectionalIterator, typename _Compare>
3735*e4b17023SJohn Marino     bool
3736*e4b17023SJohn Marino     next_permutation(_BidirectionalIterator __first,
3737*e4b17023SJohn Marino 		     _BidirectionalIterator __last, _Compare __comp)
3738*e4b17023SJohn Marino     {
3739*e4b17023SJohn Marino       // concept requirements
3740*e4b17023SJohn Marino       __glibcxx_function_requires(_BidirectionalIteratorConcept<
3741*e4b17023SJohn Marino 				  _BidirectionalIterator>)
3742*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
3743*e4b17023SJohn Marino 	    typename iterator_traits<_BidirectionalIterator>::value_type,
3744*e4b17023SJohn Marino 	    typename iterator_traits<_BidirectionalIterator>::value_type>)
3745*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
3746*e4b17023SJohn Marino 
3747*e4b17023SJohn Marino       if (__first == __last)
3748*e4b17023SJohn Marino 	return false;
3749*e4b17023SJohn Marino       _BidirectionalIterator __i = __first;
3750*e4b17023SJohn Marino       ++__i;
3751*e4b17023SJohn Marino       if (__i == __last)
3752*e4b17023SJohn Marino 	return false;
3753*e4b17023SJohn Marino       __i = __last;
3754*e4b17023SJohn Marino       --__i;
3755*e4b17023SJohn Marino 
3756*e4b17023SJohn Marino       for(;;)
3757*e4b17023SJohn Marino 	{
3758*e4b17023SJohn Marino 	  _BidirectionalIterator __ii = __i;
3759*e4b17023SJohn Marino 	  --__i;
3760*e4b17023SJohn Marino 	  if (__comp(*__i, *__ii))
3761*e4b17023SJohn Marino 	    {
3762*e4b17023SJohn Marino 	      _BidirectionalIterator __j = __last;
3763*e4b17023SJohn Marino 	      while (!bool(__comp(*__i, *--__j)))
3764*e4b17023SJohn Marino 		{}
3765*e4b17023SJohn Marino 	      std::iter_swap(__i, __j);
3766*e4b17023SJohn Marino 	      std::reverse(__ii, __last);
3767*e4b17023SJohn Marino 	      return true;
3768*e4b17023SJohn Marino 	    }
3769*e4b17023SJohn Marino 	  if (__i == __first)
3770*e4b17023SJohn Marino 	    {
3771*e4b17023SJohn Marino 	      std::reverse(__first, __last);
3772*e4b17023SJohn Marino 	      return false;
3773*e4b17023SJohn Marino 	    }
3774*e4b17023SJohn Marino 	}
3775*e4b17023SJohn Marino     }
3776*e4b17023SJohn Marino 
3777*e4b17023SJohn Marino   /**
3778*e4b17023SJohn Marino    *  @brief  Permute range into the previous @e dictionary ordering.
3779*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
3780*e4b17023SJohn Marino    *  @param  __first  Start of range.
3781*e4b17023SJohn Marino    *  @param  __last   End of range.
3782*e4b17023SJohn Marino    *  @return  False if wrapped to last permutation, true otherwise.
3783*e4b17023SJohn Marino    *
3784*e4b17023SJohn Marino    *  Treats all permutations of the range as a set of @e dictionary sorted
3785*e4b17023SJohn Marino    *  sequences.  Permutes the current sequence into the previous one of this
3786*e4b17023SJohn Marino    *  set.  Returns true if there are more sequences to generate.  If the
3787*e4b17023SJohn Marino    *  sequence is the smallest of the set, the largest is generated and false
3788*e4b17023SJohn Marino    *  returned.
3789*e4b17023SJohn Marino   */
3790*e4b17023SJohn Marino   template<typename _BidirectionalIterator>
3791*e4b17023SJohn Marino     bool
3792*e4b17023SJohn Marino     prev_permutation(_BidirectionalIterator __first,
3793*e4b17023SJohn Marino 		     _BidirectionalIterator __last)
3794*e4b17023SJohn Marino     {
3795*e4b17023SJohn Marino       // concept requirements
3796*e4b17023SJohn Marino       __glibcxx_function_requires(_BidirectionalIteratorConcept<
3797*e4b17023SJohn Marino 				  _BidirectionalIterator>)
3798*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<
3799*e4b17023SJohn Marino 	    typename iterator_traits<_BidirectionalIterator>::value_type>)
3800*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
3801*e4b17023SJohn Marino 
3802*e4b17023SJohn Marino       if (__first == __last)
3803*e4b17023SJohn Marino 	return false;
3804*e4b17023SJohn Marino       _BidirectionalIterator __i = __first;
3805*e4b17023SJohn Marino       ++__i;
3806*e4b17023SJohn Marino       if (__i == __last)
3807*e4b17023SJohn Marino 	return false;
3808*e4b17023SJohn Marino       __i = __last;
3809*e4b17023SJohn Marino       --__i;
3810*e4b17023SJohn Marino 
3811*e4b17023SJohn Marino       for(;;)
3812*e4b17023SJohn Marino 	{
3813*e4b17023SJohn Marino 	  _BidirectionalIterator __ii = __i;
3814*e4b17023SJohn Marino 	  --__i;
3815*e4b17023SJohn Marino 	  if (*__ii < *__i)
3816*e4b17023SJohn Marino 	    {
3817*e4b17023SJohn Marino 	      _BidirectionalIterator __j = __last;
3818*e4b17023SJohn Marino 	      while (!(*--__j < *__i))
3819*e4b17023SJohn Marino 		{}
3820*e4b17023SJohn Marino 	      std::iter_swap(__i, __j);
3821*e4b17023SJohn Marino 	      std::reverse(__ii, __last);
3822*e4b17023SJohn Marino 	      return true;
3823*e4b17023SJohn Marino 	    }
3824*e4b17023SJohn Marino 	  if (__i == __first)
3825*e4b17023SJohn Marino 	    {
3826*e4b17023SJohn Marino 	      std::reverse(__first, __last);
3827*e4b17023SJohn Marino 	      return false;
3828*e4b17023SJohn Marino 	    }
3829*e4b17023SJohn Marino 	}
3830*e4b17023SJohn Marino     }
3831*e4b17023SJohn Marino 
3832*e4b17023SJohn Marino   /**
3833*e4b17023SJohn Marino    *  @brief  Permute range into the previous @e dictionary ordering using
3834*e4b17023SJohn Marino    *          comparison functor.
3835*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
3836*e4b17023SJohn Marino    *  @param  __first  Start of range.
3837*e4b17023SJohn Marino    *  @param  __last   End of range.
3838*e4b17023SJohn Marino    *  @param  __comp   A comparison functor.
3839*e4b17023SJohn Marino    *  @return  False if wrapped to last permutation, true otherwise.
3840*e4b17023SJohn Marino    *
3841*e4b17023SJohn Marino    *  Treats all permutations of the range [__first,__last) as a set of
3842*e4b17023SJohn Marino    *  @e dictionary sorted sequences ordered by @p __comp.  Permutes the current
3843*e4b17023SJohn Marino    *  sequence into the previous one of this set.  Returns true if there are
3844*e4b17023SJohn Marino    *  more sequences to generate.  If the sequence is the smallest of the set,
3845*e4b17023SJohn Marino    *  the largest is generated and false returned.
3846*e4b17023SJohn Marino   */
3847*e4b17023SJohn Marino   template<typename _BidirectionalIterator, typename _Compare>
3848*e4b17023SJohn Marino     bool
3849*e4b17023SJohn Marino     prev_permutation(_BidirectionalIterator __first,
3850*e4b17023SJohn Marino 		     _BidirectionalIterator __last, _Compare __comp)
3851*e4b17023SJohn Marino     {
3852*e4b17023SJohn Marino       // concept requirements
3853*e4b17023SJohn Marino       __glibcxx_function_requires(_BidirectionalIteratorConcept<
3854*e4b17023SJohn Marino 				  _BidirectionalIterator>)
3855*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
3856*e4b17023SJohn Marino 	    typename iterator_traits<_BidirectionalIterator>::value_type,
3857*e4b17023SJohn Marino 	    typename iterator_traits<_BidirectionalIterator>::value_type>)
3858*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
3859*e4b17023SJohn Marino 
3860*e4b17023SJohn Marino       if (__first == __last)
3861*e4b17023SJohn Marino 	return false;
3862*e4b17023SJohn Marino       _BidirectionalIterator __i = __first;
3863*e4b17023SJohn Marino       ++__i;
3864*e4b17023SJohn Marino       if (__i == __last)
3865*e4b17023SJohn Marino 	return false;
3866*e4b17023SJohn Marino       __i = __last;
3867*e4b17023SJohn Marino       --__i;
3868*e4b17023SJohn Marino 
3869*e4b17023SJohn Marino       for(;;)
3870*e4b17023SJohn Marino 	{
3871*e4b17023SJohn Marino 	  _BidirectionalIterator __ii = __i;
3872*e4b17023SJohn Marino 	  --__i;
3873*e4b17023SJohn Marino 	  if (__comp(*__ii, *__i))
3874*e4b17023SJohn Marino 	    {
3875*e4b17023SJohn Marino 	      _BidirectionalIterator __j = __last;
3876*e4b17023SJohn Marino 	      while (!bool(__comp(*--__j, *__i)))
3877*e4b17023SJohn Marino 		{}
3878*e4b17023SJohn Marino 	      std::iter_swap(__i, __j);
3879*e4b17023SJohn Marino 	      std::reverse(__ii, __last);
3880*e4b17023SJohn Marino 	      return true;
3881*e4b17023SJohn Marino 	    }
3882*e4b17023SJohn Marino 	  if (__i == __first)
3883*e4b17023SJohn Marino 	    {
3884*e4b17023SJohn Marino 	      std::reverse(__first, __last);
3885*e4b17023SJohn Marino 	      return false;
3886*e4b17023SJohn Marino 	    }
3887*e4b17023SJohn Marino 	}
3888*e4b17023SJohn Marino     }
3889*e4b17023SJohn Marino 
3890*e4b17023SJohn Marino   // replace
3891*e4b17023SJohn Marino   // replace_if
3892*e4b17023SJohn Marino 
3893*e4b17023SJohn Marino   /**
3894*e4b17023SJohn Marino    *  @brief Copy a sequence, replacing each element of one value with another
3895*e4b17023SJohn Marino    *         value.
3896*e4b17023SJohn Marino    *  @param  __first      An input iterator.
3897*e4b17023SJohn Marino    *  @param  __last       An input iterator.
3898*e4b17023SJohn Marino    *  @param  __result     An output iterator.
3899*e4b17023SJohn Marino    *  @param  __old_value  The value to be replaced.
3900*e4b17023SJohn Marino    *  @param  __new_value  The replacement value.
3901*e4b17023SJohn Marino    *  @return   The end of the output sequence, @p result+(last-first).
3902*e4b17023SJohn Marino    *
3903*e4b17023SJohn Marino    *  Copies each element in the input range @p [__first,__last) to the
3904*e4b17023SJohn Marino    *  output range @p [__result,__result+(__last-__first)) replacing elements
3905*e4b17023SJohn Marino    *  equal to @p __old_value with @p __new_value.
3906*e4b17023SJohn Marino   */
3907*e4b17023SJohn Marino   template<typename _InputIterator, typename _OutputIterator, typename _Tp>
3908*e4b17023SJohn Marino     _OutputIterator
3909*e4b17023SJohn Marino     replace_copy(_InputIterator __first, _InputIterator __last,
3910*e4b17023SJohn Marino 		 _OutputIterator __result,
3911*e4b17023SJohn Marino 		 const _Tp& __old_value, const _Tp& __new_value)
3912*e4b17023SJohn Marino     {
3913*e4b17023SJohn Marino       // concept requirements
3914*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
3915*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
3916*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
3917*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualOpConcept<
3918*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type, _Tp>)
3919*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
3920*e4b17023SJohn Marino 
3921*e4b17023SJohn Marino       for (; __first != __last; ++__first, ++__result)
3922*e4b17023SJohn Marino 	if (*__first == __old_value)
3923*e4b17023SJohn Marino 	  *__result = __new_value;
3924*e4b17023SJohn Marino 	else
3925*e4b17023SJohn Marino 	  *__result = *__first;
3926*e4b17023SJohn Marino       return __result;
3927*e4b17023SJohn Marino     }
3928*e4b17023SJohn Marino 
3929*e4b17023SJohn Marino   /**
3930*e4b17023SJohn Marino    *  @brief Copy a sequence, replacing each value for which a predicate
3931*e4b17023SJohn Marino    *         returns true with another value.
3932*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
3933*e4b17023SJohn Marino    *  @param  __first      An input iterator.
3934*e4b17023SJohn Marino    *  @param  __last       An input iterator.
3935*e4b17023SJohn Marino    *  @param  __result     An output iterator.
3936*e4b17023SJohn Marino    *  @param  __pred       A predicate.
3937*e4b17023SJohn Marino    *  @param  __new_value  The replacement value.
3938*e4b17023SJohn Marino    *  @return   The end of the output sequence, @p __result+(__last-__first).
3939*e4b17023SJohn Marino    *
3940*e4b17023SJohn Marino    *  Copies each element in the range @p [__first,__last) to the range
3941*e4b17023SJohn Marino    *  @p [__result,__result+(__last-__first)) replacing elements for which
3942*e4b17023SJohn Marino    *  @p __pred returns true with @p __new_value.
3943*e4b17023SJohn Marino   */
3944*e4b17023SJohn Marino   template<typename _InputIterator, typename _OutputIterator,
3945*e4b17023SJohn Marino 	   typename _Predicate, typename _Tp>
3946*e4b17023SJohn Marino     _OutputIterator
3947*e4b17023SJohn Marino     replace_copy_if(_InputIterator __first, _InputIterator __last,
3948*e4b17023SJohn Marino 		    _OutputIterator __result,
3949*e4b17023SJohn Marino 		    _Predicate __pred, const _Tp& __new_value)
3950*e4b17023SJohn Marino     {
3951*e4b17023SJohn Marino       // concept requirements
3952*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
3953*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
3954*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
3955*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
3956*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
3957*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
3958*e4b17023SJohn Marino 
3959*e4b17023SJohn Marino       for (; __first != __last; ++__first, ++__result)
3960*e4b17023SJohn Marino 	if (__pred(*__first))
3961*e4b17023SJohn Marino 	  *__result = __new_value;
3962*e4b17023SJohn Marino 	else
3963*e4b17023SJohn Marino 	  *__result = *__first;
3964*e4b17023SJohn Marino       return __result;
3965*e4b17023SJohn Marino     }
3966*e4b17023SJohn Marino 
3967*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
3968*e4b17023SJohn Marino   /**
3969*e4b17023SJohn Marino    *  @brief  Determines whether the elements of a sequence are sorted.
3970*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
3971*e4b17023SJohn Marino    *  @param  __first   An iterator.
3972*e4b17023SJohn Marino    *  @param  __last    Another iterator.
3973*e4b17023SJohn Marino    *  @return  True if the elements are sorted, false otherwise.
3974*e4b17023SJohn Marino   */
3975*e4b17023SJohn Marino   template<typename _ForwardIterator>
3976*e4b17023SJohn Marino     inline bool
3977*e4b17023SJohn Marino     is_sorted(_ForwardIterator __first, _ForwardIterator __last)
3978*e4b17023SJohn Marino     { return std::is_sorted_until(__first, __last) == __last; }
3979*e4b17023SJohn Marino 
3980*e4b17023SJohn Marino   /**
3981*e4b17023SJohn Marino    *  @brief  Determines whether the elements of a sequence are sorted
3982*e4b17023SJohn Marino    *          according to a comparison functor.
3983*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
3984*e4b17023SJohn Marino    *  @param  __first   An iterator.
3985*e4b17023SJohn Marino    *  @param  __last    Another iterator.
3986*e4b17023SJohn Marino    *  @param  __comp    A comparison functor.
3987*e4b17023SJohn Marino    *  @return  True if the elements are sorted, false otherwise.
3988*e4b17023SJohn Marino   */
3989*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Compare>
3990*e4b17023SJohn Marino     inline bool
3991*e4b17023SJohn Marino     is_sorted(_ForwardIterator __first, _ForwardIterator __last,
3992*e4b17023SJohn Marino 	      _Compare __comp)
3993*e4b17023SJohn Marino     { return std::is_sorted_until(__first, __last, __comp) == __last; }
3994*e4b17023SJohn Marino 
3995*e4b17023SJohn Marino   /**
3996*e4b17023SJohn Marino    *  @brief  Determines the end of a sorted sequence.
3997*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
3998*e4b17023SJohn Marino    *  @param  __first   An iterator.
3999*e4b17023SJohn Marino    *  @param  __last    Another iterator.
4000*e4b17023SJohn Marino    *  @return  An iterator pointing to the last iterator i in [__first, __last)
4001*e4b17023SJohn Marino    *           for which the range [__first, i) is sorted.
4002*e4b17023SJohn Marino   */
4003*e4b17023SJohn Marino   template<typename _ForwardIterator>
4004*e4b17023SJohn Marino     _ForwardIterator
4005*e4b17023SJohn Marino     is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
4006*e4b17023SJohn Marino     {
4007*e4b17023SJohn Marino       // concept requirements
4008*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4009*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<
4010*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
4011*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4012*e4b17023SJohn Marino 
4013*e4b17023SJohn Marino       if (__first == __last)
4014*e4b17023SJohn Marino 	return __last;
4015*e4b17023SJohn Marino 
4016*e4b17023SJohn Marino       _ForwardIterator __next = __first;
4017*e4b17023SJohn Marino       for (++__next; __next != __last; __first = __next, ++__next)
4018*e4b17023SJohn Marino 	if (*__next < *__first)
4019*e4b17023SJohn Marino 	  return __next;
4020*e4b17023SJohn Marino       return __next;
4021*e4b17023SJohn Marino     }
4022*e4b17023SJohn Marino 
4023*e4b17023SJohn Marino   /**
4024*e4b17023SJohn Marino    *  @brief  Determines the end of a sorted sequence using comparison functor.
4025*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
4026*e4b17023SJohn Marino    *  @param  __first   An iterator.
4027*e4b17023SJohn Marino    *  @param  __last    Another iterator.
4028*e4b17023SJohn Marino    *  @param  __comp    A comparison functor.
4029*e4b17023SJohn Marino    *  @return  An iterator pointing to the last iterator i in [__first, __last)
4030*e4b17023SJohn Marino    *           for which the range [__first, i) is sorted.
4031*e4b17023SJohn Marino   */
4032*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Compare>
4033*e4b17023SJohn Marino     _ForwardIterator
4034*e4b17023SJohn Marino     is_sorted_until(_ForwardIterator __first, _ForwardIterator __last,
4035*e4b17023SJohn Marino 		    _Compare __comp)
4036*e4b17023SJohn Marino     {
4037*e4b17023SJohn Marino       // concept requirements
4038*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4039*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
4040*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type,
4041*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
4042*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4043*e4b17023SJohn Marino 
4044*e4b17023SJohn Marino       if (__first == __last)
4045*e4b17023SJohn Marino 	return __last;
4046*e4b17023SJohn Marino 
4047*e4b17023SJohn Marino       _ForwardIterator __next = __first;
4048*e4b17023SJohn Marino       for (++__next; __next != __last; __first = __next, ++__next)
4049*e4b17023SJohn Marino 	if (__comp(*__next, *__first))
4050*e4b17023SJohn Marino 	  return __next;
4051*e4b17023SJohn Marino       return __next;
4052*e4b17023SJohn Marino     }
4053*e4b17023SJohn Marino 
4054*e4b17023SJohn Marino   /**
4055*e4b17023SJohn Marino    *  @brief  Determines min and max at once as an ordered pair.
4056*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
4057*e4b17023SJohn Marino    *  @param  __a  A thing of arbitrary type.
4058*e4b17023SJohn Marino    *  @param  __b  Another thing of arbitrary type.
4059*e4b17023SJohn Marino    *  @return A pair(__b, __a) if __b is smaller than __a, pair(__a,
4060*e4b17023SJohn Marino    *  __b) otherwise.
4061*e4b17023SJohn Marino   */
4062*e4b17023SJohn Marino   template<typename _Tp>
4063*e4b17023SJohn Marino     inline pair<const _Tp&, const _Tp&>
4064*e4b17023SJohn Marino     minmax(const _Tp& __a, const _Tp& __b)
4065*e4b17023SJohn Marino     {
4066*e4b17023SJohn Marino       // concept requirements
4067*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
4068*e4b17023SJohn Marino 
4069*e4b17023SJohn Marino       return __b < __a ? pair<const _Tp&, const _Tp&>(__b, __a)
4070*e4b17023SJohn Marino 	               : pair<const _Tp&, const _Tp&>(__a, __b);
4071*e4b17023SJohn Marino     }
4072*e4b17023SJohn Marino 
4073*e4b17023SJohn Marino   /**
4074*e4b17023SJohn Marino    *  @brief  Determines min and max at once as an ordered pair.
4075*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
4076*e4b17023SJohn Marino    *  @param  __a  A thing of arbitrary type.
4077*e4b17023SJohn Marino    *  @param  __b  Another thing of arbitrary type.
4078*e4b17023SJohn Marino    *  @param  __comp  A @link comparison_functors comparison functor @endlink.
4079*e4b17023SJohn Marino    *  @return A pair(__b, __a) if __b is smaller than __a, pair(__a,
4080*e4b17023SJohn Marino    *  __b) otherwise.
4081*e4b17023SJohn Marino   */
4082*e4b17023SJohn Marino   template<typename _Tp, typename _Compare>
4083*e4b17023SJohn Marino     inline pair<const _Tp&, const _Tp&>
4084*e4b17023SJohn Marino     minmax(const _Tp& __a, const _Tp& __b, _Compare __comp)
4085*e4b17023SJohn Marino     {
4086*e4b17023SJohn Marino       return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a)
4087*e4b17023SJohn Marino 	                      : pair<const _Tp&, const _Tp&>(__a, __b);
4088*e4b17023SJohn Marino     }
4089*e4b17023SJohn Marino 
4090*e4b17023SJohn Marino   /**
4091*e4b17023SJohn Marino    *  @brief  Return a pair of iterators pointing to the minimum and maximum
4092*e4b17023SJohn Marino    *          elements in a range.
4093*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
4094*e4b17023SJohn Marino    *  @param  __first  Start of range.
4095*e4b17023SJohn Marino    *  @param  __last   End of range.
4096*e4b17023SJohn Marino    *  @return  make_pair(m, M), where m is the first iterator i in
4097*e4b17023SJohn Marino    *           [__first, __last) such that no other element in the range is
4098*e4b17023SJohn Marino    *           smaller, and where M is the last iterator i in [__first, __last)
4099*e4b17023SJohn Marino    *           such that no other element in the range is larger.
4100*e4b17023SJohn Marino   */
4101*e4b17023SJohn Marino   template<typename _ForwardIterator>
4102*e4b17023SJohn Marino     pair<_ForwardIterator, _ForwardIterator>
4103*e4b17023SJohn Marino     minmax_element(_ForwardIterator __first, _ForwardIterator __last)
4104*e4b17023SJohn Marino     {
4105*e4b17023SJohn Marino       // concept requirements
4106*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4107*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<
4108*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
4109*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4110*e4b17023SJohn Marino 
4111*e4b17023SJohn Marino       _ForwardIterator __next = __first;
4112*e4b17023SJohn Marino       if (__first == __last
4113*e4b17023SJohn Marino 	  || ++__next == __last)
4114*e4b17023SJohn Marino 	return std::make_pair(__first, __first);
4115*e4b17023SJohn Marino 
4116*e4b17023SJohn Marino       _ForwardIterator __min, __max;
4117*e4b17023SJohn Marino       if (*__next < *__first)
4118*e4b17023SJohn Marino 	{
4119*e4b17023SJohn Marino 	  __min = __next;
4120*e4b17023SJohn Marino 	  __max = __first;
4121*e4b17023SJohn Marino 	}
4122*e4b17023SJohn Marino       else
4123*e4b17023SJohn Marino 	{
4124*e4b17023SJohn Marino 	  __min = __first;
4125*e4b17023SJohn Marino 	  __max = __next;
4126*e4b17023SJohn Marino 	}
4127*e4b17023SJohn Marino 
4128*e4b17023SJohn Marino       __first = __next;
4129*e4b17023SJohn Marino       ++__first;
4130*e4b17023SJohn Marino 
4131*e4b17023SJohn Marino       while (__first != __last)
4132*e4b17023SJohn Marino 	{
4133*e4b17023SJohn Marino 	  __next = __first;
4134*e4b17023SJohn Marino 	  if (++__next == __last)
4135*e4b17023SJohn Marino 	    {
4136*e4b17023SJohn Marino 	      if (*__first < *__min)
4137*e4b17023SJohn Marino 		__min = __first;
4138*e4b17023SJohn Marino 	      else if (!(*__first < *__max))
4139*e4b17023SJohn Marino 		__max = __first;
4140*e4b17023SJohn Marino 	      break;
4141*e4b17023SJohn Marino 	    }
4142*e4b17023SJohn Marino 
4143*e4b17023SJohn Marino 	  if (*__next < *__first)
4144*e4b17023SJohn Marino 	    {
4145*e4b17023SJohn Marino 	      if (*__next < *__min)
4146*e4b17023SJohn Marino 		__min = __next;
4147*e4b17023SJohn Marino 	      if (!(*__first < *__max))
4148*e4b17023SJohn Marino 		__max = __first;
4149*e4b17023SJohn Marino 	    }
4150*e4b17023SJohn Marino 	  else
4151*e4b17023SJohn Marino 	    {
4152*e4b17023SJohn Marino 	      if (*__first < *__min)
4153*e4b17023SJohn Marino 		__min = __first;
4154*e4b17023SJohn Marino 	      if (!(*__next < *__max))
4155*e4b17023SJohn Marino 		__max = __next;
4156*e4b17023SJohn Marino 	    }
4157*e4b17023SJohn Marino 
4158*e4b17023SJohn Marino 	  __first = __next;
4159*e4b17023SJohn Marino 	  ++__first;
4160*e4b17023SJohn Marino 	}
4161*e4b17023SJohn Marino 
4162*e4b17023SJohn Marino       return std::make_pair(__min, __max);
4163*e4b17023SJohn Marino     }
4164*e4b17023SJohn Marino 
4165*e4b17023SJohn Marino   /**
4166*e4b17023SJohn Marino    *  @brief  Return a pair of iterators pointing to the minimum and maximum
4167*e4b17023SJohn Marino    *          elements in a range.
4168*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
4169*e4b17023SJohn Marino    *  @param  __first  Start of range.
4170*e4b17023SJohn Marino    *  @param  __last   End of range.
4171*e4b17023SJohn Marino    *  @param  __comp   Comparison functor.
4172*e4b17023SJohn Marino    *  @return  make_pair(m, M), where m is the first iterator i in
4173*e4b17023SJohn Marino    *           [__first, __last) such that no other element in the range is
4174*e4b17023SJohn Marino    *           smaller, and where M is the last iterator i in [__first, __last)
4175*e4b17023SJohn Marino    *           such that no other element in the range is larger.
4176*e4b17023SJohn Marino   */
4177*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Compare>
4178*e4b17023SJohn Marino     pair<_ForwardIterator, _ForwardIterator>
4179*e4b17023SJohn Marino     minmax_element(_ForwardIterator __first, _ForwardIterator __last,
4180*e4b17023SJohn Marino 		   _Compare __comp)
4181*e4b17023SJohn Marino     {
4182*e4b17023SJohn Marino       // concept requirements
4183*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4184*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
4185*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type,
4186*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
4187*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4188*e4b17023SJohn Marino 
4189*e4b17023SJohn Marino       _ForwardIterator __next = __first;
4190*e4b17023SJohn Marino       if (__first == __last
4191*e4b17023SJohn Marino 	  || ++__next == __last)
4192*e4b17023SJohn Marino 	return std::make_pair(__first, __first);
4193*e4b17023SJohn Marino 
4194*e4b17023SJohn Marino       _ForwardIterator __min, __max;
4195*e4b17023SJohn Marino       if (__comp(*__next, *__first))
4196*e4b17023SJohn Marino 	{
4197*e4b17023SJohn Marino 	  __min = __next;
4198*e4b17023SJohn Marino 	  __max = __first;
4199*e4b17023SJohn Marino 	}
4200*e4b17023SJohn Marino       else
4201*e4b17023SJohn Marino 	{
4202*e4b17023SJohn Marino 	  __min = __first;
4203*e4b17023SJohn Marino 	  __max = __next;
4204*e4b17023SJohn Marino 	}
4205*e4b17023SJohn Marino 
4206*e4b17023SJohn Marino       __first = __next;
4207*e4b17023SJohn Marino       ++__first;
4208*e4b17023SJohn Marino 
4209*e4b17023SJohn Marino       while (__first != __last)
4210*e4b17023SJohn Marino 	{
4211*e4b17023SJohn Marino 	  __next = __first;
4212*e4b17023SJohn Marino 	  if (++__next == __last)
4213*e4b17023SJohn Marino 	    {
4214*e4b17023SJohn Marino 	      if (__comp(*__first, *__min))
4215*e4b17023SJohn Marino 		__min = __first;
4216*e4b17023SJohn Marino 	      else if (!__comp(*__first, *__max))
4217*e4b17023SJohn Marino 		__max = __first;
4218*e4b17023SJohn Marino 	      break;
4219*e4b17023SJohn Marino 	    }
4220*e4b17023SJohn Marino 
4221*e4b17023SJohn Marino 	  if (__comp(*__next, *__first))
4222*e4b17023SJohn Marino 	    {
4223*e4b17023SJohn Marino 	      if (__comp(*__next, *__min))
4224*e4b17023SJohn Marino 		__min = __next;
4225*e4b17023SJohn Marino 	      if (!__comp(*__first, *__max))
4226*e4b17023SJohn Marino 		__max = __first;
4227*e4b17023SJohn Marino 	    }
4228*e4b17023SJohn Marino 	  else
4229*e4b17023SJohn Marino 	    {
4230*e4b17023SJohn Marino 	      if (__comp(*__first, *__min))
4231*e4b17023SJohn Marino 		__min = __first;
4232*e4b17023SJohn Marino 	      if (!__comp(*__next, *__max))
4233*e4b17023SJohn Marino 		__max = __next;
4234*e4b17023SJohn Marino 	    }
4235*e4b17023SJohn Marino 
4236*e4b17023SJohn Marino 	  __first = __next;
4237*e4b17023SJohn Marino 	  ++__first;
4238*e4b17023SJohn Marino 	}
4239*e4b17023SJohn Marino 
4240*e4b17023SJohn Marino       return std::make_pair(__min, __max);
4241*e4b17023SJohn Marino     }
4242*e4b17023SJohn Marino 
4243*e4b17023SJohn Marino   // N2722 + DR 915.
4244*e4b17023SJohn Marino   template<typename _Tp>
4245*e4b17023SJohn Marino     inline _Tp
4246*e4b17023SJohn Marino     min(initializer_list<_Tp> __l)
4247*e4b17023SJohn Marino     { return *std::min_element(__l.begin(), __l.end()); }
4248*e4b17023SJohn Marino 
4249*e4b17023SJohn Marino   template<typename _Tp, typename _Compare>
4250*e4b17023SJohn Marino     inline _Tp
4251*e4b17023SJohn Marino     min(initializer_list<_Tp> __l, _Compare __comp)
4252*e4b17023SJohn Marino     { return *std::min_element(__l.begin(), __l.end(), __comp); }
4253*e4b17023SJohn Marino 
4254*e4b17023SJohn Marino   template<typename _Tp>
4255*e4b17023SJohn Marino     inline _Tp
4256*e4b17023SJohn Marino     max(initializer_list<_Tp> __l)
4257*e4b17023SJohn Marino     { return *std::max_element(__l.begin(), __l.end()); }
4258*e4b17023SJohn Marino 
4259*e4b17023SJohn Marino   template<typename _Tp, typename _Compare>
4260*e4b17023SJohn Marino     inline _Tp
4261*e4b17023SJohn Marino     max(initializer_list<_Tp> __l, _Compare __comp)
4262*e4b17023SJohn Marino     { return *std::max_element(__l.begin(), __l.end(), __comp); }
4263*e4b17023SJohn Marino 
4264*e4b17023SJohn Marino   template<typename _Tp>
4265*e4b17023SJohn Marino     inline pair<_Tp, _Tp>
4266*e4b17023SJohn Marino     minmax(initializer_list<_Tp> __l)
4267*e4b17023SJohn Marino     {
4268*e4b17023SJohn Marino       pair<const _Tp*, const _Tp*> __p =
4269*e4b17023SJohn Marino 	std::minmax_element(__l.begin(), __l.end());
4270*e4b17023SJohn Marino       return std::make_pair(*__p.first, *__p.second);
4271*e4b17023SJohn Marino     }
4272*e4b17023SJohn Marino 
4273*e4b17023SJohn Marino   template<typename _Tp, typename _Compare>
4274*e4b17023SJohn Marino     inline pair<_Tp, _Tp>
4275*e4b17023SJohn Marino     minmax(initializer_list<_Tp> __l, _Compare __comp)
4276*e4b17023SJohn Marino     {
4277*e4b17023SJohn Marino       pair<const _Tp*, const _Tp*> __p =
4278*e4b17023SJohn Marino 	std::minmax_element(__l.begin(), __l.end(), __comp);
4279*e4b17023SJohn Marino       return std::make_pair(*__p.first, *__p.second);
4280*e4b17023SJohn Marino     }
4281*e4b17023SJohn Marino 
4282*e4b17023SJohn Marino   /**
4283*e4b17023SJohn Marino    *  @brief  Checks whether a permutaion of the second sequence is equal
4284*e4b17023SJohn Marino    *          to the first sequence.
4285*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4286*e4b17023SJohn Marino    *  @param  __first1  Start of first range.
4287*e4b17023SJohn Marino    *  @param  __last1   End of first range.
4288*e4b17023SJohn Marino    *  @param  __first2  Start of second range.
4289*e4b17023SJohn Marino    *  @return true if there exists a permutation of the elements in the range
4290*e4b17023SJohn Marino    *          [__first2, __first2 + (__last1 - __first1)), beginning with
4291*e4b17023SJohn Marino    *          ForwardIterator2 begin, such that equal(__first1, __last1, begin)
4292*e4b17023SJohn Marino    *          returns true; otherwise, returns false.
4293*e4b17023SJohn Marino   */
4294*e4b17023SJohn Marino   template<typename _ForwardIterator1, typename _ForwardIterator2>
4295*e4b17023SJohn Marino     bool
4296*e4b17023SJohn Marino     is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
4297*e4b17023SJohn Marino 		   _ForwardIterator2 __first2)
4298*e4b17023SJohn Marino     {
4299*e4b17023SJohn Marino       // Efficiently compare identical prefixes:  O(N) if sequences
4300*e4b17023SJohn Marino       // have the same elements in the same order.
4301*e4b17023SJohn Marino       for (; __first1 != __last1; ++__first1, ++__first2)
4302*e4b17023SJohn Marino 	if (!(*__first1 == *__first2))
4303*e4b17023SJohn Marino 	  break;
4304*e4b17023SJohn Marino 
4305*e4b17023SJohn Marino       if (__first1 == __last1)
4306*e4b17023SJohn Marino 	return true;
4307*e4b17023SJohn Marino 
4308*e4b17023SJohn Marino       // Establish __last2 assuming equal ranges by iterating over the
4309*e4b17023SJohn Marino       // rest of the list.
4310*e4b17023SJohn Marino       _ForwardIterator2 __last2 = __first2;
4311*e4b17023SJohn Marino       std::advance(__last2, std::distance(__first1, __last1));
4312*e4b17023SJohn Marino       for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan)
4313*e4b17023SJohn Marino 	{
4314*e4b17023SJohn Marino 	  if (__scan != _GLIBCXX_STD_A::find(__first1, __scan, *__scan))
4315*e4b17023SJohn Marino 	    continue; // We've seen this one before.
4316*e4b17023SJohn Marino 
4317*e4b17023SJohn Marino 	  auto __matches = std::count(__first2, __last2, *__scan);
4318*e4b17023SJohn Marino 	  if (0 == __matches
4319*e4b17023SJohn Marino 	      || std::count(__scan, __last1, *__scan) != __matches)
4320*e4b17023SJohn Marino 	    return false;
4321*e4b17023SJohn Marino 	}
4322*e4b17023SJohn Marino       return true;
4323*e4b17023SJohn Marino     }
4324*e4b17023SJohn Marino 
4325*e4b17023SJohn Marino   /**
4326*e4b17023SJohn Marino    *  @brief  Checks whether a permutation of the second sequence is equal
4327*e4b17023SJohn Marino    *          to the first sequence.
4328*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4329*e4b17023SJohn Marino    *  @param  __first1  Start of first range.
4330*e4b17023SJohn Marino    *  @param  __last1   End of first range.
4331*e4b17023SJohn Marino    *  @param  __first2  Start of second range.
4332*e4b17023SJohn Marino    *  @param  __pred    A binary predicate.
4333*e4b17023SJohn Marino    *  @return true if there exists a permutation of the elements in
4334*e4b17023SJohn Marino    *          the range [__first2, __first2 + (__last1 - __first1)),
4335*e4b17023SJohn Marino    *          beginning with ForwardIterator2 begin, such that
4336*e4b17023SJohn Marino    *          equal(__first1, __last1, __begin, __pred) returns true;
4337*e4b17023SJohn Marino    *          otherwise, returns false.
4338*e4b17023SJohn Marino   */
4339*e4b17023SJohn Marino   template<typename _ForwardIterator1, typename _ForwardIterator2,
4340*e4b17023SJohn Marino 	   typename _BinaryPredicate>
4341*e4b17023SJohn Marino     bool
4342*e4b17023SJohn Marino     is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
4343*e4b17023SJohn Marino 		   _ForwardIterator2 __first2, _BinaryPredicate __pred)
4344*e4b17023SJohn Marino     {
4345*e4b17023SJohn Marino       // Efficiently compare identical prefixes:  O(N) if sequences
4346*e4b17023SJohn Marino       // have the same elements in the same order.
4347*e4b17023SJohn Marino       for (; __first1 != __last1; ++__first1, ++__first2)
4348*e4b17023SJohn Marino 	if (!bool(__pred(*__first1, *__first2)))
4349*e4b17023SJohn Marino 	  break;
4350*e4b17023SJohn Marino 
4351*e4b17023SJohn Marino       if (__first1 == __last1)
4352*e4b17023SJohn Marino 	return true;
4353*e4b17023SJohn Marino 
4354*e4b17023SJohn Marino       // Establish __last2 assuming equal ranges by iterating over the
4355*e4b17023SJohn Marino       // rest of the list.
4356*e4b17023SJohn Marino       _ForwardIterator2 __last2 = __first2;
4357*e4b17023SJohn Marino       std::advance(__last2, std::distance(__first1, __last1));
4358*e4b17023SJohn Marino       for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan)
4359*e4b17023SJohn Marino 	{
4360*e4b17023SJohn Marino 	  using std::placeholders::_1;
4361*e4b17023SJohn Marino 
4362*e4b17023SJohn Marino 	  if (__scan != _GLIBCXX_STD_A::find_if(__first1, __scan,
4363*e4b17023SJohn Marino 						std::bind(__pred, _1, *__scan)))
4364*e4b17023SJohn Marino 	    continue; // We've seen this one before.
4365*e4b17023SJohn Marino 
4366*e4b17023SJohn Marino 	  auto __matches = std::count_if(__first2, __last2,
4367*e4b17023SJohn Marino 					 std::bind(__pred, _1, *__scan));
4368*e4b17023SJohn Marino 	  if (0 == __matches
4369*e4b17023SJohn Marino 	      || std::count_if(__scan, __last1,
4370*e4b17023SJohn Marino 			       std::bind(__pred, _1, *__scan)) != __matches)
4371*e4b17023SJohn Marino 	    return false;
4372*e4b17023SJohn Marino 	}
4373*e4b17023SJohn Marino       return true;
4374*e4b17023SJohn Marino     }
4375*e4b17023SJohn Marino 
4376*e4b17023SJohn Marino #ifdef _GLIBCXX_USE_C99_STDINT_TR1
4377*e4b17023SJohn Marino   /**
4378*e4b17023SJohn Marino    *  @brief Shuffle the elements of a sequence using a uniform random
4379*e4b17023SJohn Marino    *         number generator.
4380*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
4381*e4b17023SJohn Marino    *  @param  __first   A forward iterator.
4382*e4b17023SJohn Marino    *  @param  __last    A forward iterator.
4383*e4b17023SJohn Marino    *  @param  __g       A UniformRandomNumberGenerator (26.5.1.3).
4384*e4b17023SJohn Marino    *  @return  Nothing.
4385*e4b17023SJohn Marino    *
4386*e4b17023SJohn Marino    *  Reorders the elements in the range @p [__first,__last) using @p __g to
4387*e4b17023SJohn Marino    *  provide random numbers.
4388*e4b17023SJohn Marino   */
4389*e4b17023SJohn Marino   template<typename _RandomAccessIterator,
4390*e4b17023SJohn Marino 	   typename _UniformRandomNumberGenerator>
4391*e4b17023SJohn Marino     void
4392*e4b17023SJohn Marino     shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
4393*e4b17023SJohn Marino 	    _UniformRandomNumberGenerator&& __g)
4394*e4b17023SJohn Marino     {
4395*e4b17023SJohn Marino       // concept requirements
4396*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
4397*e4b17023SJohn Marino 	    _RandomAccessIterator>)
4398*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4399*e4b17023SJohn Marino 
4400*e4b17023SJohn Marino       if (__first == __last)
4401*e4b17023SJohn Marino 	return;
4402*e4b17023SJohn Marino 
4403*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
4404*e4b17023SJohn Marino 	_DistanceType;
4405*e4b17023SJohn Marino 
4406*e4b17023SJohn Marino       typedef typename std::make_unsigned<_DistanceType>::type __ud_type;
4407*e4b17023SJohn Marino       typedef typename std::uniform_int_distribution<__ud_type> __distr_type;
4408*e4b17023SJohn Marino       typedef typename __distr_type::param_type __p_type;
4409*e4b17023SJohn Marino       __distr_type __d;
4410*e4b17023SJohn Marino 
4411*e4b17023SJohn Marino       for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
4412*e4b17023SJohn Marino 	std::iter_swap(__i, __first + __d(__g, __p_type(0, __i - __first)));
4413*e4b17023SJohn Marino     }
4414*e4b17023SJohn Marino #endif
4415*e4b17023SJohn Marino 
4416*e4b17023SJohn Marino #endif // __GXX_EXPERIMENTAL_CXX0X__
4417*e4b17023SJohn Marino 
4418*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
4419*e4b17023SJohn Marino 
4420*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_ALGO
4421*e4b17023SJohn Marino 
4422*e4b17023SJohn Marino   /**
4423*e4b17023SJohn Marino    *  @brief Apply a function to every element of a sequence.
4424*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4425*e4b17023SJohn Marino    *  @param  __first  An input iterator.
4426*e4b17023SJohn Marino    *  @param  __last   An input iterator.
4427*e4b17023SJohn Marino    *  @param  __f      A unary function object.
4428*e4b17023SJohn Marino    *  @return   @p __f (std::move(@p __f) in C++0x).
4429*e4b17023SJohn Marino    *
4430*e4b17023SJohn Marino    *  Applies the function object @p __f to each element in the range
4431*e4b17023SJohn Marino    *  @p [first,last).  @p __f must not modify the order of the sequence.
4432*e4b17023SJohn Marino    *  If @p __f has a return value it is ignored.
4433*e4b17023SJohn Marino   */
4434*e4b17023SJohn Marino   template<typename _InputIterator, typename _Function>
4435*e4b17023SJohn Marino     _Function
4436*e4b17023SJohn Marino     for_each(_InputIterator __first, _InputIterator __last, _Function __f)
4437*e4b17023SJohn Marino     {
4438*e4b17023SJohn Marino       // concept requirements
4439*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4440*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4441*e4b17023SJohn Marino       for (; __first != __last; ++__first)
4442*e4b17023SJohn Marino 	__f(*__first);
4443*e4b17023SJohn Marino       return _GLIBCXX_MOVE(__f);
4444*e4b17023SJohn Marino     }
4445*e4b17023SJohn Marino 
4446*e4b17023SJohn Marino   /**
4447*e4b17023SJohn Marino    *  @brief Find the first occurrence of a value in a sequence.
4448*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4449*e4b17023SJohn Marino    *  @param  __first  An input iterator.
4450*e4b17023SJohn Marino    *  @param  __last   An input iterator.
4451*e4b17023SJohn Marino    *  @param  __val    The value to find.
4452*e4b17023SJohn Marino    *  @return   The first iterator @c i in the range @p [__first,__last)
4453*e4b17023SJohn Marino    *  such that @c *i == @p __val, or @p __last if no such iterator exists.
4454*e4b17023SJohn Marino   */
4455*e4b17023SJohn Marino   template<typename _InputIterator, typename _Tp>
4456*e4b17023SJohn Marino     inline _InputIterator
4457*e4b17023SJohn Marino     find(_InputIterator __first, _InputIterator __last,
4458*e4b17023SJohn Marino 	 const _Tp& __val)
4459*e4b17023SJohn Marino     {
4460*e4b17023SJohn Marino       // concept requirements
4461*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4462*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualOpConcept<
4463*e4b17023SJohn Marino 		typename iterator_traits<_InputIterator>::value_type, _Tp>)
4464*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4465*e4b17023SJohn Marino       return std::__find(__first, __last, __val,
4466*e4b17023SJohn Marino 		         std::__iterator_category(__first));
4467*e4b17023SJohn Marino     }
4468*e4b17023SJohn Marino 
4469*e4b17023SJohn Marino   /**
4470*e4b17023SJohn Marino    *  @brief Find the first element in a sequence for which a
4471*e4b17023SJohn Marino    *         predicate is true.
4472*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4473*e4b17023SJohn Marino    *  @param  __first  An input iterator.
4474*e4b17023SJohn Marino    *  @param  __last   An input iterator.
4475*e4b17023SJohn Marino    *  @param  __pred   A predicate.
4476*e4b17023SJohn Marino    *  @return   The first iterator @c i in the range @p [__first,__last)
4477*e4b17023SJohn Marino    *  such that @p __pred(*i) is true, or @p __last if no such iterator exists.
4478*e4b17023SJohn Marino   */
4479*e4b17023SJohn Marino   template<typename _InputIterator, typename _Predicate>
4480*e4b17023SJohn Marino     inline _InputIterator
4481*e4b17023SJohn Marino     find_if(_InputIterator __first, _InputIterator __last,
4482*e4b17023SJohn Marino 	    _Predicate __pred)
4483*e4b17023SJohn Marino     {
4484*e4b17023SJohn Marino       // concept requirements
4485*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4486*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
4487*e4b17023SJohn Marino 	      typename iterator_traits<_InputIterator>::value_type>)
4488*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4489*e4b17023SJohn Marino       return std::__find_if(__first, __last, __pred,
4490*e4b17023SJohn Marino 			    std::__iterator_category(__first));
4491*e4b17023SJohn Marino     }
4492*e4b17023SJohn Marino 
4493*e4b17023SJohn Marino   /**
4494*e4b17023SJohn Marino    *  @brief  Find element from a set in a sequence.
4495*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4496*e4b17023SJohn Marino    *  @param  __first1  Start of range to search.
4497*e4b17023SJohn Marino    *  @param  __last1   End of range to search.
4498*e4b17023SJohn Marino    *  @param  __first2  Start of match candidates.
4499*e4b17023SJohn Marino    *  @param  __last2   End of match candidates.
4500*e4b17023SJohn Marino    *  @return   The first iterator @c i in the range
4501*e4b17023SJohn Marino    *  @p [__first1,__last1) such that @c *i == @p *(i2) such that i2 is an
4502*e4b17023SJohn Marino    *  iterator in [__first2,__last2), or @p __last1 if no such iterator exists.
4503*e4b17023SJohn Marino    *
4504*e4b17023SJohn Marino    *  Searches the range @p [__first1,__last1) for an element that is
4505*e4b17023SJohn Marino    *  equal to some element in the range [__first2,__last2).  If
4506*e4b17023SJohn Marino    *  found, returns an iterator in the range [__first1,__last1),
4507*e4b17023SJohn Marino    *  otherwise returns @p __last1.
4508*e4b17023SJohn Marino   */
4509*e4b17023SJohn Marino   template<typename _InputIterator, typename _ForwardIterator>
4510*e4b17023SJohn Marino     _InputIterator
4511*e4b17023SJohn Marino     find_first_of(_InputIterator __first1, _InputIterator __last1,
4512*e4b17023SJohn Marino 		  _ForwardIterator __first2, _ForwardIterator __last2)
4513*e4b17023SJohn Marino     {
4514*e4b17023SJohn Marino       // concept requirements
4515*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4516*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4517*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualOpConcept<
4518*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type,
4519*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
4520*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first1, __last1);
4521*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first2, __last2);
4522*e4b17023SJohn Marino 
4523*e4b17023SJohn Marino       for (; __first1 != __last1; ++__first1)
4524*e4b17023SJohn Marino 	for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter)
4525*e4b17023SJohn Marino 	  if (*__first1 == *__iter)
4526*e4b17023SJohn Marino 	    return __first1;
4527*e4b17023SJohn Marino       return __last1;
4528*e4b17023SJohn Marino     }
4529*e4b17023SJohn Marino 
4530*e4b17023SJohn Marino   /**
4531*e4b17023SJohn Marino    *  @brief  Find element from a set in a sequence using a predicate.
4532*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4533*e4b17023SJohn Marino    *  @param  __first1  Start of range to search.
4534*e4b17023SJohn Marino    *  @param  __last1   End of range to search.
4535*e4b17023SJohn Marino    *  @param  __first2  Start of match candidates.
4536*e4b17023SJohn Marino    *  @param  __last2   End of match candidates.
4537*e4b17023SJohn Marino    *  @param  __comp    Predicate to use.
4538*e4b17023SJohn Marino    *  @return   The first iterator @c i in the range
4539*e4b17023SJohn Marino    *  @p [__first1,__last1) such that @c comp(*i, @p *(i2)) is true
4540*e4b17023SJohn Marino    *  and i2 is an iterator in [__first2,__last2), or @p __last1 if no
4541*e4b17023SJohn Marino    *  such iterator exists.
4542*e4b17023SJohn Marino    *
4543*e4b17023SJohn Marino 
4544*e4b17023SJohn Marino    *  Searches the range @p [__first1,__last1) for an element that is
4545*e4b17023SJohn Marino    *  equal to some element in the range [__first2,__last2).  If
4546*e4b17023SJohn Marino    *  found, returns an iterator in the range [__first1,__last1),
4547*e4b17023SJohn Marino    *  otherwise returns @p __last1.
4548*e4b17023SJohn Marino   */
4549*e4b17023SJohn Marino   template<typename _InputIterator, typename _ForwardIterator,
4550*e4b17023SJohn Marino 	   typename _BinaryPredicate>
4551*e4b17023SJohn Marino     _InputIterator
4552*e4b17023SJohn Marino     find_first_of(_InputIterator __first1, _InputIterator __last1,
4553*e4b17023SJohn Marino 		  _ForwardIterator __first2, _ForwardIterator __last2,
4554*e4b17023SJohn Marino 		  _BinaryPredicate __comp)
4555*e4b17023SJohn Marino     {
4556*e4b17023SJohn Marino       // concept requirements
4557*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4558*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4559*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
4560*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type,
4561*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
4562*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first1, __last1);
4563*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first2, __last2);
4564*e4b17023SJohn Marino 
4565*e4b17023SJohn Marino       for (; __first1 != __last1; ++__first1)
4566*e4b17023SJohn Marino 	for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter)
4567*e4b17023SJohn Marino 	  if (__comp(*__first1, *__iter))
4568*e4b17023SJohn Marino 	    return __first1;
4569*e4b17023SJohn Marino       return __last1;
4570*e4b17023SJohn Marino     }
4571*e4b17023SJohn Marino 
4572*e4b17023SJohn Marino   /**
4573*e4b17023SJohn Marino    *  @brief Find two adjacent values in a sequence that are equal.
4574*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4575*e4b17023SJohn Marino    *  @param  __first  A forward iterator.
4576*e4b17023SJohn Marino    *  @param  __last   A forward iterator.
4577*e4b17023SJohn Marino    *  @return   The first iterator @c i such that @c i and @c i+1 are both
4578*e4b17023SJohn Marino    *  valid iterators in @p [__first,__last) and such that @c *i == @c *(i+1),
4579*e4b17023SJohn Marino    *  or @p __last if no such iterator exists.
4580*e4b17023SJohn Marino   */
4581*e4b17023SJohn Marino   template<typename _ForwardIterator>
4582*e4b17023SJohn Marino     _ForwardIterator
4583*e4b17023SJohn Marino     adjacent_find(_ForwardIterator __first, _ForwardIterator __last)
4584*e4b17023SJohn Marino     {
4585*e4b17023SJohn Marino       // concept requirements
4586*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4587*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualityComparableConcept<
4588*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
4589*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4590*e4b17023SJohn Marino       if (__first == __last)
4591*e4b17023SJohn Marino 	return __last;
4592*e4b17023SJohn Marino       _ForwardIterator __next = __first;
4593*e4b17023SJohn Marino       while(++__next != __last)
4594*e4b17023SJohn Marino 	{
4595*e4b17023SJohn Marino 	  if (*__first == *__next)
4596*e4b17023SJohn Marino 	    return __first;
4597*e4b17023SJohn Marino 	  __first = __next;
4598*e4b17023SJohn Marino 	}
4599*e4b17023SJohn Marino       return __last;
4600*e4b17023SJohn Marino     }
4601*e4b17023SJohn Marino 
4602*e4b17023SJohn Marino   /**
4603*e4b17023SJohn Marino    *  @brief Find two adjacent values in a sequence using a predicate.
4604*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4605*e4b17023SJohn Marino    *  @param  __first         A forward iterator.
4606*e4b17023SJohn Marino    *  @param  __last          A forward iterator.
4607*e4b17023SJohn Marino    *  @param  __binary_pred   A binary predicate.
4608*e4b17023SJohn Marino    *  @return   The first iterator @c i such that @c i and @c i+1 are both
4609*e4b17023SJohn Marino    *  valid iterators in @p [__first,__last) and such that
4610*e4b17023SJohn Marino    *  @p __binary_pred(*i,*(i+1)) is true, or @p __last if no such iterator
4611*e4b17023SJohn Marino    *  exists.
4612*e4b17023SJohn Marino   */
4613*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _BinaryPredicate>
4614*e4b17023SJohn Marino     _ForwardIterator
4615*e4b17023SJohn Marino     adjacent_find(_ForwardIterator __first, _ForwardIterator __last,
4616*e4b17023SJohn Marino 		  _BinaryPredicate __binary_pred)
4617*e4b17023SJohn Marino     {
4618*e4b17023SJohn Marino       // concept requirements
4619*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4620*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
4621*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type,
4622*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
4623*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4624*e4b17023SJohn Marino       if (__first == __last)
4625*e4b17023SJohn Marino 	return __last;
4626*e4b17023SJohn Marino       _ForwardIterator __next = __first;
4627*e4b17023SJohn Marino       while(++__next != __last)
4628*e4b17023SJohn Marino 	{
4629*e4b17023SJohn Marino 	  if (__binary_pred(*__first, *__next))
4630*e4b17023SJohn Marino 	    return __first;
4631*e4b17023SJohn Marino 	  __first = __next;
4632*e4b17023SJohn Marino 	}
4633*e4b17023SJohn Marino       return __last;
4634*e4b17023SJohn Marino     }
4635*e4b17023SJohn Marino 
4636*e4b17023SJohn Marino   /**
4637*e4b17023SJohn Marino    *  @brief Count the number of copies of a value in a sequence.
4638*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4639*e4b17023SJohn Marino    *  @param  __first  An input iterator.
4640*e4b17023SJohn Marino    *  @param  __last   An input iterator.
4641*e4b17023SJohn Marino    *  @param  __value  The value to be counted.
4642*e4b17023SJohn Marino    *  @return   The number of iterators @c i in the range @p [__first,__last)
4643*e4b17023SJohn Marino    *  for which @c *i == @p __value
4644*e4b17023SJohn Marino   */
4645*e4b17023SJohn Marino   template<typename _InputIterator, typename _Tp>
4646*e4b17023SJohn Marino     typename iterator_traits<_InputIterator>::difference_type
4647*e4b17023SJohn Marino     count(_InputIterator __first, _InputIterator __last, const _Tp& __value)
4648*e4b17023SJohn Marino     {
4649*e4b17023SJohn Marino       // concept requirements
4650*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4651*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualOpConcept<
4652*e4b17023SJohn Marino 	typename iterator_traits<_InputIterator>::value_type, _Tp>)
4653*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4654*e4b17023SJohn Marino       typename iterator_traits<_InputIterator>::difference_type __n = 0;
4655*e4b17023SJohn Marino       for (; __first != __last; ++__first)
4656*e4b17023SJohn Marino 	if (*__first == __value)
4657*e4b17023SJohn Marino 	  ++__n;
4658*e4b17023SJohn Marino       return __n;
4659*e4b17023SJohn Marino     }
4660*e4b17023SJohn Marino 
4661*e4b17023SJohn Marino   /**
4662*e4b17023SJohn Marino    *  @brief Count the elements of a sequence for which a predicate is true.
4663*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4664*e4b17023SJohn Marino    *  @param  __first  An input iterator.
4665*e4b17023SJohn Marino    *  @param  __last   An input iterator.
4666*e4b17023SJohn Marino    *  @param  __pred   A predicate.
4667*e4b17023SJohn Marino    *  @return   The number of iterators @c i in the range @p [__first,__last)
4668*e4b17023SJohn Marino    *  for which @p __pred(*i) is true.
4669*e4b17023SJohn Marino   */
4670*e4b17023SJohn Marino   template<typename _InputIterator, typename _Predicate>
4671*e4b17023SJohn Marino     typename iterator_traits<_InputIterator>::difference_type
4672*e4b17023SJohn Marino     count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
4673*e4b17023SJohn Marino     {
4674*e4b17023SJohn Marino       // concept requirements
4675*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4676*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
4677*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
4678*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4679*e4b17023SJohn Marino       typename iterator_traits<_InputIterator>::difference_type __n = 0;
4680*e4b17023SJohn Marino       for (; __first != __last; ++__first)
4681*e4b17023SJohn Marino 	if (__pred(*__first))
4682*e4b17023SJohn Marino 	  ++__n;
4683*e4b17023SJohn Marino       return __n;
4684*e4b17023SJohn Marino     }
4685*e4b17023SJohn Marino 
4686*e4b17023SJohn Marino   /**
4687*e4b17023SJohn Marino    *  @brief Search a sequence for a matching sub-sequence.
4688*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4689*e4b17023SJohn Marino    *  @param  __first1  A forward iterator.
4690*e4b17023SJohn Marino    *  @param  __last1   A forward iterator.
4691*e4b17023SJohn Marino    *  @param  __first2  A forward iterator.
4692*e4b17023SJohn Marino    *  @param  __last2   A forward iterator.
4693*e4b17023SJohn Marino    *  @return The first iterator @c i in the range @p
4694*e4b17023SJohn Marino    *  [__first1,__last1-(__last2-__first2)) such that @c *(i+N) == @p
4695*e4b17023SJohn Marino    *  *(__first2+N) for each @c N in the range @p
4696*e4b17023SJohn Marino    *  [0,__last2-__first2), or @p __last1 if no such iterator exists.
4697*e4b17023SJohn Marino    *
4698*e4b17023SJohn Marino    *  Searches the range @p [__first1,__last1) for a sub-sequence that
4699*e4b17023SJohn Marino    *  compares equal value-by-value with the sequence given by @p
4700*e4b17023SJohn Marino    *  [__first2,__last2) and returns an iterator to the first element
4701*e4b17023SJohn Marino    *  of the sub-sequence, or @p __last1 if the sub-sequence is not
4702*e4b17023SJohn Marino    *  found.
4703*e4b17023SJohn Marino    *
4704*e4b17023SJohn Marino    *  Because the sub-sequence must lie completely within the range @p
4705*e4b17023SJohn Marino    *  [__first1,__last1) it must start at a position less than @p
4706*e4b17023SJohn Marino    *  __last1-(__last2-__first2) where @p __last2-__first2 is the
4707*e4b17023SJohn Marino    *  length of the sub-sequence.
4708*e4b17023SJohn Marino    *
4709*e4b17023SJohn Marino    *  This means that the returned iterator @c i will be in the range
4710*e4b17023SJohn Marino    *  @p [__first1,__last1-(__last2-__first2))
4711*e4b17023SJohn Marino   */
4712*e4b17023SJohn Marino   template<typename _ForwardIterator1, typename _ForwardIterator2>
4713*e4b17023SJohn Marino     _ForwardIterator1
4714*e4b17023SJohn Marino     search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
4715*e4b17023SJohn Marino 	   _ForwardIterator2 __first2, _ForwardIterator2 __last2)
4716*e4b17023SJohn Marino     {
4717*e4b17023SJohn Marino       // concept requirements
4718*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
4719*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
4720*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualOpConcept<
4721*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator1>::value_type,
4722*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator2>::value_type>)
4723*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first1, __last1);
4724*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first2, __last2);
4725*e4b17023SJohn Marino 
4726*e4b17023SJohn Marino       // Test for empty ranges
4727*e4b17023SJohn Marino       if (__first1 == __last1 || __first2 == __last2)
4728*e4b17023SJohn Marino 	return __first1;
4729*e4b17023SJohn Marino 
4730*e4b17023SJohn Marino       // Test for a pattern of length 1.
4731*e4b17023SJohn Marino       _ForwardIterator2 __p1(__first2);
4732*e4b17023SJohn Marino       if (++__p1 == __last2)
4733*e4b17023SJohn Marino 	return _GLIBCXX_STD_A::find(__first1, __last1, *__first2);
4734*e4b17023SJohn Marino 
4735*e4b17023SJohn Marino       // General case.
4736*e4b17023SJohn Marino       _ForwardIterator2 __p;
4737*e4b17023SJohn Marino       _ForwardIterator1 __current = __first1;
4738*e4b17023SJohn Marino 
4739*e4b17023SJohn Marino       for (;;)
4740*e4b17023SJohn Marino 	{
4741*e4b17023SJohn Marino 	  __first1 = _GLIBCXX_STD_A::find(__first1, __last1, *__first2);
4742*e4b17023SJohn Marino 	  if (__first1 == __last1)
4743*e4b17023SJohn Marino 	    return __last1;
4744*e4b17023SJohn Marino 
4745*e4b17023SJohn Marino 	  __p = __p1;
4746*e4b17023SJohn Marino 	  __current = __first1;
4747*e4b17023SJohn Marino 	  if (++__current == __last1)
4748*e4b17023SJohn Marino 	    return __last1;
4749*e4b17023SJohn Marino 
4750*e4b17023SJohn Marino 	  while (*__current == *__p)
4751*e4b17023SJohn Marino 	    {
4752*e4b17023SJohn Marino 	      if (++__p == __last2)
4753*e4b17023SJohn Marino 		return __first1;
4754*e4b17023SJohn Marino 	      if (++__current == __last1)
4755*e4b17023SJohn Marino 		return __last1;
4756*e4b17023SJohn Marino 	    }
4757*e4b17023SJohn Marino 	  ++__first1;
4758*e4b17023SJohn Marino 	}
4759*e4b17023SJohn Marino       return __first1;
4760*e4b17023SJohn Marino     }
4761*e4b17023SJohn Marino 
4762*e4b17023SJohn Marino   /**
4763*e4b17023SJohn Marino    *  @brief Search a sequence for a matching sub-sequence using a predicate.
4764*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4765*e4b17023SJohn Marino    *  @param  __first1     A forward iterator.
4766*e4b17023SJohn Marino    *  @param  __last1      A forward iterator.
4767*e4b17023SJohn Marino    *  @param  __first2     A forward iterator.
4768*e4b17023SJohn Marino    *  @param  __last2      A forward iterator.
4769*e4b17023SJohn Marino    *  @param  __predicate  A binary predicate.
4770*e4b17023SJohn Marino    *  @return   The first iterator @c i in the range
4771*e4b17023SJohn Marino    *  @p [__first1,__last1-(__last2-__first2)) such that
4772*e4b17023SJohn Marino    *  @p __predicate(*(i+N),*(__first2+N)) is true for each @c N in the range
4773*e4b17023SJohn Marino    *  @p [0,__last2-__first2), or @p __last1 if no such iterator exists.
4774*e4b17023SJohn Marino    *
4775*e4b17023SJohn Marino    *  Searches the range @p [__first1,__last1) for a sub-sequence that
4776*e4b17023SJohn Marino    *  compares equal value-by-value with the sequence given by @p
4777*e4b17023SJohn Marino    *  [__first2,__last2), using @p __predicate to determine equality,
4778*e4b17023SJohn Marino    *  and returns an iterator to the first element of the
4779*e4b17023SJohn Marino    *  sub-sequence, or @p __last1 if no such iterator exists.
4780*e4b17023SJohn Marino    *
4781*e4b17023SJohn Marino    *  @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2)
4782*e4b17023SJohn Marino   */
4783*e4b17023SJohn Marino   template<typename _ForwardIterator1, typename _ForwardIterator2,
4784*e4b17023SJohn Marino 	   typename _BinaryPredicate>
4785*e4b17023SJohn Marino     _ForwardIterator1
4786*e4b17023SJohn Marino     search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
4787*e4b17023SJohn Marino 	   _ForwardIterator2 __first2, _ForwardIterator2 __last2,
4788*e4b17023SJohn Marino 	   _BinaryPredicate  __predicate)
4789*e4b17023SJohn Marino     {
4790*e4b17023SJohn Marino       // concept requirements
4791*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
4792*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
4793*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
4794*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator1>::value_type,
4795*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator2>::value_type>)
4796*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first1, __last1);
4797*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first2, __last2);
4798*e4b17023SJohn Marino 
4799*e4b17023SJohn Marino       // Test for empty ranges
4800*e4b17023SJohn Marino       if (__first1 == __last1 || __first2 == __last2)
4801*e4b17023SJohn Marino 	return __first1;
4802*e4b17023SJohn Marino 
4803*e4b17023SJohn Marino       // Test for a pattern of length 1.
4804*e4b17023SJohn Marino       _ForwardIterator2 __p1(__first2);
4805*e4b17023SJohn Marino       if (++__p1 == __last2)
4806*e4b17023SJohn Marino 	{
4807*e4b17023SJohn Marino 	  while (__first1 != __last1
4808*e4b17023SJohn Marino 		 && !bool(__predicate(*__first1, *__first2)))
4809*e4b17023SJohn Marino 	    ++__first1;
4810*e4b17023SJohn Marino 	  return __first1;
4811*e4b17023SJohn Marino 	}
4812*e4b17023SJohn Marino 
4813*e4b17023SJohn Marino       // General case.
4814*e4b17023SJohn Marino       _ForwardIterator2 __p;
4815*e4b17023SJohn Marino       _ForwardIterator1 __current = __first1;
4816*e4b17023SJohn Marino 
4817*e4b17023SJohn Marino       for (;;)
4818*e4b17023SJohn Marino 	{
4819*e4b17023SJohn Marino 	  while (__first1 != __last1
4820*e4b17023SJohn Marino 		 && !bool(__predicate(*__first1, *__first2)))
4821*e4b17023SJohn Marino 	    ++__first1;
4822*e4b17023SJohn Marino 	  if (__first1 == __last1)
4823*e4b17023SJohn Marino 	    return __last1;
4824*e4b17023SJohn Marino 
4825*e4b17023SJohn Marino 	  __p = __p1;
4826*e4b17023SJohn Marino 	  __current = __first1;
4827*e4b17023SJohn Marino 	  if (++__current == __last1)
4828*e4b17023SJohn Marino 	    return __last1;
4829*e4b17023SJohn Marino 
4830*e4b17023SJohn Marino 	  while (__predicate(*__current, *__p))
4831*e4b17023SJohn Marino 	    {
4832*e4b17023SJohn Marino 	      if (++__p == __last2)
4833*e4b17023SJohn Marino 		return __first1;
4834*e4b17023SJohn Marino 	      if (++__current == __last1)
4835*e4b17023SJohn Marino 		return __last1;
4836*e4b17023SJohn Marino 	    }
4837*e4b17023SJohn Marino 	  ++__first1;
4838*e4b17023SJohn Marino 	}
4839*e4b17023SJohn Marino       return __first1;
4840*e4b17023SJohn Marino     }
4841*e4b17023SJohn Marino 
4842*e4b17023SJohn Marino 
4843*e4b17023SJohn Marino   /**
4844*e4b17023SJohn Marino    *  @brief Search a sequence for a number of consecutive values.
4845*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4846*e4b17023SJohn Marino    *  @param  __first  A forward iterator.
4847*e4b17023SJohn Marino    *  @param  __last   A forward iterator.
4848*e4b17023SJohn Marino    *  @param  __count  The number of consecutive values.
4849*e4b17023SJohn Marino    *  @param  __val    The value to find.
4850*e4b17023SJohn Marino    *  @return The first iterator @c i in the range @p
4851*e4b17023SJohn Marino    *  [__first,__last-__count) such that @c *(i+N) == @p __val for
4852*e4b17023SJohn Marino    *  each @c N in the range @p [0,__count), or @p __last if no such
4853*e4b17023SJohn Marino    *  iterator exists.
4854*e4b17023SJohn Marino    *
4855*e4b17023SJohn Marino    *  Searches the range @p [__first,__last) for @p count consecutive elements
4856*e4b17023SJohn Marino    *  equal to @p __val.
4857*e4b17023SJohn Marino   */
4858*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Integer, typename _Tp>
4859*e4b17023SJohn Marino     _ForwardIterator
4860*e4b17023SJohn Marino     search_n(_ForwardIterator __first, _ForwardIterator __last,
4861*e4b17023SJohn Marino 	     _Integer __count, const _Tp& __val)
4862*e4b17023SJohn Marino     {
4863*e4b17023SJohn Marino       // concept requirements
4864*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4865*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualOpConcept<
4866*e4b17023SJohn Marino 	typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
4867*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4868*e4b17023SJohn Marino 
4869*e4b17023SJohn Marino       if (__count <= 0)
4870*e4b17023SJohn Marino 	return __first;
4871*e4b17023SJohn Marino       if (__count == 1)
4872*e4b17023SJohn Marino 	return _GLIBCXX_STD_A::find(__first, __last, __val);
4873*e4b17023SJohn Marino       return std::__search_n(__first, __last, __count, __val,
4874*e4b17023SJohn Marino 			     std::__iterator_category(__first));
4875*e4b17023SJohn Marino     }
4876*e4b17023SJohn Marino 
4877*e4b17023SJohn Marino 
4878*e4b17023SJohn Marino   /**
4879*e4b17023SJohn Marino    *  @brief Search a sequence for a number of consecutive values using a
4880*e4b17023SJohn Marino    *         predicate.
4881*e4b17023SJohn Marino    *  @ingroup non_mutating_algorithms
4882*e4b17023SJohn Marino    *  @param  __first        A forward iterator.
4883*e4b17023SJohn Marino    *  @param  __last         A forward iterator.
4884*e4b17023SJohn Marino    *  @param  __count        The number of consecutive values.
4885*e4b17023SJohn Marino    *  @param  __val          The value to find.
4886*e4b17023SJohn Marino    *  @param  __binary_pred  A binary predicate.
4887*e4b17023SJohn Marino    *  @return The first iterator @c i in the range @p
4888*e4b17023SJohn Marino    *  [__first,__last-__count) such that @p
4889*e4b17023SJohn Marino    *  __binary_pred(*(i+N),__val) is true for each @c N in the range
4890*e4b17023SJohn Marino    *  @p [0,__count), or @p __last if no such iterator exists.
4891*e4b17023SJohn Marino    *
4892*e4b17023SJohn Marino    *  Searches the range @p [__first,__last) for @p __count
4893*e4b17023SJohn Marino    *  consecutive elements for which the predicate returns true.
4894*e4b17023SJohn Marino   */
4895*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Integer, typename _Tp,
4896*e4b17023SJohn Marino            typename _BinaryPredicate>
4897*e4b17023SJohn Marino     _ForwardIterator
4898*e4b17023SJohn Marino     search_n(_ForwardIterator __first, _ForwardIterator __last,
4899*e4b17023SJohn Marino 	     _Integer __count, const _Tp& __val,
4900*e4b17023SJohn Marino 	     _BinaryPredicate __binary_pred)
4901*e4b17023SJohn Marino     {
4902*e4b17023SJohn Marino       // concept requirements
4903*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4904*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
4905*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
4906*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4907*e4b17023SJohn Marino 
4908*e4b17023SJohn Marino       if (__count <= 0)
4909*e4b17023SJohn Marino 	return __first;
4910*e4b17023SJohn Marino       if (__count == 1)
4911*e4b17023SJohn Marino 	{
4912*e4b17023SJohn Marino 	  while (__first != __last && !bool(__binary_pred(*__first, __val)))
4913*e4b17023SJohn Marino 	    ++__first;
4914*e4b17023SJohn Marino 	  return __first;
4915*e4b17023SJohn Marino 	}
4916*e4b17023SJohn Marino       return std::__search_n(__first, __last, __count, __val, __binary_pred,
4917*e4b17023SJohn Marino 			     std::__iterator_category(__first));
4918*e4b17023SJohn Marino     }
4919*e4b17023SJohn Marino 
4920*e4b17023SJohn Marino 
4921*e4b17023SJohn Marino   /**
4922*e4b17023SJohn Marino    *  @brief Perform an operation on a sequence.
4923*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
4924*e4b17023SJohn Marino    *  @param  __first     An input iterator.
4925*e4b17023SJohn Marino    *  @param  __last      An input iterator.
4926*e4b17023SJohn Marino    *  @param  __result    An output iterator.
4927*e4b17023SJohn Marino    *  @param  __unary_op  A unary operator.
4928*e4b17023SJohn Marino    *  @return   An output iterator equal to @p __result+(__last-__first).
4929*e4b17023SJohn Marino    *
4930*e4b17023SJohn Marino    *  Applies the operator to each element in the input range and assigns
4931*e4b17023SJohn Marino    *  the results to successive elements of the output sequence.
4932*e4b17023SJohn Marino    *  Evaluates @p *(__result+N)=unary_op(*(__first+N)) for each @c N in the
4933*e4b17023SJohn Marino    *  range @p [0,__last-__first).
4934*e4b17023SJohn Marino    *
4935*e4b17023SJohn Marino    *  @p unary_op must not alter its argument.
4936*e4b17023SJohn Marino   */
4937*e4b17023SJohn Marino   template<typename _InputIterator, typename _OutputIterator,
4938*e4b17023SJohn Marino 	   typename _UnaryOperation>
4939*e4b17023SJohn Marino     _OutputIterator
4940*e4b17023SJohn Marino     transform(_InputIterator __first, _InputIterator __last,
4941*e4b17023SJohn Marino 	      _OutputIterator __result, _UnaryOperation __unary_op)
4942*e4b17023SJohn Marino     {
4943*e4b17023SJohn Marino       // concept requirements
4944*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4945*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
4946*e4b17023SJohn Marino             // "the type returned by a _UnaryOperation"
4947*e4b17023SJohn Marino             __typeof__(__unary_op(*__first))>)
4948*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
4949*e4b17023SJohn Marino 
4950*e4b17023SJohn Marino       for (; __first != __last; ++__first, ++__result)
4951*e4b17023SJohn Marino 	*__result = __unary_op(*__first);
4952*e4b17023SJohn Marino       return __result;
4953*e4b17023SJohn Marino     }
4954*e4b17023SJohn Marino 
4955*e4b17023SJohn Marino   /**
4956*e4b17023SJohn Marino    *  @brief Perform an operation on corresponding elements of two sequences.
4957*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
4958*e4b17023SJohn Marino    *  @param  __first1     An input iterator.
4959*e4b17023SJohn Marino    *  @param  __last1      An input iterator.
4960*e4b17023SJohn Marino    *  @param  __first2     An input iterator.
4961*e4b17023SJohn Marino    *  @param  __result     An output iterator.
4962*e4b17023SJohn Marino    *  @param  __binary_op  A binary operator.
4963*e4b17023SJohn Marino    *  @return   An output iterator equal to @p result+(last-first).
4964*e4b17023SJohn Marino    *
4965*e4b17023SJohn Marino    *  Applies the operator to the corresponding elements in the two
4966*e4b17023SJohn Marino    *  input ranges and assigns the results to successive elements of the
4967*e4b17023SJohn Marino    *  output sequence.
4968*e4b17023SJohn Marino    *  Evaluates @p
4969*e4b17023SJohn Marino    *  *(__result+N)=__binary_op(*(__first1+N),*(__first2+N)) for each
4970*e4b17023SJohn Marino    *  @c N in the range @p [0,__last1-__first1).
4971*e4b17023SJohn Marino    *
4972*e4b17023SJohn Marino    *  @p binary_op must not alter either of its arguments.
4973*e4b17023SJohn Marino   */
4974*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
4975*e4b17023SJohn Marino 	   typename _OutputIterator, typename _BinaryOperation>
4976*e4b17023SJohn Marino     _OutputIterator
4977*e4b17023SJohn Marino     transform(_InputIterator1 __first1, _InputIterator1 __last1,
4978*e4b17023SJohn Marino 	      _InputIterator2 __first2, _OutputIterator __result,
4979*e4b17023SJohn Marino 	      _BinaryOperation __binary_op)
4980*e4b17023SJohn Marino     {
4981*e4b17023SJohn Marino       // concept requirements
4982*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
4983*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
4984*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
4985*e4b17023SJohn Marino             // "the type returned by a _BinaryOperation"
4986*e4b17023SJohn Marino             __typeof__(__binary_op(*__first1,*__first2))>)
4987*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first1, __last1);
4988*e4b17023SJohn Marino 
4989*e4b17023SJohn Marino       for (; __first1 != __last1; ++__first1, ++__first2, ++__result)
4990*e4b17023SJohn Marino 	*__result = __binary_op(*__first1, *__first2);
4991*e4b17023SJohn Marino       return __result;
4992*e4b17023SJohn Marino     }
4993*e4b17023SJohn Marino 
4994*e4b17023SJohn Marino   /**
4995*e4b17023SJohn Marino    *  @brief Replace each occurrence of one value in a sequence with another
4996*e4b17023SJohn Marino    *         value.
4997*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
4998*e4b17023SJohn Marino    *  @param  __first      A forward iterator.
4999*e4b17023SJohn Marino    *  @param  __last       A forward iterator.
5000*e4b17023SJohn Marino    *  @param  __old_value  The value to be replaced.
5001*e4b17023SJohn Marino    *  @param  __new_value  The replacement value.
5002*e4b17023SJohn Marino    *  @return   replace() returns no value.
5003*e4b17023SJohn Marino    *
5004*e4b17023SJohn Marino    *  For each iterator @c i in the range @p [__first,__last) if @c *i ==
5005*e4b17023SJohn Marino    *  @p __old_value then the assignment @c *i = @p __new_value is performed.
5006*e4b17023SJohn Marino   */
5007*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Tp>
5008*e4b17023SJohn Marino     void
5009*e4b17023SJohn Marino     replace(_ForwardIterator __first, _ForwardIterator __last,
5010*e4b17023SJohn Marino 	    const _Tp& __old_value, const _Tp& __new_value)
5011*e4b17023SJohn Marino     {
5012*e4b17023SJohn Marino       // concept requirements
5013*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
5014*e4b17023SJohn Marino 				  _ForwardIterator>)
5015*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualOpConcept<
5016*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
5017*e4b17023SJohn Marino       __glibcxx_function_requires(_ConvertibleConcept<_Tp,
5018*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
5019*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5020*e4b17023SJohn Marino 
5021*e4b17023SJohn Marino       for (; __first != __last; ++__first)
5022*e4b17023SJohn Marino 	if (*__first == __old_value)
5023*e4b17023SJohn Marino 	  *__first = __new_value;
5024*e4b17023SJohn Marino     }
5025*e4b17023SJohn Marino 
5026*e4b17023SJohn Marino   /**
5027*e4b17023SJohn Marino    *  @brief Replace each value in a sequence for which a predicate returns
5028*e4b17023SJohn Marino    *         true with another value.
5029*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
5030*e4b17023SJohn Marino    *  @param  __first      A forward iterator.
5031*e4b17023SJohn Marino    *  @param  __last       A forward iterator.
5032*e4b17023SJohn Marino    *  @param  __pred       A predicate.
5033*e4b17023SJohn Marino    *  @param  __new_value  The replacement value.
5034*e4b17023SJohn Marino    *  @return   replace_if() returns no value.
5035*e4b17023SJohn Marino    *
5036*e4b17023SJohn Marino    *  For each iterator @c i in the range @p [__first,__last) if @p __pred(*i)
5037*e4b17023SJohn Marino    *  is true then the assignment @c *i = @p __new_value is performed.
5038*e4b17023SJohn Marino   */
5039*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Predicate, typename _Tp>
5040*e4b17023SJohn Marino     void
5041*e4b17023SJohn Marino     replace_if(_ForwardIterator __first, _ForwardIterator __last,
5042*e4b17023SJohn Marino 	       _Predicate __pred, const _Tp& __new_value)
5043*e4b17023SJohn Marino     {
5044*e4b17023SJohn Marino       // concept requirements
5045*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
5046*e4b17023SJohn Marino 				  _ForwardIterator>)
5047*e4b17023SJohn Marino       __glibcxx_function_requires(_ConvertibleConcept<_Tp,
5048*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
5049*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
5050*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
5051*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5052*e4b17023SJohn Marino 
5053*e4b17023SJohn Marino       for (; __first != __last; ++__first)
5054*e4b17023SJohn Marino 	if (__pred(*__first))
5055*e4b17023SJohn Marino 	  *__first = __new_value;
5056*e4b17023SJohn Marino     }
5057*e4b17023SJohn Marino 
5058*e4b17023SJohn Marino   /**
5059*e4b17023SJohn Marino    *  @brief Assign the result of a function object to each value in a
5060*e4b17023SJohn Marino    *         sequence.
5061*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
5062*e4b17023SJohn Marino    *  @param  __first  A forward iterator.
5063*e4b17023SJohn Marino    *  @param  __last   A forward iterator.
5064*e4b17023SJohn Marino    *  @param  __gen    A function object taking no arguments and returning
5065*e4b17023SJohn Marino    *                 std::iterator_traits<_ForwardIterator>::value_type
5066*e4b17023SJohn Marino    *  @return   generate() returns no value.
5067*e4b17023SJohn Marino    *
5068*e4b17023SJohn Marino    *  Performs the assignment @c *i = @p __gen() for each @c i in the range
5069*e4b17023SJohn Marino    *  @p [__first,__last).
5070*e4b17023SJohn Marino   */
5071*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Generator>
5072*e4b17023SJohn Marino     void
5073*e4b17023SJohn Marino     generate(_ForwardIterator __first, _ForwardIterator __last,
5074*e4b17023SJohn Marino 	     _Generator __gen)
5075*e4b17023SJohn Marino     {
5076*e4b17023SJohn Marino       // concept requirements
5077*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
5078*e4b17023SJohn Marino       __glibcxx_function_requires(_GeneratorConcept<_Generator,
5079*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
5080*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5081*e4b17023SJohn Marino 
5082*e4b17023SJohn Marino       for (; __first != __last; ++__first)
5083*e4b17023SJohn Marino 	*__first = __gen();
5084*e4b17023SJohn Marino     }
5085*e4b17023SJohn Marino 
5086*e4b17023SJohn Marino   /**
5087*e4b17023SJohn Marino    *  @brief Assign the result of a function object to each value in a
5088*e4b17023SJohn Marino    *         sequence.
5089*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
5090*e4b17023SJohn Marino    *  @param  __first  A forward iterator.
5091*e4b17023SJohn Marino    *  @param  __n      The length of the sequence.
5092*e4b17023SJohn Marino    *  @param  __gen    A function object taking no arguments and returning
5093*e4b17023SJohn Marino    *                 std::iterator_traits<_ForwardIterator>::value_type
5094*e4b17023SJohn Marino    *  @return   The end of the sequence, @p __first+__n
5095*e4b17023SJohn Marino    *
5096*e4b17023SJohn Marino    *  Performs the assignment @c *i = @p __gen() for each @c i in the range
5097*e4b17023SJohn Marino    *  @p [__first,__first+__n).
5098*e4b17023SJohn Marino    *
5099*e4b17023SJohn Marino    *  _GLIBCXX_RESOLVE_LIB_DEFECTS
5100*e4b17023SJohn Marino    *  DR 865. More algorithms that throw away information
5101*e4b17023SJohn Marino   */
5102*e4b17023SJohn Marino   template<typename _OutputIterator, typename _Size, typename _Generator>
5103*e4b17023SJohn Marino     _OutputIterator
5104*e4b17023SJohn Marino     generate_n(_OutputIterator __first, _Size __n, _Generator __gen)
5105*e4b17023SJohn Marino     {
5106*e4b17023SJohn Marino       // concept requirements
5107*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5108*e4b17023SJohn Marino             // "the type returned by a _Generator"
5109*e4b17023SJohn Marino             __typeof__(__gen())>)
5110*e4b17023SJohn Marino 
5111*e4b17023SJohn Marino       for (__decltype(__n + 0) __niter = __n;
5112*e4b17023SJohn Marino 	   __niter > 0; --__niter, ++__first)
5113*e4b17023SJohn Marino 	*__first = __gen();
5114*e4b17023SJohn Marino       return __first;
5115*e4b17023SJohn Marino     }
5116*e4b17023SJohn Marino 
5117*e4b17023SJohn Marino 
5118*e4b17023SJohn Marino   /**
5119*e4b17023SJohn Marino    *  @brief Copy a sequence, removing consecutive duplicate values.
5120*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
5121*e4b17023SJohn Marino    *  @param  __first   An input iterator.
5122*e4b17023SJohn Marino    *  @param  __last    An input iterator.
5123*e4b17023SJohn Marino    *  @param  __result  An output iterator.
5124*e4b17023SJohn Marino    *  @return   An iterator designating the end of the resulting sequence.
5125*e4b17023SJohn Marino    *
5126*e4b17023SJohn Marino    *  Copies each element in the range @p [__first,__last) to the range
5127*e4b17023SJohn Marino    *  beginning at @p __result, except that only the first element is copied
5128*e4b17023SJohn Marino    *  from groups of consecutive elements that compare equal.
5129*e4b17023SJohn Marino    *  unique_copy() is stable, so the relative order of elements that are
5130*e4b17023SJohn Marino    *  copied is unchanged.
5131*e4b17023SJohn Marino    *
5132*e4b17023SJohn Marino    *  _GLIBCXX_RESOLVE_LIB_DEFECTS
5133*e4b17023SJohn Marino    *  DR 241. Does unique_copy() require CopyConstructible and Assignable?
5134*e4b17023SJohn Marino    *
5135*e4b17023SJohn Marino    *  _GLIBCXX_RESOLVE_LIB_DEFECTS
5136*e4b17023SJohn Marino    *  DR 538. 241 again: Does unique_copy() require CopyConstructible and
5137*e4b17023SJohn Marino    *  Assignable?
5138*e4b17023SJohn Marino   */
5139*e4b17023SJohn Marino   template<typename _InputIterator, typename _OutputIterator>
5140*e4b17023SJohn Marino     inline _OutputIterator
5141*e4b17023SJohn Marino     unique_copy(_InputIterator __first, _InputIterator __last,
5142*e4b17023SJohn Marino 		_OutputIterator __result)
5143*e4b17023SJohn Marino     {
5144*e4b17023SJohn Marino       // concept requirements
5145*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
5146*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5147*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
5148*e4b17023SJohn Marino       __glibcxx_function_requires(_EqualityComparableConcept<
5149*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
5150*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5151*e4b17023SJohn Marino 
5152*e4b17023SJohn Marino       if (__first == __last)
5153*e4b17023SJohn Marino 	return __result;
5154*e4b17023SJohn Marino       return std::__unique_copy(__first, __last, __result,
5155*e4b17023SJohn Marino 				std::__iterator_category(__first),
5156*e4b17023SJohn Marino 				std::__iterator_category(__result));
5157*e4b17023SJohn Marino     }
5158*e4b17023SJohn Marino 
5159*e4b17023SJohn Marino   /**
5160*e4b17023SJohn Marino    *  @brief Copy a sequence, removing consecutive values using a predicate.
5161*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
5162*e4b17023SJohn Marino    *  @param  __first        An input iterator.
5163*e4b17023SJohn Marino    *  @param  __last         An input iterator.
5164*e4b17023SJohn Marino    *  @param  __result       An output iterator.
5165*e4b17023SJohn Marino    *  @param  __binary_pred  A binary predicate.
5166*e4b17023SJohn Marino    *  @return   An iterator designating the end of the resulting sequence.
5167*e4b17023SJohn Marino    *
5168*e4b17023SJohn Marino    *  Copies each element in the range @p [__first,__last) to the range
5169*e4b17023SJohn Marino    *  beginning at @p __result, except that only the first element is copied
5170*e4b17023SJohn Marino    *  from groups of consecutive elements for which @p __binary_pred returns
5171*e4b17023SJohn Marino    *  true.
5172*e4b17023SJohn Marino    *  unique_copy() is stable, so the relative order of elements that are
5173*e4b17023SJohn Marino    *  copied is unchanged.
5174*e4b17023SJohn Marino    *
5175*e4b17023SJohn Marino    *  _GLIBCXX_RESOLVE_LIB_DEFECTS
5176*e4b17023SJohn Marino    *  DR 241. Does unique_copy() require CopyConstructible and Assignable?
5177*e4b17023SJohn Marino   */
5178*e4b17023SJohn Marino   template<typename _InputIterator, typename _OutputIterator,
5179*e4b17023SJohn Marino 	   typename _BinaryPredicate>
5180*e4b17023SJohn Marino     inline _OutputIterator
5181*e4b17023SJohn Marino     unique_copy(_InputIterator __first, _InputIterator __last,
5182*e4b17023SJohn Marino 		_OutputIterator __result,
5183*e4b17023SJohn Marino 		_BinaryPredicate __binary_pred)
5184*e4b17023SJohn Marino     {
5185*e4b17023SJohn Marino       // concept requirements -- predicates checked later
5186*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
5187*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5188*e4b17023SJohn Marino 	    typename iterator_traits<_InputIterator>::value_type>)
5189*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5190*e4b17023SJohn Marino 
5191*e4b17023SJohn Marino       if (__first == __last)
5192*e4b17023SJohn Marino 	return __result;
5193*e4b17023SJohn Marino       return std::__unique_copy(__first, __last, __result, __binary_pred,
5194*e4b17023SJohn Marino 				std::__iterator_category(__first),
5195*e4b17023SJohn Marino 				std::__iterator_category(__result));
5196*e4b17023SJohn Marino     }
5197*e4b17023SJohn Marino 
5198*e4b17023SJohn Marino 
5199*e4b17023SJohn Marino   /**
5200*e4b17023SJohn Marino    *  @brief Randomly shuffle the elements of a sequence.
5201*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
5202*e4b17023SJohn Marino    *  @param  __first   A forward iterator.
5203*e4b17023SJohn Marino    *  @param  __last    A forward iterator.
5204*e4b17023SJohn Marino    *  @return  Nothing.
5205*e4b17023SJohn Marino    *
5206*e4b17023SJohn Marino    *  Reorder the elements in the range @p [__first,__last) using a random
5207*e4b17023SJohn Marino    *  distribution, so that every possible ordering of the sequence is
5208*e4b17023SJohn Marino    *  equally likely.
5209*e4b17023SJohn Marino   */
5210*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
5211*e4b17023SJohn Marino     inline void
5212*e4b17023SJohn Marino     random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
5213*e4b17023SJohn Marino     {
5214*e4b17023SJohn Marino       // concept requirements
5215*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5216*e4b17023SJohn Marino 	    _RandomAccessIterator>)
5217*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5218*e4b17023SJohn Marino 
5219*e4b17023SJohn Marino       if (__first != __last)
5220*e4b17023SJohn Marino 	for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
5221*e4b17023SJohn Marino 	  std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1)));
5222*e4b17023SJohn Marino     }
5223*e4b17023SJohn Marino 
5224*e4b17023SJohn Marino   /**
5225*e4b17023SJohn Marino    *  @brief Shuffle the elements of a sequence using a random number
5226*e4b17023SJohn Marino    *         generator.
5227*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
5228*e4b17023SJohn Marino    *  @param  __first   A forward iterator.
5229*e4b17023SJohn Marino    *  @param  __last    A forward iterator.
5230*e4b17023SJohn Marino    *  @param  __rand    The RNG functor or function.
5231*e4b17023SJohn Marino    *  @return  Nothing.
5232*e4b17023SJohn Marino    *
5233*e4b17023SJohn Marino    *  Reorders the elements in the range @p [__first,__last) using @p __rand to
5234*e4b17023SJohn Marino    *  provide a random distribution. Calling @p __rand(N) for a positive
5235*e4b17023SJohn Marino    *  integer @p N should return a randomly chosen integer from the
5236*e4b17023SJohn Marino    *  range [0,N).
5237*e4b17023SJohn Marino   */
5238*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _RandomNumberGenerator>
5239*e4b17023SJohn Marino     void
5240*e4b17023SJohn Marino     random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
5241*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
5242*e4b17023SJohn Marino 		   _RandomNumberGenerator&& __rand)
5243*e4b17023SJohn Marino #else
5244*e4b17023SJohn Marino 		   _RandomNumberGenerator& __rand)
5245*e4b17023SJohn Marino #endif
5246*e4b17023SJohn Marino     {
5247*e4b17023SJohn Marino       // concept requirements
5248*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5249*e4b17023SJohn Marino 	    _RandomAccessIterator>)
5250*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5251*e4b17023SJohn Marino 
5252*e4b17023SJohn Marino       if (__first == __last)
5253*e4b17023SJohn Marino 	return;
5254*e4b17023SJohn Marino       for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
5255*e4b17023SJohn Marino 	std::iter_swap(__i, __first + __rand((__i - __first) + 1));
5256*e4b17023SJohn Marino     }
5257*e4b17023SJohn Marino 
5258*e4b17023SJohn Marino 
5259*e4b17023SJohn Marino   /**
5260*e4b17023SJohn Marino    *  @brief Move elements for which a predicate is true to the beginning
5261*e4b17023SJohn Marino    *         of a sequence.
5262*e4b17023SJohn Marino    *  @ingroup mutating_algorithms
5263*e4b17023SJohn Marino    *  @param  __first   A forward iterator.
5264*e4b17023SJohn Marino    *  @param  __last    A forward iterator.
5265*e4b17023SJohn Marino    *  @param  __pred    A predicate functor.
5266*e4b17023SJohn Marino    *  @return  An iterator @p middle such that @p __pred(i) is true for each
5267*e4b17023SJohn Marino    *  iterator @p i in the range @p [__first,middle) and false for each @p i
5268*e4b17023SJohn Marino    *  in the range @p [middle,__last).
5269*e4b17023SJohn Marino    *
5270*e4b17023SJohn Marino    *  @p __pred must not modify its operand. @p partition() does not preserve
5271*e4b17023SJohn Marino    *  the relative ordering of elements in each group, use
5272*e4b17023SJohn Marino    *  @p stable_partition() if this is needed.
5273*e4b17023SJohn Marino   */
5274*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Predicate>
5275*e4b17023SJohn Marino     inline _ForwardIterator
5276*e4b17023SJohn Marino     partition(_ForwardIterator __first, _ForwardIterator __last,
5277*e4b17023SJohn Marino 	      _Predicate   __pred)
5278*e4b17023SJohn Marino     {
5279*e4b17023SJohn Marino       // concept requirements
5280*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
5281*e4b17023SJohn Marino 				  _ForwardIterator>)
5282*e4b17023SJohn Marino       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
5283*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
5284*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5285*e4b17023SJohn Marino 
5286*e4b17023SJohn Marino       return std::__partition(__first, __last, __pred,
5287*e4b17023SJohn Marino 			      std::__iterator_category(__first));
5288*e4b17023SJohn Marino     }
5289*e4b17023SJohn Marino 
5290*e4b17023SJohn Marino 
5291*e4b17023SJohn Marino 
5292*e4b17023SJohn Marino   /**
5293*e4b17023SJohn Marino    *  @brief Sort the smallest elements of a sequence.
5294*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
5295*e4b17023SJohn Marino    *  @param  __first   An iterator.
5296*e4b17023SJohn Marino    *  @param  __middle  Another iterator.
5297*e4b17023SJohn Marino    *  @param  __last    Another iterator.
5298*e4b17023SJohn Marino    *  @return  Nothing.
5299*e4b17023SJohn Marino    *
5300*e4b17023SJohn Marino    *  Sorts the smallest @p (__middle-__first) elements in the range
5301*e4b17023SJohn Marino    *  @p [first,last) and moves them to the range @p [__first,__middle). The
5302*e4b17023SJohn Marino    *  order of the remaining elements in the range @p [__middle,__last) is
5303*e4b17023SJohn Marino    *  undefined.
5304*e4b17023SJohn Marino    *  After the sort if @e i and @e j are iterators in the range
5305*e4b17023SJohn Marino    *  @p [__first,__middle) such that i precedes j and @e k is an iterator in
5306*e4b17023SJohn Marino    *  the range @p [__middle,__last) then *j<*i and *k<*i are both false.
5307*e4b17023SJohn Marino   */
5308*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
5309*e4b17023SJohn Marino     inline void
5310*e4b17023SJohn Marino     partial_sort(_RandomAccessIterator __first,
5311*e4b17023SJohn Marino 		 _RandomAccessIterator __middle,
5312*e4b17023SJohn Marino 		 _RandomAccessIterator __last)
5313*e4b17023SJohn Marino     {
5314*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
5315*e4b17023SJohn Marino 	_ValueType;
5316*e4b17023SJohn Marino 
5317*e4b17023SJohn Marino       // concept requirements
5318*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5319*e4b17023SJohn Marino 	    _RandomAccessIterator>)
5320*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
5321*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __middle);
5322*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__middle, __last);
5323*e4b17023SJohn Marino 
5324*e4b17023SJohn Marino       std::__heap_select(__first, __middle, __last);
5325*e4b17023SJohn Marino       std::sort_heap(__first, __middle);
5326*e4b17023SJohn Marino     }
5327*e4b17023SJohn Marino 
5328*e4b17023SJohn Marino   /**
5329*e4b17023SJohn Marino    *  @brief Sort the smallest elements of a sequence using a predicate
5330*e4b17023SJohn Marino    *         for comparison.
5331*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
5332*e4b17023SJohn Marino    *  @param  __first   An iterator.
5333*e4b17023SJohn Marino    *  @param  __middle  Another iterator.
5334*e4b17023SJohn Marino    *  @param  __last    Another iterator.
5335*e4b17023SJohn Marino    *  @param  __comp    A comparison functor.
5336*e4b17023SJohn Marino    *  @return  Nothing.
5337*e4b17023SJohn Marino    *
5338*e4b17023SJohn Marino    *  Sorts the smallest @p (__middle-__first) elements in the range
5339*e4b17023SJohn Marino    *  @p [__first,__last) and moves them to the range @p [__first,__middle). The
5340*e4b17023SJohn Marino    *  order of the remaining elements in the range @p [__middle,__last) is
5341*e4b17023SJohn Marino    *  undefined.
5342*e4b17023SJohn Marino    *  After the sort if @e i and @e j are iterators in the range
5343*e4b17023SJohn Marino    *  @p [__first,__middle) such that i precedes j and @e k is an iterator in
5344*e4b17023SJohn Marino    *  the range @p [__middle,__last) then @p *__comp(j,*i) and @p __comp(*k,*i)
5345*e4b17023SJohn Marino    *  are both false.
5346*e4b17023SJohn Marino   */
5347*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Compare>
5348*e4b17023SJohn Marino     inline void
5349*e4b17023SJohn Marino     partial_sort(_RandomAccessIterator __first,
5350*e4b17023SJohn Marino 		 _RandomAccessIterator __middle,
5351*e4b17023SJohn Marino 		 _RandomAccessIterator __last,
5352*e4b17023SJohn Marino 		 _Compare __comp)
5353*e4b17023SJohn Marino     {
5354*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
5355*e4b17023SJohn Marino 	_ValueType;
5356*e4b17023SJohn Marino 
5357*e4b17023SJohn Marino       // concept requirements
5358*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5359*e4b17023SJohn Marino 	    _RandomAccessIterator>)
5360*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5361*e4b17023SJohn Marino 				  _ValueType, _ValueType>)
5362*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __middle);
5363*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__middle, __last);
5364*e4b17023SJohn Marino 
5365*e4b17023SJohn Marino       std::__heap_select(__first, __middle, __last, __comp);
5366*e4b17023SJohn Marino       std::sort_heap(__first, __middle, __comp);
5367*e4b17023SJohn Marino     }
5368*e4b17023SJohn Marino 
5369*e4b17023SJohn Marino   /**
5370*e4b17023SJohn Marino    *  @brief Sort a sequence just enough to find a particular position.
5371*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
5372*e4b17023SJohn Marino    *  @param  __first   An iterator.
5373*e4b17023SJohn Marino    *  @param  __nth     Another iterator.
5374*e4b17023SJohn Marino    *  @param  __last    Another iterator.
5375*e4b17023SJohn Marino    *  @return  Nothing.
5376*e4b17023SJohn Marino    *
5377*e4b17023SJohn Marino    *  Rearranges the elements in the range @p [__first,__last) so that @p *__nth
5378*e4b17023SJohn Marino    *  is the same element that would have been in that position had the
5379*e4b17023SJohn Marino    *  whole sequence been sorted. The elements either side of @p *__nth are
5380*e4b17023SJohn Marino    *  not completely sorted, but for any iterator @e i in the range
5381*e4b17023SJohn Marino    *  @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it
5382*e4b17023SJohn Marino    *  holds that *j < *i is false.
5383*e4b17023SJohn Marino   */
5384*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
5385*e4b17023SJohn Marino     inline void
5386*e4b17023SJohn Marino     nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth,
5387*e4b17023SJohn Marino 		_RandomAccessIterator __last)
5388*e4b17023SJohn Marino     {
5389*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
5390*e4b17023SJohn Marino 	_ValueType;
5391*e4b17023SJohn Marino 
5392*e4b17023SJohn Marino       // concept requirements
5393*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5394*e4b17023SJohn Marino 				  _RandomAccessIterator>)
5395*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
5396*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __nth);
5397*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__nth, __last);
5398*e4b17023SJohn Marino 
5399*e4b17023SJohn Marino       if (__first == __last || __nth == __last)
5400*e4b17023SJohn Marino 	return;
5401*e4b17023SJohn Marino 
5402*e4b17023SJohn Marino       std::__introselect(__first, __nth, __last,
5403*e4b17023SJohn Marino 			 std::__lg(__last - __first) * 2);
5404*e4b17023SJohn Marino     }
5405*e4b17023SJohn Marino 
5406*e4b17023SJohn Marino   /**
5407*e4b17023SJohn Marino    *  @brief Sort a sequence just enough to find a particular position
5408*e4b17023SJohn Marino    *         using a predicate for comparison.
5409*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
5410*e4b17023SJohn Marino    *  @param  __first   An iterator.
5411*e4b17023SJohn Marino    *  @param  __nth     Another iterator.
5412*e4b17023SJohn Marino    *  @param  __last    Another iterator.
5413*e4b17023SJohn Marino    *  @param  __comp    A comparison functor.
5414*e4b17023SJohn Marino    *  @return  Nothing.
5415*e4b17023SJohn Marino    *
5416*e4b17023SJohn Marino    *  Rearranges the elements in the range @p [__first,__last) so that @p *__nth
5417*e4b17023SJohn Marino    *  is the same element that would have been in that position had the
5418*e4b17023SJohn Marino    *  whole sequence been sorted. The elements either side of @p *__nth are
5419*e4b17023SJohn Marino    *  not completely sorted, but for any iterator @e i in the range
5420*e4b17023SJohn Marino    *  @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it
5421*e4b17023SJohn Marino    *  holds that @p __comp(*j,*i) is false.
5422*e4b17023SJohn Marino   */
5423*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Compare>
5424*e4b17023SJohn Marino     inline void
5425*e4b17023SJohn Marino     nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth,
5426*e4b17023SJohn Marino 		_RandomAccessIterator __last, _Compare __comp)
5427*e4b17023SJohn Marino     {
5428*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
5429*e4b17023SJohn Marino 	_ValueType;
5430*e4b17023SJohn Marino 
5431*e4b17023SJohn Marino       // concept requirements
5432*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5433*e4b17023SJohn Marino 				  _RandomAccessIterator>)
5434*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5435*e4b17023SJohn Marino 				  _ValueType, _ValueType>)
5436*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __nth);
5437*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__nth, __last);
5438*e4b17023SJohn Marino 
5439*e4b17023SJohn Marino       if (__first == __last || __nth == __last)
5440*e4b17023SJohn Marino 	return;
5441*e4b17023SJohn Marino 
5442*e4b17023SJohn Marino       std::__introselect(__first, __nth, __last,
5443*e4b17023SJohn Marino 			 std::__lg(__last - __first) * 2, __comp);
5444*e4b17023SJohn Marino     }
5445*e4b17023SJohn Marino 
5446*e4b17023SJohn Marino 
5447*e4b17023SJohn Marino   /**
5448*e4b17023SJohn Marino    *  @brief Sort the elements of a sequence.
5449*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
5450*e4b17023SJohn Marino    *  @param  __first   An iterator.
5451*e4b17023SJohn Marino    *  @param  __last    Another iterator.
5452*e4b17023SJohn Marino    *  @return  Nothing.
5453*e4b17023SJohn Marino    *
5454*e4b17023SJohn Marino    *  Sorts the elements in the range @p [__first,__last) in ascending order,
5455*e4b17023SJohn Marino    *  such that for each iterator @e i in the range @p [__first,__last-1),
5456*e4b17023SJohn Marino    *  *(i+1)<*i is false.
5457*e4b17023SJohn Marino    *
5458*e4b17023SJohn Marino    *  The relative ordering of equivalent elements is not preserved, use
5459*e4b17023SJohn Marino    *  @p stable_sort() if this is needed.
5460*e4b17023SJohn Marino   */
5461*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
5462*e4b17023SJohn Marino     inline void
5463*e4b17023SJohn Marino     sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
5464*e4b17023SJohn Marino     {
5465*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
5466*e4b17023SJohn Marino 	_ValueType;
5467*e4b17023SJohn Marino 
5468*e4b17023SJohn Marino       // concept requirements
5469*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5470*e4b17023SJohn Marino 	    _RandomAccessIterator>)
5471*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
5472*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5473*e4b17023SJohn Marino 
5474*e4b17023SJohn Marino       if (__first != __last)
5475*e4b17023SJohn Marino 	{
5476*e4b17023SJohn Marino 	  std::__introsort_loop(__first, __last,
5477*e4b17023SJohn Marino 				std::__lg(__last - __first) * 2);
5478*e4b17023SJohn Marino 	  std::__final_insertion_sort(__first, __last);
5479*e4b17023SJohn Marino 	}
5480*e4b17023SJohn Marino     }
5481*e4b17023SJohn Marino 
5482*e4b17023SJohn Marino   /**
5483*e4b17023SJohn Marino    *  @brief Sort the elements of a sequence using a predicate for comparison.
5484*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
5485*e4b17023SJohn Marino    *  @param  __first   An iterator.
5486*e4b17023SJohn Marino    *  @param  __last    Another iterator.
5487*e4b17023SJohn Marino    *  @param  __comp    A comparison functor.
5488*e4b17023SJohn Marino    *  @return  Nothing.
5489*e4b17023SJohn Marino    *
5490*e4b17023SJohn Marino    *  Sorts the elements in the range @p [__first,__last) in ascending order,
5491*e4b17023SJohn Marino    *  such that @p __comp(*(i+1),*i) is false for every iterator @e i in the
5492*e4b17023SJohn Marino    *  range @p [__first,__last-1).
5493*e4b17023SJohn Marino    *
5494*e4b17023SJohn Marino    *  The relative ordering of equivalent elements is not preserved, use
5495*e4b17023SJohn Marino    *  @p stable_sort() if this is needed.
5496*e4b17023SJohn Marino   */
5497*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Compare>
5498*e4b17023SJohn Marino     inline void
5499*e4b17023SJohn Marino     sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
5500*e4b17023SJohn Marino 	 _Compare __comp)
5501*e4b17023SJohn Marino     {
5502*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
5503*e4b17023SJohn Marino 	_ValueType;
5504*e4b17023SJohn Marino 
5505*e4b17023SJohn Marino       // concept requirements
5506*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5507*e4b17023SJohn Marino 	    _RandomAccessIterator>)
5508*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType,
5509*e4b17023SJohn Marino 				  _ValueType>)
5510*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5511*e4b17023SJohn Marino 
5512*e4b17023SJohn Marino       if (__first != __last)
5513*e4b17023SJohn Marino 	{
5514*e4b17023SJohn Marino 	  std::__introsort_loop(__first, __last,
5515*e4b17023SJohn Marino 				std::__lg(__last - __first) * 2, __comp);
5516*e4b17023SJohn Marino 	  std::__final_insertion_sort(__first, __last, __comp);
5517*e4b17023SJohn Marino 	}
5518*e4b17023SJohn Marino     }
5519*e4b17023SJohn Marino 
5520*e4b17023SJohn Marino   /**
5521*e4b17023SJohn Marino    *  @brief Merges two sorted ranges.
5522*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
5523*e4b17023SJohn Marino    *  @param  __first1  An iterator.
5524*e4b17023SJohn Marino    *  @param  __first2  Another iterator.
5525*e4b17023SJohn Marino    *  @param  __last1   Another iterator.
5526*e4b17023SJohn Marino    *  @param  __last2   Another iterator.
5527*e4b17023SJohn Marino    *  @param  __result  An iterator pointing to the end of the merged range.
5528*e4b17023SJohn Marino    *  @return         An iterator pointing to the first element <em>not less
5529*e4b17023SJohn Marino    *                  than</em> @e val.
5530*e4b17023SJohn Marino    *
5531*e4b17023SJohn Marino    *  Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into
5532*e4b17023SJohn Marino    *  the sorted range @p [__result, __result + (__last1-__first1) +
5533*e4b17023SJohn Marino    *  (__last2-__first2)).  Both input ranges must be sorted, and the
5534*e4b17023SJohn Marino    *  output range must not overlap with either of the input ranges.
5535*e4b17023SJohn Marino    *  The sort is @e stable, that is, for equivalent elements in the
5536*e4b17023SJohn Marino    *  two ranges, elements from the first range will always come
5537*e4b17023SJohn Marino    *  before elements from the second.
5538*e4b17023SJohn Marino   */
5539*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
5540*e4b17023SJohn Marino 	   typename _OutputIterator>
5541*e4b17023SJohn Marino     _OutputIterator
5542*e4b17023SJohn Marino     merge(_InputIterator1 __first1, _InputIterator1 __last1,
5543*e4b17023SJohn Marino 	  _InputIterator2 __first2, _InputIterator2 __last2,
5544*e4b17023SJohn Marino 	  _OutputIterator __result)
5545*e4b17023SJohn Marino     {
5546*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
5547*e4b17023SJohn Marino 	_ValueType1;
5548*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
5549*e4b17023SJohn Marino 	_ValueType2;
5550*e4b17023SJohn Marino 
5551*e4b17023SJohn Marino       // concept requirements
5552*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5553*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5554*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5555*e4b17023SJohn Marino 				  _ValueType1>)
5556*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5557*e4b17023SJohn Marino 				  _ValueType2>)
5558*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
5559*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first1, __last1, __first2);
5560*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first2, __last2, __first1);
5561*e4b17023SJohn Marino 
5562*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
5563*e4b17023SJohn Marino 	{
5564*e4b17023SJohn Marino 	  if (*__first2 < *__first1)
5565*e4b17023SJohn Marino 	    {
5566*e4b17023SJohn Marino 	      *__result = *__first2;
5567*e4b17023SJohn Marino 	      ++__first2;
5568*e4b17023SJohn Marino 	    }
5569*e4b17023SJohn Marino 	  else
5570*e4b17023SJohn Marino 	    {
5571*e4b17023SJohn Marino 	      *__result = *__first1;
5572*e4b17023SJohn Marino 	      ++__first1;
5573*e4b17023SJohn Marino 	    }
5574*e4b17023SJohn Marino 	  ++__result;
5575*e4b17023SJohn Marino 	}
5576*e4b17023SJohn Marino       return std::copy(__first2, __last2, std::copy(__first1, __last1,
5577*e4b17023SJohn Marino 						    __result));
5578*e4b17023SJohn Marino     }
5579*e4b17023SJohn Marino 
5580*e4b17023SJohn Marino   /**
5581*e4b17023SJohn Marino    *  @brief Merges two sorted ranges.
5582*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
5583*e4b17023SJohn Marino    *  @param  __first1  An iterator.
5584*e4b17023SJohn Marino    *  @param  __first2  Another iterator.
5585*e4b17023SJohn Marino    *  @param  __last1   Another iterator.
5586*e4b17023SJohn Marino    *  @param  __last2   Another iterator.
5587*e4b17023SJohn Marino    *  @param  __result  An iterator pointing to the end of the merged range.
5588*e4b17023SJohn Marino    *  @param  __comp    A functor to use for comparisons.
5589*e4b17023SJohn Marino    *  @return         An iterator pointing to the first element "not less
5590*e4b17023SJohn Marino    *                  than" @e val.
5591*e4b17023SJohn Marino    *
5592*e4b17023SJohn Marino    *  Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into
5593*e4b17023SJohn Marino    *  the sorted range @p [__result, __result + (__last1-__first1) +
5594*e4b17023SJohn Marino    *  (__last2-__first2)).  Both input ranges must be sorted, and the
5595*e4b17023SJohn Marino    *  output range must not overlap with either of the input ranges.
5596*e4b17023SJohn Marino    *  The sort is @e stable, that is, for equivalent elements in the
5597*e4b17023SJohn Marino    *  two ranges, elements from the first range will always come
5598*e4b17023SJohn Marino    *  before elements from the second.
5599*e4b17023SJohn Marino    *
5600*e4b17023SJohn Marino    *  The comparison function should have the same effects on ordering as
5601*e4b17023SJohn Marino    *  the function used for the initial sort.
5602*e4b17023SJohn Marino   */
5603*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
5604*e4b17023SJohn Marino 	   typename _OutputIterator, typename _Compare>
5605*e4b17023SJohn Marino     _OutputIterator
5606*e4b17023SJohn Marino     merge(_InputIterator1 __first1, _InputIterator1 __last1,
5607*e4b17023SJohn Marino 	  _InputIterator2 __first2, _InputIterator2 __last2,
5608*e4b17023SJohn Marino 	  _OutputIterator __result, _Compare __comp)
5609*e4b17023SJohn Marino     {
5610*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
5611*e4b17023SJohn Marino 	_ValueType1;
5612*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
5613*e4b17023SJohn Marino 	_ValueType2;
5614*e4b17023SJohn Marino 
5615*e4b17023SJohn Marino       // concept requirements
5616*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5617*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5618*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5619*e4b17023SJohn Marino 				  _ValueType1>)
5620*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5621*e4b17023SJohn Marino 				  _ValueType2>)
5622*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5623*e4b17023SJohn Marino 				  _ValueType2, _ValueType1>)
5624*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
5625*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
5626*e4b17023SJohn Marino 
5627*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
5628*e4b17023SJohn Marino 	{
5629*e4b17023SJohn Marino 	  if (__comp(*__first2, *__first1))
5630*e4b17023SJohn Marino 	    {
5631*e4b17023SJohn Marino 	      *__result = *__first2;
5632*e4b17023SJohn Marino 	      ++__first2;
5633*e4b17023SJohn Marino 	    }
5634*e4b17023SJohn Marino 	  else
5635*e4b17023SJohn Marino 	    {
5636*e4b17023SJohn Marino 	      *__result = *__first1;
5637*e4b17023SJohn Marino 	      ++__first1;
5638*e4b17023SJohn Marino 	    }
5639*e4b17023SJohn Marino 	  ++__result;
5640*e4b17023SJohn Marino 	}
5641*e4b17023SJohn Marino       return std::copy(__first2, __last2, std::copy(__first1, __last1,
5642*e4b17023SJohn Marino 						    __result));
5643*e4b17023SJohn Marino     }
5644*e4b17023SJohn Marino 
5645*e4b17023SJohn Marino 
5646*e4b17023SJohn Marino   /**
5647*e4b17023SJohn Marino    *  @brief Sort the elements of a sequence, preserving the relative order
5648*e4b17023SJohn Marino    *         of equivalent elements.
5649*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
5650*e4b17023SJohn Marino    *  @param  __first   An iterator.
5651*e4b17023SJohn Marino    *  @param  __last    Another iterator.
5652*e4b17023SJohn Marino    *  @return  Nothing.
5653*e4b17023SJohn Marino    *
5654*e4b17023SJohn Marino    *  Sorts the elements in the range @p [__first,__last) in ascending order,
5655*e4b17023SJohn Marino    *  such that for each iterator @p i in the range @p [__first,__last-1),
5656*e4b17023SJohn Marino    *  @p *(i+1)<*i is false.
5657*e4b17023SJohn Marino    *
5658*e4b17023SJohn Marino    *  The relative ordering of equivalent elements is preserved, so any two
5659*e4b17023SJohn Marino    *  elements @p x and @p y in the range @p [__first,__last) such that
5660*e4b17023SJohn Marino    *  @p x<y is false and @p y<x is false will have the same relative
5661*e4b17023SJohn Marino    *  ordering after calling @p stable_sort().
5662*e4b17023SJohn Marino   */
5663*e4b17023SJohn Marino   template<typename _RandomAccessIterator>
5664*e4b17023SJohn Marino     inline void
5665*e4b17023SJohn Marino     stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
5666*e4b17023SJohn Marino     {
5667*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
5668*e4b17023SJohn Marino 	_ValueType;
5669*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
5670*e4b17023SJohn Marino 	_DistanceType;
5671*e4b17023SJohn Marino 
5672*e4b17023SJohn Marino       // concept requirements
5673*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5674*e4b17023SJohn Marino 	    _RandomAccessIterator>)
5675*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
5676*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5677*e4b17023SJohn Marino 
5678*e4b17023SJohn Marino       _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first,
5679*e4b17023SJohn Marino 								 __last);
5680*e4b17023SJohn Marino       if (__buf.begin() == 0)
5681*e4b17023SJohn Marino 	std::__inplace_stable_sort(__first, __last);
5682*e4b17023SJohn Marino       else
5683*e4b17023SJohn Marino 	std::__stable_sort_adaptive(__first, __last, __buf.begin(),
5684*e4b17023SJohn Marino 				    _DistanceType(__buf.size()));
5685*e4b17023SJohn Marino     }
5686*e4b17023SJohn Marino 
5687*e4b17023SJohn Marino   /**
5688*e4b17023SJohn Marino    *  @brief Sort the elements of a sequence using a predicate for comparison,
5689*e4b17023SJohn Marino    *         preserving the relative order of equivalent elements.
5690*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
5691*e4b17023SJohn Marino    *  @param  __first   An iterator.
5692*e4b17023SJohn Marino    *  @param  __last    Another iterator.
5693*e4b17023SJohn Marino    *  @param  __comp    A comparison functor.
5694*e4b17023SJohn Marino    *  @return  Nothing.
5695*e4b17023SJohn Marino    *
5696*e4b17023SJohn Marino    *  Sorts the elements in the range @p [__first,__last) in ascending order,
5697*e4b17023SJohn Marino    *  such that for each iterator @p i in the range @p [__first,__last-1),
5698*e4b17023SJohn Marino    *  @p __comp(*(i+1),*i) is false.
5699*e4b17023SJohn Marino    *
5700*e4b17023SJohn Marino    *  The relative ordering of equivalent elements is preserved, so any two
5701*e4b17023SJohn Marino    *  elements @p x and @p y in the range @p [__first,__last) such that
5702*e4b17023SJohn Marino    *  @p __comp(x,y) is false and @p __comp(y,x) is false will have the same
5703*e4b17023SJohn Marino    *  relative ordering after calling @p stable_sort().
5704*e4b17023SJohn Marino   */
5705*e4b17023SJohn Marino   template<typename _RandomAccessIterator, typename _Compare>
5706*e4b17023SJohn Marino     inline void
5707*e4b17023SJohn Marino     stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
5708*e4b17023SJohn Marino 		_Compare __comp)
5709*e4b17023SJohn Marino     {
5710*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::value_type
5711*e4b17023SJohn Marino 	_ValueType;
5712*e4b17023SJohn Marino       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
5713*e4b17023SJohn Marino 	_DistanceType;
5714*e4b17023SJohn Marino 
5715*e4b17023SJohn Marino       // concept requirements
5716*e4b17023SJohn Marino       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5717*e4b17023SJohn Marino 	    _RandomAccessIterator>)
5718*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5719*e4b17023SJohn Marino 				  _ValueType,
5720*e4b17023SJohn Marino 				  _ValueType>)
5721*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
5722*e4b17023SJohn Marino 
5723*e4b17023SJohn Marino       _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first,
5724*e4b17023SJohn Marino 								 __last);
5725*e4b17023SJohn Marino       if (__buf.begin() == 0)
5726*e4b17023SJohn Marino 	std::__inplace_stable_sort(__first, __last, __comp);
5727*e4b17023SJohn Marino       else
5728*e4b17023SJohn Marino 	std::__stable_sort_adaptive(__first, __last, __buf.begin(),
5729*e4b17023SJohn Marino 				    _DistanceType(__buf.size()), __comp);
5730*e4b17023SJohn Marino     }
5731*e4b17023SJohn Marino 
5732*e4b17023SJohn Marino 
5733*e4b17023SJohn Marino   /**
5734*e4b17023SJohn Marino    *  @brief Return the union of two sorted ranges.
5735*e4b17023SJohn Marino    *  @ingroup set_algorithms
5736*e4b17023SJohn Marino    *  @param  __first1  Start of first range.
5737*e4b17023SJohn Marino    *  @param  __last1   End of first range.
5738*e4b17023SJohn Marino    *  @param  __first2  Start of second range.
5739*e4b17023SJohn Marino    *  @param  __last2   End of second range.
5740*e4b17023SJohn Marino    *  @return  End of the output range.
5741*e4b17023SJohn Marino    *  @ingroup set_algorithms
5742*e4b17023SJohn Marino    *
5743*e4b17023SJohn Marino    *  This operation iterates over both ranges, copying elements present in
5744*e4b17023SJohn Marino    *  each range in order to the output range.  Iterators increment for each
5745*e4b17023SJohn Marino    *  range.  When the current element of one range is less than the other,
5746*e4b17023SJohn Marino    *  that element is copied and the iterator advanced.  If an element is
5747*e4b17023SJohn Marino    *  contained in both ranges, the element from the first range is copied and
5748*e4b17023SJohn Marino    *  both ranges advance.  The output range may not overlap either input
5749*e4b17023SJohn Marino    *  range.
5750*e4b17023SJohn Marino   */
5751*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
5752*e4b17023SJohn Marino 	   typename _OutputIterator>
5753*e4b17023SJohn Marino     _OutputIterator
5754*e4b17023SJohn Marino     set_union(_InputIterator1 __first1, _InputIterator1 __last1,
5755*e4b17023SJohn Marino 	      _InputIterator2 __first2, _InputIterator2 __last2,
5756*e4b17023SJohn Marino 	      _OutputIterator __result)
5757*e4b17023SJohn Marino     {
5758*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
5759*e4b17023SJohn Marino 	_ValueType1;
5760*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
5761*e4b17023SJohn Marino 	_ValueType2;
5762*e4b17023SJohn Marino 
5763*e4b17023SJohn Marino       // concept requirements
5764*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5765*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5766*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5767*e4b17023SJohn Marino 				  _ValueType1>)
5768*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5769*e4b17023SJohn Marino 				  _ValueType2>)
5770*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
5771*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
5772*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first1, __last1, __first2);
5773*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first2, __last2, __first1);
5774*e4b17023SJohn Marino 
5775*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
5776*e4b17023SJohn Marino 	{
5777*e4b17023SJohn Marino 	  if (*__first1 < *__first2)
5778*e4b17023SJohn Marino 	    {
5779*e4b17023SJohn Marino 	      *__result = *__first1;
5780*e4b17023SJohn Marino 	      ++__first1;
5781*e4b17023SJohn Marino 	    }
5782*e4b17023SJohn Marino 	  else if (*__first2 < *__first1)
5783*e4b17023SJohn Marino 	    {
5784*e4b17023SJohn Marino 	      *__result = *__first2;
5785*e4b17023SJohn Marino 	      ++__first2;
5786*e4b17023SJohn Marino 	    }
5787*e4b17023SJohn Marino 	  else
5788*e4b17023SJohn Marino 	    {
5789*e4b17023SJohn Marino 	      *__result = *__first1;
5790*e4b17023SJohn Marino 	      ++__first1;
5791*e4b17023SJohn Marino 	      ++__first2;
5792*e4b17023SJohn Marino 	    }
5793*e4b17023SJohn Marino 	  ++__result;
5794*e4b17023SJohn Marino 	}
5795*e4b17023SJohn Marino       return std::copy(__first2, __last2, std::copy(__first1, __last1,
5796*e4b17023SJohn Marino 						    __result));
5797*e4b17023SJohn Marino     }
5798*e4b17023SJohn Marino 
5799*e4b17023SJohn Marino   /**
5800*e4b17023SJohn Marino    *  @brief Return the union of two sorted ranges using a comparison functor.
5801*e4b17023SJohn Marino    *  @ingroup set_algorithms
5802*e4b17023SJohn Marino    *  @param  __first1  Start of first range.
5803*e4b17023SJohn Marino    *  @param  __last1   End of first range.
5804*e4b17023SJohn Marino    *  @param  __first2  Start of second range.
5805*e4b17023SJohn Marino    *  @param  __last2   End of second range.
5806*e4b17023SJohn Marino    *  @param  __comp    The comparison functor.
5807*e4b17023SJohn Marino    *  @return  End of the output range.
5808*e4b17023SJohn Marino    *  @ingroup set_algorithms
5809*e4b17023SJohn Marino    *
5810*e4b17023SJohn Marino    *  This operation iterates over both ranges, copying elements present in
5811*e4b17023SJohn Marino    *  each range in order to the output range.  Iterators increment for each
5812*e4b17023SJohn Marino    *  range.  When the current element of one range is less than the other
5813*e4b17023SJohn Marino    *  according to @p __comp, that element is copied and the iterator advanced.
5814*e4b17023SJohn Marino    *  If an equivalent element according to @p __comp is contained in both
5815*e4b17023SJohn Marino    *  ranges, the element from the first range is copied and both ranges
5816*e4b17023SJohn Marino    *  advance.  The output range may not overlap either input range.
5817*e4b17023SJohn Marino   */
5818*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
5819*e4b17023SJohn Marino 	   typename _OutputIterator, typename _Compare>
5820*e4b17023SJohn Marino     _OutputIterator
5821*e4b17023SJohn Marino     set_union(_InputIterator1 __first1, _InputIterator1 __last1,
5822*e4b17023SJohn Marino 	      _InputIterator2 __first2, _InputIterator2 __last2,
5823*e4b17023SJohn Marino 	      _OutputIterator __result, _Compare __comp)
5824*e4b17023SJohn Marino     {
5825*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
5826*e4b17023SJohn Marino 	_ValueType1;
5827*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
5828*e4b17023SJohn Marino 	_ValueType2;
5829*e4b17023SJohn Marino 
5830*e4b17023SJohn Marino       // concept requirements
5831*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5832*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5833*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5834*e4b17023SJohn Marino 				  _ValueType1>)
5835*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5836*e4b17023SJohn Marino 				  _ValueType2>)
5837*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5838*e4b17023SJohn Marino 				  _ValueType1, _ValueType2>)
5839*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5840*e4b17023SJohn Marino 				  _ValueType2, _ValueType1>)
5841*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
5842*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
5843*e4b17023SJohn Marino 
5844*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
5845*e4b17023SJohn Marino 	{
5846*e4b17023SJohn Marino 	  if (__comp(*__first1, *__first2))
5847*e4b17023SJohn Marino 	    {
5848*e4b17023SJohn Marino 	      *__result = *__first1;
5849*e4b17023SJohn Marino 	      ++__first1;
5850*e4b17023SJohn Marino 	    }
5851*e4b17023SJohn Marino 	  else if (__comp(*__first2, *__first1))
5852*e4b17023SJohn Marino 	    {
5853*e4b17023SJohn Marino 	      *__result = *__first2;
5854*e4b17023SJohn Marino 	      ++__first2;
5855*e4b17023SJohn Marino 	    }
5856*e4b17023SJohn Marino 	  else
5857*e4b17023SJohn Marino 	    {
5858*e4b17023SJohn Marino 	      *__result = *__first1;
5859*e4b17023SJohn Marino 	      ++__first1;
5860*e4b17023SJohn Marino 	      ++__first2;
5861*e4b17023SJohn Marino 	    }
5862*e4b17023SJohn Marino 	  ++__result;
5863*e4b17023SJohn Marino 	}
5864*e4b17023SJohn Marino       return std::copy(__first2, __last2, std::copy(__first1, __last1,
5865*e4b17023SJohn Marino 						    __result));
5866*e4b17023SJohn Marino     }
5867*e4b17023SJohn Marino 
5868*e4b17023SJohn Marino   /**
5869*e4b17023SJohn Marino    *  @brief Return the intersection of two sorted ranges.
5870*e4b17023SJohn Marino    *  @ingroup set_algorithms
5871*e4b17023SJohn Marino    *  @param  __first1  Start of first range.
5872*e4b17023SJohn Marino    *  @param  __last1   End of first range.
5873*e4b17023SJohn Marino    *  @param  __first2  Start of second range.
5874*e4b17023SJohn Marino    *  @param  __last2   End of second range.
5875*e4b17023SJohn Marino    *  @return  End of the output range.
5876*e4b17023SJohn Marino    *  @ingroup set_algorithms
5877*e4b17023SJohn Marino    *
5878*e4b17023SJohn Marino    *  This operation iterates over both ranges, copying elements present in
5879*e4b17023SJohn Marino    *  both ranges in order to the output range.  Iterators increment for each
5880*e4b17023SJohn Marino    *  range.  When the current element of one range is less than the other,
5881*e4b17023SJohn Marino    *  that iterator advances.  If an element is contained in both ranges, the
5882*e4b17023SJohn Marino    *  element from the first range is copied and both ranges advance.  The
5883*e4b17023SJohn Marino    *  output range may not overlap either input range.
5884*e4b17023SJohn Marino   */
5885*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
5886*e4b17023SJohn Marino 	   typename _OutputIterator>
5887*e4b17023SJohn Marino     _OutputIterator
5888*e4b17023SJohn Marino     set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
5889*e4b17023SJohn Marino 		     _InputIterator2 __first2, _InputIterator2 __last2,
5890*e4b17023SJohn Marino 		     _OutputIterator __result)
5891*e4b17023SJohn Marino     {
5892*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
5893*e4b17023SJohn Marino 	_ValueType1;
5894*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
5895*e4b17023SJohn Marino 	_ValueType2;
5896*e4b17023SJohn Marino 
5897*e4b17023SJohn Marino       // concept requirements
5898*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5899*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5900*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5901*e4b17023SJohn Marino 				  _ValueType1>)
5902*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
5903*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
5904*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first1, __last1, __first2);
5905*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first2, __last2, __first1);
5906*e4b17023SJohn Marino 
5907*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
5908*e4b17023SJohn Marino 	if (*__first1 < *__first2)
5909*e4b17023SJohn Marino 	  ++__first1;
5910*e4b17023SJohn Marino 	else if (*__first2 < *__first1)
5911*e4b17023SJohn Marino 	  ++__first2;
5912*e4b17023SJohn Marino 	else
5913*e4b17023SJohn Marino 	  {
5914*e4b17023SJohn Marino 	    *__result = *__first1;
5915*e4b17023SJohn Marino 	    ++__first1;
5916*e4b17023SJohn Marino 	    ++__first2;
5917*e4b17023SJohn Marino 	    ++__result;
5918*e4b17023SJohn Marino 	  }
5919*e4b17023SJohn Marino       return __result;
5920*e4b17023SJohn Marino     }
5921*e4b17023SJohn Marino 
5922*e4b17023SJohn Marino   /**
5923*e4b17023SJohn Marino    *  @brief Return the intersection of two sorted ranges using comparison
5924*e4b17023SJohn Marino    *  functor.
5925*e4b17023SJohn Marino    *  @ingroup set_algorithms
5926*e4b17023SJohn Marino    *  @param  __first1  Start of first range.
5927*e4b17023SJohn Marino    *  @param  __last1   End of first range.
5928*e4b17023SJohn Marino    *  @param  __first2  Start of second range.
5929*e4b17023SJohn Marino    *  @param  __last2   End of second range.
5930*e4b17023SJohn Marino    *  @param  __comp    The comparison functor.
5931*e4b17023SJohn Marino    *  @return  End of the output range.
5932*e4b17023SJohn Marino    *  @ingroup set_algorithms
5933*e4b17023SJohn Marino    *
5934*e4b17023SJohn Marino    *  This operation iterates over both ranges, copying elements present in
5935*e4b17023SJohn Marino    *  both ranges in order to the output range.  Iterators increment for each
5936*e4b17023SJohn Marino    *  range.  When the current element of one range is less than the other
5937*e4b17023SJohn Marino    *  according to @p __comp, that iterator advances.  If an element is
5938*e4b17023SJohn Marino    *  contained in both ranges according to @p __comp, the element from the
5939*e4b17023SJohn Marino    *  first range is copied and both ranges advance.  The output range may not
5940*e4b17023SJohn Marino    *  overlap either input range.
5941*e4b17023SJohn Marino   */
5942*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
5943*e4b17023SJohn Marino 	   typename _OutputIterator, typename _Compare>
5944*e4b17023SJohn Marino     _OutputIterator
5945*e4b17023SJohn Marino     set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
5946*e4b17023SJohn Marino 		     _InputIterator2 __first2, _InputIterator2 __last2,
5947*e4b17023SJohn Marino 		     _OutputIterator __result, _Compare __comp)
5948*e4b17023SJohn Marino     {
5949*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
5950*e4b17023SJohn Marino 	_ValueType1;
5951*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
5952*e4b17023SJohn Marino 	_ValueType2;
5953*e4b17023SJohn Marino 
5954*e4b17023SJohn Marino       // concept requirements
5955*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5956*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5957*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5958*e4b17023SJohn Marino 				  _ValueType1>)
5959*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5960*e4b17023SJohn Marino 				  _ValueType1, _ValueType2>)
5961*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5962*e4b17023SJohn Marino 				  _ValueType2, _ValueType1>)
5963*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
5964*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
5965*e4b17023SJohn Marino 
5966*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
5967*e4b17023SJohn Marino 	if (__comp(*__first1, *__first2))
5968*e4b17023SJohn Marino 	  ++__first1;
5969*e4b17023SJohn Marino 	else if (__comp(*__first2, *__first1))
5970*e4b17023SJohn Marino 	  ++__first2;
5971*e4b17023SJohn Marino 	else
5972*e4b17023SJohn Marino 	  {
5973*e4b17023SJohn Marino 	    *__result = *__first1;
5974*e4b17023SJohn Marino 	    ++__first1;
5975*e4b17023SJohn Marino 	    ++__first2;
5976*e4b17023SJohn Marino 	    ++__result;
5977*e4b17023SJohn Marino 	  }
5978*e4b17023SJohn Marino       return __result;
5979*e4b17023SJohn Marino     }
5980*e4b17023SJohn Marino 
5981*e4b17023SJohn Marino   /**
5982*e4b17023SJohn Marino    *  @brief Return the difference of two sorted ranges.
5983*e4b17023SJohn Marino    *  @ingroup set_algorithms
5984*e4b17023SJohn Marino    *  @param  __first1  Start of first range.
5985*e4b17023SJohn Marino    *  @param  __last1   End of first range.
5986*e4b17023SJohn Marino    *  @param  __first2  Start of second range.
5987*e4b17023SJohn Marino    *  @param  __last2   End of second range.
5988*e4b17023SJohn Marino    *  @return  End of the output range.
5989*e4b17023SJohn Marino    *  @ingroup set_algorithms
5990*e4b17023SJohn Marino    *
5991*e4b17023SJohn Marino    *  This operation iterates over both ranges, copying elements present in
5992*e4b17023SJohn Marino    *  the first range but not the second in order to the output range.
5993*e4b17023SJohn Marino    *  Iterators increment for each range.  When the current element of the
5994*e4b17023SJohn Marino    *  first range is less than the second, that element is copied and the
5995*e4b17023SJohn Marino    *  iterator advances.  If the current element of the second range is less,
5996*e4b17023SJohn Marino    *  the iterator advances, but no element is copied.  If an element is
5997*e4b17023SJohn Marino    *  contained in both ranges, no elements are copied and both ranges
5998*e4b17023SJohn Marino    *  advance.  The output range may not overlap either input range.
5999*e4b17023SJohn Marino   */
6000*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
6001*e4b17023SJohn Marino 	   typename _OutputIterator>
6002*e4b17023SJohn Marino     _OutputIterator
6003*e4b17023SJohn Marino     set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
6004*e4b17023SJohn Marino 		   _InputIterator2 __first2, _InputIterator2 __last2,
6005*e4b17023SJohn Marino 		   _OutputIterator __result)
6006*e4b17023SJohn Marino     {
6007*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
6008*e4b17023SJohn Marino 	_ValueType1;
6009*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
6010*e4b17023SJohn Marino 	_ValueType2;
6011*e4b17023SJohn Marino 
6012*e4b17023SJohn Marino       // concept requirements
6013*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
6014*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
6015*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6016*e4b17023SJohn Marino 				  _ValueType1>)
6017*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
6018*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
6019*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first1, __last1, __first2);
6020*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first2, __last2, __first1);
6021*e4b17023SJohn Marino 
6022*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
6023*e4b17023SJohn Marino 	if (*__first1 < *__first2)
6024*e4b17023SJohn Marino 	  {
6025*e4b17023SJohn Marino 	    *__result = *__first1;
6026*e4b17023SJohn Marino 	    ++__first1;
6027*e4b17023SJohn Marino 	    ++__result;
6028*e4b17023SJohn Marino 	  }
6029*e4b17023SJohn Marino 	else if (*__first2 < *__first1)
6030*e4b17023SJohn Marino 	  ++__first2;
6031*e4b17023SJohn Marino 	else
6032*e4b17023SJohn Marino 	  {
6033*e4b17023SJohn Marino 	    ++__first1;
6034*e4b17023SJohn Marino 	    ++__first2;
6035*e4b17023SJohn Marino 	  }
6036*e4b17023SJohn Marino       return std::copy(__first1, __last1, __result);
6037*e4b17023SJohn Marino     }
6038*e4b17023SJohn Marino 
6039*e4b17023SJohn Marino   /**
6040*e4b17023SJohn Marino    *  @brief  Return the difference of two sorted ranges using comparison
6041*e4b17023SJohn Marino    *  functor.
6042*e4b17023SJohn Marino    *  @ingroup set_algorithms
6043*e4b17023SJohn Marino    *  @param  __first1  Start of first range.
6044*e4b17023SJohn Marino    *  @param  __last1   End of first range.
6045*e4b17023SJohn Marino    *  @param  __first2  Start of second range.
6046*e4b17023SJohn Marino    *  @param  __last2   End of second range.
6047*e4b17023SJohn Marino    *  @param  __comp    The comparison functor.
6048*e4b17023SJohn Marino    *  @return  End of the output range.
6049*e4b17023SJohn Marino    *  @ingroup set_algorithms
6050*e4b17023SJohn Marino    *
6051*e4b17023SJohn Marino    *  This operation iterates over both ranges, copying elements present in
6052*e4b17023SJohn Marino    *  the first range but not the second in order to the output range.
6053*e4b17023SJohn Marino    *  Iterators increment for each range.  When the current element of the
6054*e4b17023SJohn Marino    *  first range is less than the second according to @p __comp, that element
6055*e4b17023SJohn Marino    *  is copied and the iterator advances.  If the current element of the
6056*e4b17023SJohn Marino    *  second range is less, no element is copied and the iterator advances.
6057*e4b17023SJohn Marino    *  If an element is contained in both ranges according to @p __comp, no
6058*e4b17023SJohn Marino    *  elements are copied and both ranges advance.  The output range may not
6059*e4b17023SJohn Marino    *  overlap either input range.
6060*e4b17023SJohn Marino   */
6061*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
6062*e4b17023SJohn Marino 	   typename _OutputIterator, typename _Compare>
6063*e4b17023SJohn Marino     _OutputIterator
6064*e4b17023SJohn Marino     set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
6065*e4b17023SJohn Marino 		   _InputIterator2 __first2, _InputIterator2 __last2,
6066*e4b17023SJohn Marino 		   _OutputIterator __result, _Compare __comp)
6067*e4b17023SJohn Marino     {
6068*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
6069*e4b17023SJohn Marino 	_ValueType1;
6070*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
6071*e4b17023SJohn Marino 	_ValueType2;
6072*e4b17023SJohn Marino 
6073*e4b17023SJohn Marino       // concept requirements
6074*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
6075*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
6076*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6077*e4b17023SJohn Marino 				  _ValueType1>)
6078*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6079*e4b17023SJohn Marino 				  _ValueType1, _ValueType2>)
6080*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6081*e4b17023SJohn Marino 				  _ValueType2, _ValueType1>)
6082*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
6083*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
6084*e4b17023SJohn Marino 
6085*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
6086*e4b17023SJohn Marino 	if (__comp(*__first1, *__first2))
6087*e4b17023SJohn Marino 	  {
6088*e4b17023SJohn Marino 	    *__result = *__first1;
6089*e4b17023SJohn Marino 	    ++__first1;
6090*e4b17023SJohn Marino 	    ++__result;
6091*e4b17023SJohn Marino 	  }
6092*e4b17023SJohn Marino 	else if (__comp(*__first2, *__first1))
6093*e4b17023SJohn Marino 	  ++__first2;
6094*e4b17023SJohn Marino 	else
6095*e4b17023SJohn Marino 	  {
6096*e4b17023SJohn Marino 	    ++__first1;
6097*e4b17023SJohn Marino 	    ++__first2;
6098*e4b17023SJohn Marino 	  }
6099*e4b17023SJohn Marino       return std::copy(__first1, __last1, __result);
6100*e4b17023SJohn Marino     }
6101*e4b17023SJohn Marino 
6102*e4b17023SJohn Marino   /**
6103*e4b17023SJohn Marino    *  @brief  Return the symmetric difference of two sorted ranges.
6104*e4b17023SJohn Marino    *  @ingroup set_algorithms
6105*e4b17023SJohn Marino    *  @param  __first1  Start of first range.
6106*e4b17023SJohn Marino    *  @param  __last1   End of first range.
6107*e4b17023SJohn Marino    *  @param  __first2  Start of second range.
6108*e4b17023SJohn Marino    *  @param  __last2   End of second range.
6109*e4b17023SJohn Marino    *  @return  End of the output range.
6110*e4b17023SJohn Marino    *  @ingroup set_algorithms
6111*e4b17023SJohn Marino    *
6112*e4b17023SJohn Marino    *  This operation iterates over both ranges, copying elements present in
6113*e4b17023SJohn Marino    *  one range but not the other in order to the output range.  Iterators
6114*e4b17023SJohn Marino    *  increment for each range.  When the current element of one range is less
6115*e4b17023SJohn Marino    *  than the other, that element is copied and the iterator advances.  If an
6116*e4b17023SJohn Marino    *  element is contained in both ranges, no elements are copied and both
6117*e4b17023SJohn Marino    *  ranges advance.  The output range may not overlap either input range.
6118*e4b17023SJohn Marino   */
6119*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
6120*e4b17023SJohn Marino 	   typename _OutputIterator>
6121*e4b17023SJohn Marino     _OutputIterator
6122*e4b17023SJohn Marino     set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
6123*e4b17023SJohn Marino 			     _InputIterator2 __first2, _InputIterator2 __last2,
6124*e4b17023SJohn Marino 			     _OutputIterator __result)
6125*e4b17023SJohn Marino     {
6126*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
6127*e4b17023SJohn Marino 	_ValueType1;
6128*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
6129*e4b17023SJohn Marino 	_ValueType2;
6130*e4b17023SJohn Marino 
6131*e4b17023SJohn Marino       // concept requirements
6132*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
6133*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
6134*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6135*e4b17023SJohn Marino 				  _ValueType1>)
6136*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6137*e4b17023SJohn Marino 				  _ValueType2>)
6138*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
6139*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
6140*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first1, __last1, __first2);
6141*e4b17023SJohn Marino       __glibcxx_requires_sorted_set(__first2, __last2, __first1);
6142*e4b17023SJohn Marino 
6143*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
6144*e4b17023SJohn Marino 	if (*__first1 < *__first2)
6145*e4b17023SJohn Marino 	  {
6146*e4b17023SJohn Marino 	    *__result = *__first1;
6147*e4b17023SJohn Marino 	    ++__first1;
6148*e4b17023SJohn Marino 	    ++__result;
6149*e4b17023SJohn Marino 	  }
6150*e4b17023SJohn Marino 	else if (*__first2 < *__first1)
6151*e4b17023SJohn Marino 	  {
6152*e4b17023SJohn Marino 	    *__result = *__first2;
6153*e4b17023SJohn Marino 	    ++__first2;
6154*e4b17023SJohn Marino 	    ++__result;
6155*e4b17023SJohn Marino 	  }
6156*e4b17023SJohn Marino 	else
6157*e4b17023SJohn Marino 	  {
6158*e4b17023SJohn Marino 	    ++__first1;
6159*e4b17023SJohn Marino 	    ++__first2;
6160*e4b17023SJohn Marino 	  }
6161*e4b17023SJohn Marino       return std::copy(__first2, __last2, std::copy(__first1,
6162*e4b17023SJohn Marino 						    __last1, __result));
6163*e4b17023SJohn Marino     }
6164*e4b17023SJohn Marino 
6165*e4b17023SJohn Marino   /**
6166*e4b17023SJohn Marino    *  @brief  Return the symmetric difference of two sorted ranges using
6167*e4b17023SJohn Marino    *  comparison functor.
6168*e4b17023SJohn Marino    *  @ingroup set_algorithms
6169*e4b17023SJohn Marino    *  @param  __first1  Start of first range.
6170*e4b17023SJohn Marino    *  @param  __last1   End of first range.
6171*e4b17023SJohn Marino    *  @param  __first2  Start of second range.
6172*e4b17023SJohn Marino    *  @param  __last2   End of second range.
6173*e4b17023SJohn Marino    *  @param  __comp    The comparison functor.
6174*e4b17023SJohn Marino    *  @return  End of the output range.
6175*e4b17023SJohn Marino    *  @ingroup set_algorithms
6176*e4b17023SJohn Marino    *
6177*e4b17023SJohn Marino    *  This operation iterates over both ranges, copying elements present in
6178*e4b17023SJohn Marino    *  one range but not the other in order to the output range.  Iterators
6179*e4b17023SJohn Marino    *  increment for each range.  When the current element of one range is less
6180*e4b17023SJohn Marino    *  than the other according to @p comp, that element is copied and the
6181*e4b17023SJohn Marino    *  iterator advances.  If an element is contained in both ranges according
6182*e4b17023SJohn Marino    *  to @p __comp, no elements are copied and both ranges advance.  The output
6183*e4b17023SJohn Marino    *  range may not overlap either input range.
6184*e4b17023SJohn Marino   */
6185*e4b17023SJohn Marino   template<typename _InputIterator1, typename _InputIterator2,
6186*e4b17023SJohn Marino 	   typename _OutputIterator, typename _Compare>
6187*e4b17023SJohn Marino     _OutputIterator
6188*e4b17023SJohn Marino     set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
6189*e4b17023SJohn Marino 			     _InputIterator2 __first2, _InputIterator2 __last2,
6190*e4b17023SJohn Marino 			     _OutputIterator __result,
6191*e4b17023SJohn Marino 			     _Compare __comp)
6192*e4b17023SJohn Marino     {
6193*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator1>::value_type
6194*e4b17023SJohn Marino 	_ValueType1;
6195*e4b17023SJohn Marino       typedef typename iterator_traits<_InputIterator2>::value_type
6196*e4b17023SJohn Marino 	_ValueType2;
6197*e4b17023SJohn Marino 
6198*e4b17023SJohn Marino       // concept requirements
6199*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
6200*e4b17023SJohn Marino       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
6201*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6202*e4b17023SJohn Marino 				  _ValueType1>)
6203*e4b17023SJohn Marino       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6204*e4b17023SJohn Marino 				  _ValueType2>)
6205*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6206*e4b17023SJohn Marino 				  _ValueType1, _ValueType2>)
6207*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6208*e4b17023SJohn Marino 				  _ValueType2, _ValueType1>)
6209*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
6210*e4b17023SJohn Marino       __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
6211*e4b17023SJohn Marino 
6212*e4b17023SJohn Marino       while (__first1 != __last1 && __first2 != __last2)
6213*e4b17023SJohn Marino 	if (__comp(*__first1, *__first2))
6214*e4b17023SJohn Marino 	  {
6215*e4b17023SJohn Marino 	    *__result = *__first1;
6216*e4b17023SJohn Marino 	    ++__first1;
6217*e4b17023SJohn Marino 	    ++__result;
6218*e4b17023SJohn Marino 	  }
6219*e4b17023SJohn Marino 	else if (__comp(*__first2, *__first1))
6220*e4b17023SJohn Marino 	  {
6221*e4b17023SJohn Marino 	    *__result = *__first2;
6222*e4b17023SJohn Marino 	    ++__first2;
6223*e4b17023SJohn Marino 	    ++__result;
6224*e4b17023SJohn Marino 	  }
6225*e4b17023SJohn Marino 	else
6226*e4b17023SJohn Marino 	  {
6227*e4b17023SJohn Marino 	    ++__first1;
6228*e4b17023SJohn Marino 	    ++__first2;
6229*e4b17023SJohn Marino 	  }
6230*e4b17023SJohn Marino       return std::copy(__first2, __last2,
6231*e4b17023SJohn Marino 		       std::copy(__first1, __last1, __result));
6232*e4b17023SJohn Marino     }
6233*e4b17023SJohn Marino 
6234*e4b17023SJohn Marino 
6235*e4b17023SJohn Marino   /**
6236*e4b17023SJohn Marino    *  @brief  Return the minimum element in a range.
6237*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
6238*e4b17023SJohn Marino    *  @param  __first  Start of range.
6239*e4b17023SJohn Marino    *  @param  __last   End of range.
6240*e4b17023SJohn Marino    *  @return  Iterator referencing the first instance of the smallest value.
6241*e4b17023SJohn Marino   */
6242*e4b17023SJohn Marino   template<typename _ForwardIterator>
6243*e4b17023SJohn Marino     _ForwardIterator
6244*e4b17023SJohn Marino     min_element(_ForwardIterator __first, _ForwardIterator __last)
6245*e4b17023SJohn Marino     {
6246*e4b17023SJohn Marino       // concept requirements
6247*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
6248*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<
6249*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
6250*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
6251*e4b17023SJohn Marino 
6252*e4b17023SJohn Marino       if (__first == __last)
6253*e4b17023SJohn Marino 	return __first;
6254*e4b17023SJohn Marino       _ForwardIterator __result = __first;
6255*e4b17023SJohn Marino       while (++__first != __last)
6256*e4b17023SJohn Marino 	if (*__first < *__result)
6257*e4b17023SJohn Marino 	  __result = __first;
6258*e4b17023SJohn Marino       return __result;
6259*e4b17023SJohn Marino     }
6260*e4b17023SJohn Marino 
6261*e4b17023SJohn Marino   /**
6262*e4b17023SJohn Marino    *  @brief  Return the minimum element in a range using comparison functor.
6263*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
6264*e4b17023SJohn Marino    *  @param  __first  Start of range.
6265*e4b17023SJohn Marino    *  @param  __last   End of range.
6266*e4b17023SJohn Marino    *  @param  __comp   Comparison functor.
6267*e4b17023SJohn Marino    *  @return  Iterator referencing the first instance of the smallest value
6268*e4b17023SJohn Marino    *  according to __comp.
6269*e4b17023SJohn Marino   */
6270*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Compare>
6271*e4b17023SJohn Marino     _ForwardIterator
6272*e4b17023SJohn Marino     min_element(_ForwardIterator __first, _ForwardIterator __last,
6273*e4b17023SJohn Marino 		_Compare __comp)
6274*e4b17023SJohn Marino     {
6275*e4b17023SJohn Marino       // concept requirements
6276*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
6277*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6278*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type,
6279*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
6280*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
6281*e4b17023SJohn Marino 
6282*e4b17023SJohn Marino       if (__first == __last)
6283*e4b17023SJohn Marino 	return __first;
6284*e4b17023SJohn Marino       _ForwardIterator __result = __first;
6285*e4b17023SJohn Marino       while (++__first != __last)
6286*e4b17023SJohn Marino 	if (__comp(*__first, *__result))
6287*e4b17023SJohn Marino 	  __result = __first;
6288*e4b17023SJohn Marino       return __result;
6289*e4b17023SJohn Marino     }
6290*e4b17023SJohn Marino 
6291*e4b17023SJohn Marino   /**
6292*e4b17023SJohn Marino    *  @brief  Return the maximum element in a range.
6293*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
6294*e4b17023SJohn Marino    *  @param  __first  Start of range.
6295*e4b17023SJohn Marino    *  @param  __last   End of range.
6296*e4b17023SJohn Marino    *  @return  Iterator referencing the first instance of the largest value.
6297*e4b17023SJohn Marino   */
6298*e4b17023SJohn Marino   template<typename _ForwardIterator>
6299*e4b17023SJohn Marino     _ForwardIterator
6300*e4b17023SJohn Marino     max_element(_ForwardIterator __first, _ForwardIterator __last)
6301*e4b17023SJohn Marino     {
6302*e4b17023SJohn Marino       // concept requirements
6303*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
6304*e4b17023SJohn Marino       __glibcxx_function_requires(_LessThanComparableConcept<
6305*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
6306*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
6307*e4b17023SJohn Marino 
6308*e4b17023SJohn Marino       if (__first == __last)
6309*e4b17023SJohn Marino 	return __first;
6310*e4b17023SJohn Marino       _ForwardIterator __result = __first;
6311*e4b17023SJohn Marino       while (++__first != __last)
6312*e4b17023SJohn Marino 	if (*__result < *__first)
6313*e4b17023SJohn Marino 	  __result = __first;
6314*e4b17023SJohn Marino       return __result;
6315*e4b17023SJohn Marino     }
6316*e4b17023SJohn Marino 
6317*e4b17023SJohn Marino   /**
6318*e4b17023SJohn Marino    *  @brief  Return the maximum element in a range using comparison functor.
6319*e4b17023SJohn Marino    *  @ingroup sorting_algorithms
6320*e4b17023SJohn Marino    *  @param  __first  Start of range.
6321*e4b17023SJohn Marino    *  @param  __last   End of range.
6322*e4b17023SJohn Marino    *  @param  __comp   Comparison functor.
6323*e4b17023SJohn Marino    *  @return  Iterator referencing the first instance of the largest value
6324*e4b17023SJohn Marino    *  according to __comp.
6325*e4b17023SJohn Marino   */
6326*e4b17023SJohn Marino   template<typename _ForwardIterator, typename _Compare>
6327*e4b17023SJohn Marino     _ForwardIterator
6328*e4b17023SJohn Marino     max_element(_ForwardIterator __first, _ForwardIterator __last,
6329*e4b17023SJohn Marino 		_Compare __comp)
6330*e4b17023SJohn Marino     {
6331*e4b17023SJohn Marino       // concept requirements
6332*e4b17023SJohn Marino       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
6333*e4b17023SJohn Marino       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6334*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type,
6335*e4b17023SJohn Marino 	    typename iterator_traits<_ForwardIterator>::value_type>)
6336*e4b17023SJohn Marino       __glibcxx_requires_valid_range(__first, __last);
6337*e4b17023SJohn Marino 
6338*e4b17023SJohn Marino       if (__first == __last) return __first;
6339*e4b17023SJohn Marino       _ForwardIterator __result = __first;
6340*e4b17023SJohn Marino       while (++__first != __last)
6341*e4b17023SJohn Marino 	if (__comp(*__result, *__first))
6342*e4b17023SJohn Marino 	  __result = __first;
6343*e4b17023SJohn Marino       return __result;
6344*e4b17023SJohn Marino     }
6345*e4b17023SJohn Marino 
6346*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_ALGO
6347*e4b17023SJohn Marino } // namespace std
6348*e4b17023SJohn Marino 
6349*e4b17023SJohn Marino #endif /* _STL_ALGO_H */
6350