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