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