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