xref: /openbsd-src/gnu/gcc/libstdc++-v3/include/ext/algorithm (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert// Algorithm extensions -*- C++ -*-
2*404b540aSrobert
3*404b540aSrobert// Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
4*404b540aSrobert//
5*404b540aSrobert// This file is part of the GNU ISO C++ Library.  This library is free
6*404b540aSrobert// software; you can redistribute it and/or modify it under the
7*404b540aSrobert// terms of the GNU General Public License as published by the
8*404b540aSrobert// Free Software Foundation; either version 2, or (at your option)
9*404b540aSrobert// any later version.
10*404b540aSrobert
11*404b540aSrobert// This library is distributed in the hope that it will be useful,
12*404b540aSrobert// but WITHOUT ANY WARRANTY; without even the implied warranty of
13*404b540aSrobert// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*404b540aSrobert// GNU General Public License for more details.
15*404b540aSrobert
16*404b540aSrobert// You should have received a copy of the GNU General Public License along
17*404b540aSrobert// with this library; see the file COPYING.  If not, write to the Free
18*404b540aSrobert// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19*404b540aSrobert// USA.
20*404b540aSrobert
21*404b540aSrobert// As a special exception, you may use this file as part of a free software
22*404b540aSrobert// library without restriction.  Specifically, if other files instantiate
23*404b540aSrobert// templates or use macros or inline functions from this file, or you compile
24*404b540aSrobert// this file and link it with other files to produce an executable, this
25*404b540aSrobert// file does not by itself cause the resulting executable to be covered by
26*404b540aSrobert// the GNU General Public License.  This exception does not however
27*404b540aSrobert// invalidate any other reasons why the executable file might be covered by
28*404b540aSrobert// the GNU General Public License.
29*404b540aSrobert
30*404b540aSrobert/*
31*404b540aSrobert *
32*404b540aSrobert * Copyright (c) 1994
33*404b540aSrobert * Hewlett-Packard Company
34*404b540aSrobert *
35*404b540aSrobert * Permission to use, copy, modify, distribute and sell this software
36*404b540aSrobert * and its documentation for any purpose is hereby granted without fee,
37*404b540aSrobert * provided that the above copyright notice appear in all copies and
38*404b540aSrobert * that both that copyright notice and this permission notice appear
39*404b540aSrobert * in supporting documentation.  Hewlett-Packard Company makes no
40*404b540aSrobert * representations about the suitability of this software for any
41*404b540aSrobert * purpose.  It is provided "as is" without express or implied warranty.
42*404b540aSrobert *
43*404b540aSrobert *
44*404b540aSrobert * Copyright (c) 1996
45*404b540aSrobert * Silicon Graphics Computer Systems, Inc.
46*404b540aSrobert *
47*404b540aSrobert * Permission to use, copy, modify, distribute and sell this software
48*404b540aSrobert * and its documentation for any purpose is hereby granted without fee,
49*404b540aSrobert * provided that the above copyright notice appear in all copies and
50*404b540aSrobert * that both that copyright notice and this permission notice appear
51*404b540aSrobert * in supporting documentation.  Silicon Graphics makes no
52*404b540aSrobert * representations about the suitability of this software for any
53*404b540aSrobert * purpose.  It is provided "as is" without express or implied warranty.
54*404b540aSrobert */
55*404b540aSrobert
56*404b540aSrobert/** @file ext/algorithm
57*404b540aSrobert *  This file is a GNU extension to the Standard C++ Library (possibly
58*404b540aSrobert *  containing extensions from the HP/SGI STL subset).
59*404b540aSrobert */
60*404b540aSrobert
61*404b540aSrobert#ifndef _EXT_ALGORITHM
62*404b540aSrobert#define _EXT_ALGORITHM 1
63*404b540aSrobert
64*404b540aSrobert#pragma GCC system_header
65*404b540aSrobert
66*404b540aSrobert#include <algorithm>
67*404b540aSrobert
68*404b540aSrobert_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
69*404b540aSrobert
70*404b540aSrobert  using std::ptrdiff_t;
71*404b540aSrobert  using std::min;
72*404b540aSrobert  using std::pair;
73*404b540aSrobert  using std::input_iterator_tag;
74*404b540aSrobert  using std::random_access_iterator_tag;
75*404b540aSrobert  using std::iterator_traits;
76*404b540aSrobert
77*404b540aSrobert  //--------------------------------------------------
78*404b540aSrobert  // copy_n (not part of the C++ standard)
79*404b540aSrobert
80*404b540aSrobert  template<typename _InputIterator, typename _Size, typename _OutputIterator>
81*404b540aSrobert    pair<_InputIterator, _OutputIterator>
82*404b540aSrobert    __copy_n(_InputIterator __first, _Size __count,
83*404b540aSrobert	     _OutputIterator __result,
84*404b540aSrobert	     input_iterator_tag)
85*404b540aSrobert    {
86*404b540aSrobert      for ( ; __count > 0; --__count)
87*404b540aSrobert	{
88*404b540aSrobert	  *__result = *__first;
89*404b540aSrobert	  ++__first;
90*404b540aSrobert	  ++__result;
91*404b540aSrobert	}
92*404b540aSrobert      return pair<_InputIterator, _OutputIterator>(__first, __result);
93*404b540aSrobert    }
94*404b540aSrobert
95*404b540aSrobert  template<typename _RAIterator, typename _Size, typename _OutputIterator>
96*404b540aSrobert    inline pair<_RAIterator, _OutputIterator>
97*404b540aSrobert    __copy_n(_RAIterator __first, _Size __count,
98*404b540aSrobert	     _OutputIterator __result,
99*404b540aSrobert	     random_access_iterator_tag)
100*404b540aSrobert    {
101*404b540aSrobert      _RAIterator __last = __first + __count;
102*404b540aSrobert      return pair<_RAIterator, _OutputIterator>(__last, std::copy(__first,
103*404b540aSrobert								  __last,
104*404b540aSrobert								  __result));
105*404b540aSrobert    }
106*404b540aSrobert
107*404b540aSrobert  /**
108*404b540aSrobert   *  @brief Copies the range [first,first+count) into [result,result+count).
109*404b540aSrobert   *  @param  first  An input iterator.
110*404b540aSrobert   *  @param  count  The number of elements to copy.
111*404b540aSrobert   *  @param  result An output iterator.
112*404b540aSrobert   *  @return   A std::pair composed of first+count and result+count.
113*404b540aSrobert   *
114*404b540aSrobert   *  This is an SGI extension.
115*404b540aSrobert   *  This inline function will boil down to a call to @c memmove whenever
116*404b540aSrobert   *  possible.  Failing that, if random access iterators are passed, then the
117*404b540aSrobert   *  loop count will be known (and therefore a candidate for compiler
118*404b540aSrobert   *  optimizations such as unrolling).
119*404b540aSrobert   *  @ingroup SGIextensions
120*404b540aSrobert  */
121*404b540aSrobert  template<typename _InputIterator, typename _Size, typename _OutputIterator>
122*404b540aSrobert    inline pair<_InputIterator, _OutputIterator>
123*404b540aSrobert    copy_n(_InputIterator __first, _Size __count, _OutputIterator __result)
124*404b540aSrobert    {
125*404b540aSrobert      // concept requirements
126*404b540aSrobert      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
127*404b540aSrobert      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
128*404b540aSrobert	    typename iterator_traits<_InputIterator>::value_type>)
129*404b540aSrobert
130*404b540aSrobert      return __copy_n(__first, __count, __result,
131*404b540aSrobert		      std::__iterator_category(__first));
132*404b540aSrobert    }
133*404b540aSrobert
134*404b540aSrobert  template<typename _InputIterator1, typename _InputIterator2>
135*404b540aSrobert    int
136*404b540aSrobert    __lexicographical_compare_3way(_InputIterator1 __first1,
137*404b540aSrobert				   _InputIterator1 __last1,
138*404b540aSrobert				   _InputIterator2 __first2,
139*404b540aSrobert				   _InputIterator2 __last2)
140*404b540aSrobert    {
141*404b540aSrobert      while (__first1 != __last1 && __first2 != __last2)
142*404b540aSrobert	{
143*404b540aSrobert	  if (*__first1 < *__first2)
144*404b540aSrobert	    return -1;
145*404b540aSrobert	  if (*__first2 < *__first1)
146*404b540aSrobert	    return 1;
147*404b540aSrobert	  ++__first1;
148*404b540aSrobert	  ++__first2;
149*404b540aSrobert	}
150*404b540aSrobert      if (__first2 == __last2)
151*404b540aSrobert	return !(__first1 == __last1);
152*404b540aSrobert      else
153*404b540aSrobert	return -1;
154*404b540aSrobert    }
155*404b540aSrobert
156*404b540aSrobert  inline int
157*404b540aSrobert  __lexicographical_compare_3way(const unsigned char* __first1,
158*404b540aSrobert				 const unsigned char* __last1,
159*404b540aSrobert				 const unsigned char* __first2,
160*404b540aSrobert				 const unsigned char* __last2)
161*404b540aSrobert  {
162*404b540aSrobert    const ptrdiff_t __len1 = __last1 - __first1;
163*404b540aSrobert    const ptrdiff_t __len2 = __last2 - __first2;
164*404b540aSrobert    const int __result = std::memcmp(__first1, __first2, min(__len1, __len2));
165*404b540aSrobert    return __result != 0 ? __result
166*404b540aSrobert			 : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1));
167*404b540aSrobert  }
168*404b540aSrobert
169*404b540aSrobert  inline int
170*404b540aSrobert  __lexicographical_compare_3way(const char* __first1, const char* __last1,
171*404b540aSrobert				 const char* __first2, const char* __last2)
172*404b540aSrobert  {
173*404b540aSrobert#if CHAR_MAX == SCHAR_MAX
174*404b540aSrobert    return __lexicographical_compare_3way((const signed char*) __first1,
175*404b540aSrobert					  (const signed char*) __last1,
176*404b540aSrobert					  (const signed char*) __first2,
177*404b540aSrobert					  (const signed char*) __last2);
178*404b540aSrobert#else
179*404b540aSrobert    return __lexicographical_compare_3way((const unsigned char*) __first1,
180*404b540aSrobert					  (const unsigned char*) __last1,
181*404b540aSrobert					  (const unsigned char*) __first2,
182*404b540aSrobert					  (const unsigned char*) __last2);
183*404b540aSrobert#endif
184*404b540aSrobert  }
185*404b540aSrobert
186*404b540aSrobert  /**
187*404b540aSrobert   *  @brief @c memcmp on steroids.
188*404b540aSrobert   *  @param  first1  An input iterator.
189*404b540aSrobert   *  @param  last1   An input iterator.
190*404b540aSrobert   *  @param  first2  An input iterator.
191*404b540aSrobert   *  @param  last2   An input iterator.
192*404b540aSrobert   *  @return   An int, as with @c memcmp.
193*404b540aSrobert   *
194*404b540aSrobert   *  The return value will be less than zero if the first range is
195*404b540aSrobert   *  "lexigraphically less than" the second, greater than zero if the second
196*404b540aSrobert   *  range is "lexigraphically less than" the first, and zero otherwise.
197*404b540aSrobert   *  This is an SGI extension.
198*404b540aSrobert   *  @ingroup SGIextensions
199*404b540aSrobert  */
200*404b540aSrobert  template<typename _InputIterator1, typename _InputIterator2>
201*404b540aSrobert    int
202*404b540aSrobert    lexicographical_compare_3way(_InputIterator1 __first1,
203*404b540aSrobert				 _InputIterator1 __last1,
204*404b540aSrobert				 _InputIterator2 __first2,
205*404b540aSrobert				 _InputIterator2 __last2)
206*404b540aSrobert    {
207*404b540aSrobert      // concept requirements
208*404b540aSrobert      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
209*404b540aSrobert      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
210*404b540aSrobert      __glibcxx_function_requires(_LessThanComparableConcept<
211*404b540aSrobert	    typename iterator_traits<_InputIterator1>::value_type>)
212*404b540aSrobert      __glibcxx_function_requires(_LessThanComparableConcept<
213*404b540aSrobert	    typename iterator_traits<_InputIterator2>::value_type>)
214*404b540aSrobert      __glibcxx_requires_valid_range(__first1, __last1);
215*404b540aSrobert      __glibcxx_requires_valid_range(__first2, __last2);
216*404b540aSrobert
217*404b540aSrobert      return __lexicographical_compare_3way(__first1, __last1, __first2,
218*404b540aSrobert					    __last2);
219*404b540aSrobert    }
220*404b540aSrobert
221*404b540aSrobert  // count and count_if: this version, whose return type is void, was present
222*404b540aSrobert  // in the HP STL, and is retained as an extension for backward compatibility.
223*404b540aSrobert  template<typename _InputIterator, typename _Tp, typename _Size>
224*404b540aSrobert    void
225*404b540aSrobert    count(_InputIterator __first, _InputIterator __last,
226*404b540aSrobert	  const _Tp& __value,
227*404b540aSrobert	  _Size& __n)
228*404b540aSrobert    {
229*404b540aSrobert      // concept requirements
230*404b540aSrobert      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
231*404b540aSrobert      __glibcxx_function_requires(_EqualityComparableConcept<
232*404b540aSrobert	    typename iterator_traits<_InputIterator>::value_type >)
233*404b540aSrobert      __glibcxx_function_requires(_EqualityComparableConcept<_Tp>)
234*404b540aSrobert      __glibcxx_requires_valid_range(__first, __last);
235*404b540aSrobert
236*404b540aSrobert      for ( ; __first != __last; ++__first)
237*404b540aSrobert	if (*__first == __value)
238*404b540aSrobert	  ++__n;
239*404b540aSrobert    }
240*404b540aSrobert
241*404b540aSrobert  template<typename _InputIterator, typename _Predicate, typename _Size>
242*404b540aSrobert    void
243*404b540aSrobert    count_if(_InputIterator __first, _InputIterator __last,
244*404b540aSrobert	     _Predicate __pred,
245*404b540aSrobert	     _Size& __n)
246*404b540aSrobert    {
247*404b540aSrobert      // concept requirements
248*404b540aSrobert      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
249*404b540aSrobert      __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
250*404b540aSrobert	    typename iterator_traits<_InputIterator>::value_type>)
251*404b540aSrobert      __glibcxx_requires_valid_range(__first, __last);
252*404b540aSrobert
253*404b540aSrobert      for ( ; __first != __last; ++__first)
254*404b540aSrobert	if (__pred(*__first))
255*404b540aSrobert	  ++__n;
256*404b540aSrobert    }
257*404b540aSrobert
258*404b540aSrobert  // random_sample and random_sample_n (extensions, not part of the standard).
259*404b540aSrobert
260*404b540aSrobert  /**
261*404b540aSrobert   *  This is an SGI extension.
262*404b540aSrobert   *  @ingroup SGIextensions
263*404b540aSrobert   *  @doctodo
264*404b540aSrobert  */
265*404b540aSrobert  template<typename _ForwardIterator, typename _OutputIterator,
266*404b540aSrobert	   typename _Distance>
267*404b540aSrobert    _OutputIterator
268*404b540aSrobert    random_sample_n(_ForwardIterator __first, _ForwardIterator __last,
269*404b540aSrobert                    _OutputIterator __out, const _Distance __n)
270*404b540aSrobert    {
271*404b540aSrobert      // concept requirements
272*404b540aSrobert      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
273*404b540aSrobert      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
274*404b540aSrobert		typename iterator_traits<_ForwardIterator>::value_type>)
275*404b540aSrobert      __glibcxx_requires_valid_range(__first, __last);
276*404b540aSrobert
277*404b540aSrobert      _Distance __remaining = std::distance(__first, __last);
278*404b540aSrobert      _Distance __m = min(__n, __remaining);
279*404b540aSrobert
280*404b540aSrobert      while (__m > 0)
281*404b540aSrobert	{
282*404b540aSrobert	  if ((std::rand() % __remaining) < __m)
283*404b540aSrobert	    {
284*404b540aSrobert	      *__out = *__first;
285*404b540aSrobert	      ++__out;
286*404b540aSrobert	      --__m;
287*404b540aSrobert	    }
288*404b540aSrobert	  --__remaining;
289*404b540aSrobert	  ++__first;
290*404b540aSrobert	}
291*404b540aSrobert      return __out;
292*404b540aSrobert    }
293*404b540aSrobert
294*404b540aSrobert  /**
295*404b540aSrobert   *  This is an SGI extension.
296*404b540aSrobert   *  @ingroup SGIextensions
297*404b540aSrobert   *  @doctodo
298*404b540aSrobert  */
299*404b540aSrobert  template<typename _ForwardIterator, typename _OutputIterator,
300*404b540aSrobert	   typename _Distance, typename _RandomNumberGenerator>
301*404b540aSrobert    _OutputIterator
302*404b540aSrobert    random_sample_n(_ForwardIterator __first, _ForwardIterator __last,
303*404b540aSrobert                   _OutputIterator __out, const _Distance __n,
304*404b540aSrobert		   _RandomNumberGenerator& __rand)
305*404b540aSrobert    {
306*404b540aSrobert      // concept requirements
307*404b540aSrobert      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
308*404b540aSrobert      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
309*404b540aSrobert		typename iterator_traits<_ForwardIterator>::value_type>)
310*404b540aSrobert      __glibcxx_function_requires(_UnaryFunctionConcept<
311*404b540aSrobert		_RandomNumberGenerator, _Distance, _Distance>)
312*404b540aSrobert      __glibcxx_requires_valid_range(__first, __last);
313*404b540aSrobert
314*404b540aSrobert      _Distance __remaining = std::distance(__first, __last);
315*404b540aSrobert      _Distance __m = min(__n, __remaining);
316*404b540aSrobert
317*404b540aSrobert      while (__m > 0)
318*404b540aSrobert	{
319*404b540aSrobert	  if (__rand(__remaining) < __m)
320*404b540aSrobert	    {
321*404b540aSrobert	      *__out = *__first;
322*404b540aSrobert	      ++__out;
323*404b540aSrobert	      --__m;
324*404b540aSrobert	    }
325*404b540aSrobert	  --__remaining;
326*404b540aSrobert	  ++__first;
327*404b540aSrobert	}
328*404b540aSrobert      return __out;
329*404b540aSrobert    }
330*404b540aSrobert
331*404b540aSrobert  template<typename _InputIterator, typename _RandomAccessIterator,
332*404b540aSrobert	   typename _Distance>
333*404b540aSrobert    _RandomAccessIterator
334*404b540aSrobert    __random_sample(_InputIterator __first, _InputIterator __last,
335*404b540aSrobert		    _RandomAccessIterator __out,
336*404b540aSrobert		    const _Distance __n)
337*404b540aSrobert    {
338*404b540aSrobert      _Distance __m = 0;
339*404b540aSrobert      _Distance __t = __n;
340*404b540aSrobert      for ( ; __first != __last && __m < __n; ++__m, ++__first)
341*404b540aSrobert	__out[__m] = *__first;
342*404b540aSrobert
343*404b540aSrobert      while (__first != __last)
344*404b540aSrobert	{
345*404b540aSrobert	  ++__t;
346*404b540aSrobert	  _Distance __M = std::rand() % (__t);
347*404b540aSrobert	  if (__M < __n)
348*404b540aSrobert	    __out[__M] = *__first;
349*404b540aSrobert	  ++__first;
350*404b540aSrobert	}
351*404b540aSrobert      return __out + __m;
352*404b540aSrobert    }
353*404b540aSrobert
354*404b540aSrobert  template<typename _InputIterator, typename _RandomAccessIterator,
355*404b540aSrobert	   typename _RandomNumberGenerator, typename _Distance>
356*404b540aSrobert    _RandomAccessIterator
357*404b540aSrobert    __random_sample(_InputIterator __first, _InputIterator __last,
358*404b540aSrobert		    _RandomAccessIterator __out,
359*404b540aSrobert		    _RandomNumberGenerator& __rand,
360*404b540aSrobert		    const _Distance __n)
361*404b540aSrobert    {
362*404b540aSrobert      // concept requirements
363*404b540aSrobert      __glibcxx_function_requires(_UnaryFunctionConcept<
364*404b540aSrobert	    _RandomNumberGenerator, _Distance, _Distance>)
365*404b540aSrobert
366*404b540aSrobert      _Distance __m = 0;
367*404b540aSrobert      _Distance __t = __n;
368*404b540aSrobert      for ( ; __first != __last && __m < __n; ++__m, ++__first)
369*404b540aSrobert	__out[__m] = *__first;
370*404b540aSrobert
371*404b540aSrobert      while (__first != __last)
372*404b540aSrobert	{
373*404b540aSrobert	  ++__t;
374*404b540aSrobert	  _Distance __M = __rand(__t);
375*404b540aSrobert	  if (__M < __n)
376*404b540aSrobert	    __out[__M] = *__first;
377*404b540aSrobert	  ++__first;
378*404b540aSrobert	}
379*404b540aSrobert      return __out + __m;
380*404b540aSrobert    }
381*404b540aSrobert
382*404b540aSrobert  /**
383*404b540aSrobert   *  This is an SGI extension.
384*404b540aSrobert   *  @ingroup SGIextensions
385*404b540aSrobert   *  @doctodo
386*404b540aSrobert  */
387*404b540aSrobert  template<typename _InputIterator, typename _RandomAccessIterator>
388*404b540aSrobert    inline _RandomAccessIterator
389*404b540aSrobert    random_sample(_InputIterator __first, _InputIterator __last,
390*404b540aSrobert		  _RandomAccessIterator __out_first,
391*404b540aSrobert		  _RandomAccessIterator __out_last)
392*404b540aSrobert    {
393*404b540aSrobert      // concept requirements
394*404b540aSrobert      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
395*404b540aSrobert      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
396*404b540aSrobert	    _RandomAccessIterator>)
397*404b540aSrobert      __glibcxx_requires_valid_range(__first, __last);
398*404b540aSrobert      __glibcxx_requires_valid_range(__out_first, __out_last);
399*404b540aSrobert
400*404b540aSrobert      return __random_sample(__first, __last,
401*404b540aSrobert			     __out_first, __out_last - __out_first);
402*404b540aSrobert    }
403*404b540aSrobert
404*404b540aSrobert  /**
405*404b540aSrobert   *  This is an SGI extension.
406*404b540aSrobert   *  @ingroup SGIextensions
407*404b540aSrobert   *  @doctodo
408*404b540aSrobert  */
409*404b540aSrobert  template<typename _InputIterator, typename _RandomAccessIterator,
410*404b540aSrobert	   typename _RandomNumberGenerator>
411*404b540aSrobert    inline _RandomAccessIterator
412*404b540aSrobert    random_sample(_InputIterator __first, _InputIterator __last,
413*404b540aSrobert		  _RandomAccessIterator __out_first,
414*404b540aSrobert		  _RandomAccessIterator __out_last,
415*404b540aSrobert		  _RandomNumberGenerator& __rand)
416*404b540aSrobert    {
417*404b540aSrobert      // concept requirements
418*404b540aSrobert      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
419*404b540aSrobert      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
420*404b540aSrobert	    _RandomAccessIterator>)
421*404b540aSrobert      __glibcxx_requires_valid_range(__first, __last);
422*404b540aSrobert      __glibcxx_requires_valid_range(__out_first, __out_last);
423*404b540aSrobert
424*404b540aSrobert      return __random_sample(__first, __last,
425*404b540aSrobert			     __out_first, __rand,
426*404b540aSrobert			     __out_last - __out_first);
427*404b540aSrobert    }
428*404b540aSrobert
429*404b540aSrobert  /**
430*404b540aSrobert   *  This is an SGI extension.
431*404b540aSrobert   *  @ingroup SGIextensions
432*404b540aSrobert   *  @doctodo
433*404b540aSrobert  */
434*404b540aSrobert  template<typename _RandomAccessIterator>
435*404b540aSrobert    inline bool
436*404b540aSrobert    is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
437*404b540aSrobert    {
438*404b540aSrobert      // concept requirements
439*404b540aSrobert      __glibcxx_function_requires(_RandomAccessIteratorConcept<
440*404b540aSrobert				  _RandomAccessIterator>)
441*404b540aSrobert      __glibcxx_function_requires(_LessThanComparableConcept<
442*404b540aSrobert	    typename iterator_traits<_RandomAccessIterator>::value_type>)
443*404b540aSrobert      __glibcxx_requires_valid_range(__first, __last);
444*404b540aSrobert
445*404b540aSrobert      return std::__is_heap(__first, __last - __first);
446*404b540aSrobert    }
447*404b540aSrobert
448*404b540aSrobert  /**
449*404b540aSrobert   *  This is an SGI extension.
450*404b540aSrobert   *  @ingroup SGIextensions
451*404b540aSrobert   *  @doctodo
452*404b540aSrobert  */
453*404b540aSrobert  template<typename _RandomAccessIterator, typename _StrictWeakOrdering>
454*404b540aSrobert    inline bool
455*404b540aSrobert    is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
456*404b540aSrobert	    _StrictWeakOrdering __comp)
457*404b540aSrobert    {
458*404b540aSrobert      // concept requirements
459*404b540aSrobert      __glibcxx_function_requires(_RandomAccessIteratorConcept<
460*404b540aSrobert				  _RandomAccessIterator>)
461*404b540aSrobert      __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering,
462*404b540aSrobert	    typename iterator_traits<_RandomAccessIterator>::value_type,
463*404b540aSrobert	    typename iterator_traits<_RandomAccessIterator>::value_type>)
464*404b540aSrobert      __glibcxx_requires_valid_range(__first, __last);
465*404b540aSrobert
466*404b540aSrobert      return std::__is_heap(__first, __comp, __last - __first);
467*404b540aSrobert    }
468*404b540aSrobert
469*404b540aSrobert  // is_sorted, a predicated testing whether a range is sorted in
470*404b540aSrobert  // nondescending order.  This is an extension, not part of the C++
471*404b540aSrobert  // standard.
472*404b540aSrobert
473*404b540aSrobert  /**
474*404b540aSrobert   *  This is an SGI extension.
475*404b540aSrobert   *  @ingroup SGIextensions
476*404b540aSrobert   *  @doctodo
477*404b540aSrobert  */
478*404b540aSrobert  template<typename _ForwardIterator>
479*404b540aSrobert    bool
480*404b540aSrobert    is_sorted(_ForwardIterator __first, _ForwardIterator __last)
481*404b540aSrobert    {
482*404b540aSrobert      // concept requirements
483*404b540aSrobert      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
484*404b540aSrobert      __glibcxx_function_requires(_LessThanComparableConcept<
485*404b540aSrobert	    typename iterator_traits<_ForwardIterator>::value_type>)
486*404b540aSrobert      __glibcxx_requires_valid_range(__first, __last);
487*404b540aSrobert
488*404b540aSrobert      if (__first == __last)
489*404b540aSrobert	return true;
490*404b540aSrobert
491*404b540aSrobert      _ForwardIterator __next = __first;
492*404b540aSrobert      for (++__next; __next != __last; __first = __next, ++__next)
493*404b540aSrobert	if (*__next < *__first)
494*404b540aSrobert	  return false;
495*404b540aSrobert      return true;
496*404b540aSrobert    }
497*404b540aSrobert
498*404b540aSrobert  /**
499*404b540aSrobert   *  This is an SGI extension.
500*404b540aSrobert   *  @ingroup SGIextensions
501*404b540aSrobert   *  @doctodo
502*404b540aSrobert  */
503*404b540aSrobert  template<typename _ForwardIterator, typename _StrictWeakOrdering>
504*404b540aSrobert    bool
505*404b540aSrobert    is_sorted(_ForwardIterator __first, _ForwardIterator __last,
506*404b540aSrobert	      _StrictWeakOrdering __comp)
507*404b540aSrobert    {
508*404b540aSrobert      // concept requirements
509*404b540aSrobert      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
510*404b540aSrobert      __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering,
511*404b540aSrobert	    typename iterator_traits<_ForwardIterator>::value_type,
512*404b540aSrobert	    typename iterator_traits<_ForwardIterator>::value_type>)
513*404b540aSrobert      __glibcxx_requires_valid_range(__first, __last);
514*404b540aSrobert
515*404b540aSrobert      if (__first == __last)
516*404b540aSrobert	return true;
517*404b540aSrobert
518*404b540aSrobert      _ForwardIterator __next = __first;
519*404b540aSrobert      for (++__next; __next != __last; __first = __next, ++__next)
520*404b540aSrobert	if (__comp(*__next, *__first))
521*404b540aSrobert	  return false;
522*404b540aSrobert      return true;
523*404b540aSrobert    }
524*404b540aSrobert
525*404b540aSrobert_GLIBCXX_END_NAMESPACE
526*404b540aSrobert
527*404b540aSrobert#endif /* _EXT_ALGORITHM */
528