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