136ac495dSmrg// Algorithm extensions -*- C++ -*- 236ac495dSmrg 3*8feb0f0bSmrg// Copyright (C) 2001-2020 Free Software Foundation, Inc. 436ac495dSmrg// 536ac495dSmrg// This file is part of the GNU ISO C++ Library. This library is free 636ac495dSmrg// software; you can redistribute it and/or modify it under the 736ac495dSmrg// terms of the GNU General Public License as published by the 836ac495dSmrg// Free Software Foundation; either version 3, or (at your option) 936ac495dSmrg// any later version. 1036ac495dSmrg 1136ac495dSmrg// This library is distributed in the hope that it will be useful, 1236ac495dSmrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 1336ac495dSmrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1436ac495dSmrg// GNU General Public License for more details. 1536ac495dSmrg 1636ac495dSmrg// Under Section 7 of GPL version 3, you are granted additional 1736ac495dSmrg// permissions described in the GCC Runtime Library Exception, version 1836ac495dSmrg// 3.1, as published by the Free Software Foundation. 1936ac495dSmrg 2036ac495dSmrg// You should have received a copy of the GNU General Public License and 2136ac495dSmrg// a copy of the GCC Runtime Library Exception along with this program; 2236ac495dSmrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2336ac495dSmrg// <http://www.gnu.org/licenses/>. 2436ac495dSmrg 2536ac495dSmrg/* 2636ac495dSmrg * 2736ac495dSmrg * Copyright (c) 1994 2836ac495dSmrg * Hewlett-Packard Company 2936ac495dSmrg * 3036ac495dSmrg * Permission to use, copy, modify, distribute and sell this software 3136ac495dSmrg * and its documentation for any purpose is hereby granted without fee, 3236ac495dSmrg * provided that the above copyright notice appear in all copies and 3336ac495dSmrg * that both that copyright notice and this permission notice appear 3436ac495dSmrg * in supporting documentation. Hewlett-Packard Company makes no 3536ac495dSmrg * representations about the suitability of this software for any 3636ac495dSmrg * purpose. It is provided "as is" without express or implied warranty. 3736ac495dSmrg * 3836ac495dSmrg * 3936ac495dSmrg * Copyright (c) 1996 4036ac495dSmrg * Silicon Graphics Computer Systems, Inc. 4136ac495dSmrg * 4236ac495dSmrg * Permission to use, copy, modify, distribute and sell this software 4336ac495dSmrg * and its documentation for any purpose is hereby granted without fee, 4436ac495dSmrg * provided that the above copyright notice appear in all copies and 4536ac495dSmrg * that both that copyright notice and this permission notice appear 4636ac495dSmrg * in supporting documentation. Silicon Graphics makes no 4736ac495dSmrg * representations about the suitability of this software for any 4836ac495dSmrg * purpose. It is provided "as is" without express or implied warranty. 4936ac495dSmrg */ 5036ac495dSmrg 5136ac495dSmrg/** @file ext/algorithm 5236ac495dSmrg * This file is a GNU extension to the Standard C++ Library (possibly 5336ac495dSmrg * containing extensions from the HP/SGI STL subset). 5436ac495dSmrg */ 5536ac495dSmrg 5636ac495dSmrg#ifndef _EXT_ALGORITHM 5736ac495dSmrg#define _EXT_ALGORITHM 1 5836ac495dSmrg 5936ac495dSmrg#pragma GCC system_header 6036ac495dSmrg 6136ac495dSmrg#include <algorithm> 6236ac495dSmrg 6336ac495dSmrgnamespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 6436ac495dSmrg{ 6536ac495dSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 6636ac495dSmrg 6736ac495dSmrg //-------------------------------------------------- 6836ac495dSmrg // copy_n (not part of the C++ standard) 6936ac495dSmrg 7036ac495dSmrg template<typename _InputIterator, typename _Size, typename _OutputIterator> 71*8feb0f0bSmrg std::pair<_InputIterator, _OutputIterator> 7236ac495dSmrg __copy_n(_InputIterator __first, _Size __count, 7336ac495dSmrg _OutputIterator __result, 74*8feb0f0bSmrg std::input_iterator_tag) 7536ac495dSmrg { 7636ac495dSmrg for ( ; __count > 0; --__count) 7736ac495dSmrg { 7836ac495dSmrg *__result = *__first; 7936ac495dSmrg ++__first; 8036ac495dSmrg ++__result; 8136ac495dSmrg } 82*8feb0f0bSmrg return std::pair<_InputIterator, _OutputIterator>(__first, __result); 8336ac495dSmrg } 8436ac495dSmrg 8536ac495dSmrg template<typename _RAIterator, typename _Size, typename _OutputIterator> 86*8feb0f0bSmrg inline std::pair<_RAIterator, _OutputIterator> 8736ac495dSmrg __copy_n(_RAIterator __first, _Size __count, 8836ac495dSmrg _OutputIterator __result, 89*8feb0f0bSmrg std::random_access_iterator_tag) 9036ac495dSmrg { 9136ac495dSmrg _RAIterator __last = __first + __count; 92*8feb0f0bSmrg return std::pair<_RAIterator, _OutputIterator>(__last, std::copy(__first, 9336ac495dSmrg __last, 9436ac495dSmrg __result)); 9536ac495dSmrg } 9636ac495dSmrg 9736ac495dSmrg /** 9836ac495dSmrg * @brief Copies the range [first,first+count) into [result,result+count). 9936ac495dSmrg * @param __first An input iterator. 10036ac495dSmrg * @param __count The number of elements to copy. 10136ac495dSmrg * @param __result An output iterator. 10236ac495dSmrg * @return A std::pair composed of first+count and result+count. 10336ac495dSmrg * 10436ac495dSmrg * This is an SGI extension. 10536ac495dSmrg * This inline function will boil down to a call to @c memmove whenever 10636ac495dSmrg * possible. Failing that, if random access iterators are passed, then the 10736ac495dSmrg * loop count will be known (and therefore a candidate for compiler 10836ac495dSmrg * optimizations such as unrolling). 10936ac495dSmrg * @ingroup SGIextensions 11036ac495dSmrg */ 11136ac495dSmrg template<typename _InputIterator, typename _Size, typename _OutputIterator> 112*8feb0f0bSmrg inline std::pair<_InputIterator, _OutputIterator> 11336ac495dSmrg copy_n(_InputIterator __first, _Size __count, _OutputIterator __result) 11436ac495dSmrg { 11536ac495dSmrg // concept requirements 11636ac495dSmrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 11736ac495dSmrg __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 118*8feb0f0bSmrg typename std::iterator_traits<_InputIterator>::value_type>) 11936ac495dSmrg 12036ac495dSmrg return __gnu_cxx::__copy_n(__first, __count, __result, 12136ac495dSmrg std::__iterator_category(__first)); 12236ac495dSmrg } 12336ac495dSmrg 12436ac495dSmrg template<typename _InputIterator1, typename _InputIterator2> 12536ac495dSmrg int 12636ac495dSmrg __lexicographical_compare_3way(_InputIterator1 __first1, 12736ac495dSmrg _InputIterator1 __last1, 12836ac495dSmrg _InputIterator2 __first2, 12936ac495dSmrg _InputIterator2 __last2) 13036ac495dSmrg { 13136ac495dSmrg while (__first1 != __last1 && __first2 != __last2) 13236ac495dSmrg { 13336ac495dSmrg if (*__first1 < *__first2) 13436ac495dSmrg return -1; 13536ac495dSmrg if (*__first2 < *__first1) 13636ac495dSmrg return 1; 13736ac495dSmrg ++__first1; 13836ac495dSmrg ++__first2; 13936ac495dSmrg } 14036ac495dSmrg if (__first2 == __last2) 14136ac495dSmrg return !(__first1 == __last1); 14236ac495dSmrg else 14336ac495dSmrg return -1; 14436ac495dSmrg } 14536ac495dSmrg 14636ac495dSmrg inline int 14736ac495dSmrg __lexicographical_compare_3way(const unsigned char* __first1, 14836ac495dSmrg const unsigned char* __last1, 14936ac495dSmrg const unsigned char* __first2, 15036ac495dSmrg const unsigned char* __last2) 15136ac495dSmrg { 152*8feb0f0bSmrg const std::ptrdiff_t __len1 = __last1 - __first1; 153*8feb0f0bSmrg const std::ptrdiff_t __len2 = __last2 - __first2; 15436ac495dSmrg const int __result = __builtin_memcmp(__first1, __first2, 155*8feb0f0bSmrg (std::min)(__len1, __len2)); 15636ac495dSmrg return __result != 0 ? __result 15736ac495dSmrg : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); 15836ac495dSmrg } 15936ac495dSmrg 16036ac495dSmrg inline int 16136ac495dSmrg __lexicographical_compare_3way(const char* __first1, const char* __last1, 16236ac495dSmrg const char* __first2, const char* __last2) 16336ac495dSmrg { 16436ac495dSmrg#if CHAR_MAX == SCHAR_MAX 16536ac495dSmrg return __lexicographical_compare_3way((const signed char*) __first1, 16636ac495dSmrg (const signed char*) __last1, 16736ac495dSmrg (const signed char*) __first2, 16836ac495dSmrg (const signed char*) __last2); 16936ac495dSmrg#else 17036ac495dSmrg return __lexicographical_compare_3way((const unsigned char*) __first1, 17136ac495dSmrg (const unsigned char*) __last1, 17236ac495dSmrg (const unsigned char*) __first2, 17336ac495dSmrg (const unsigned char*) __last2); 17436ac495dSmrg#endif 17536ac495dSmrg } 17636ac495dSmrg 17736ac495dSmrg /** 17836ac495dSmrg * @brief @c memcmp on steroids. 17936ac495dSmrg * @param __first1 An input iterator. 18036ac495dSmrg * @param __last1 An input iterator. 18136ac495dSmrg * @param __first2 An input iterator. 18236ac495dSmrg * @param __last2 An input iterator. 18336ac495dSmrg * @return An int, as with @c memcmp. 18436ac495dSmrg * 18536ac495dSmrg * The return value will be less than zero if the first range is 18636ac495dSmrg * <em>lexigraphically less than</em> the second, greater than zero 18736ac495dSmrg * if the second range is <em>lexigraphically less than</em> the 18836ac495dSmrg * first, and zero otherwise. 18936ac495dSmrg * This is an SGI extension. 19036ac495dSmrg * @ingroup SGIextensions 19136ac495dSmrg */ 19236ac495dSmrg template<typename _InputIterator1, typename _InputIterator2> 19336ac495dSmrg int 19436ac495dSmrg lexicographical_compare_3way(_InputIterator1 __first1, 19536ac495dSmrg _InputIterator1 __last1, 19636ac495dSmrg _InputIterator2 __first2, 19736ac495dSmrg _InputIterator2 __last2) 19836ac495dSmrg { 19936ac495dSmrg // concept requirements 20036ac495dSmrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 20136ac495dSmrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 20236ac495dSmrg __glibcxx_function_requires(_LessThanComparableConcept< 203*8feb0f0bSmrg typename std::iterator_traits<_InputIterator1>::value_type>) 20436ac495dSmrg __glibcxx_function_requires(_LessThanComparableConcept< 205*8feb0f0bSmrg typename std::iterator_traits<_InputIterator2>::value_type>) 20636ac495dSmrg __glibcxx_requires_valid_range(__first1, __last1); 20736ac495dSmrg __glibcxx_requires_valid_range(__first2, __last2); 20836ac495dSmrg 20936ac495dSmrg return __lexicographical_compare_3way(__first1, __last1, __first2, 21036ac495dSmrg __last2); 21136ac495dSmrg } 21236ac495dSmrg 21336ac495dSmrg // count and count_if: this version, whose return type is void, was present 21436ac495dSmrg // in the HP STL, and is retained as an extension for backward compatibility. 21536ac495dSmrg template<typename _InputIterator, typename _Tp, typename _Size> 21636ac495dSmrg void 21736ac495dSmrg count(_InputIterator __first, _InputIterator __last, 21836ac495dSmrg const _Tp& __value, 21936ac495dSmrg _Size& __n) 22036ac495dSmrg { 22136ac495dSmrg // concept requirements 22236ac495dSmrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 22336ac495dSmrg __glibcxx_function_requires(_EqualityComparableConcept< 224*8feb0f0bSmrg typename std::iterator_traits<_InputIterator>::value_type >) 22536ac495dSmrg __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) 22636ac495dSmrg __glibcxx_requires_valid_range(__first, __last); 22736ac495dSmrg 22836ac495dSmrg for ( ; __first != __last; ++__first) 22936ac495dSmrg if (*__first == __value) 23036ac495dSmrg ++__n; 23136ac495dSmrg } 23236ac495dSmrg 23336ac495dSmrg template<typename _InputIterator, typename _Predicate, typename _Size> 23436ac495dSmrg void 23536ac495dSmrg count_if(_InputIterator __first, _InputIterator __last, 23636ac495dSmrg _Predicate __pred, 23736ac495dSmrg _Size& __n) 23836ac495dSmrg { 23936ac495dSmrg // concept requirements 24036ac495dSmrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 24136ac495dSmrg __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 242*8feb0f0bSmrg typename std::iterator_traits<_InputIterator>::value_type>) 24336ac495dSmrg __glibcxx_requires_valid_range(__first, __last); 24436ac495dSmrg 24536ac495dSmrg for ( ; __first != __last; ++__first) 24636ac495dSmrg if (__pred(*__first)) 24736ac495dSmrg ++__n; 24836ac495dSmrg } 24936ac495dSmrg 25036ac495dSmrg // random_sample and random_sample_n (extensions, not part of the standard). 25136ac495dSmrg 25236ac495dSmrg /** 25336ac495dSmrg * This is an SGI extension. 25436ac495dSmrg * @ingroup SGIextensions 25536ac495dSmrg * @doctodo 25636ac495dSmrg */ 25736ac495dSmrg template<typename _ForwardIterator, typename _OutputIterator, 25836ac495dSmrg typename _Distance> 25936ac495dSmrg _OutputIterator 26036ac495dSmrg random_sample_n(_ForwardIterator __first, _ForwardIterator __last, 26136ac495dSmrg _OutputIterator __out, const _Distance __n) 26236ac495dSmrg { 26336ac495dSmrg // concept requirements 26436ac495dSmrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 26536ac495dSmrg __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 266*8feb0f0bSmrg typename std::iterator_traits<_ForwardIterator>::value_type>) 26736ac495dSmrg __glibcxx_requires_valid_range(__first, __last); 26836ac495dSmrg 26936ac495dSmrg _Distance __remaining = std::distance(__first, __last); 270*8feb0f0bSmrg _Distance __m = (std::min)(__n, __remaining); 27136ac495dSmrg 27236ac495dSmrg while (__m > 0) 27336ac495dSmrg { 27436ac495dSmrg if ((std::rand() % __remaining) < __m) 27536ac495dSmrg { 27636ac495dSmrg *__out = *__first; 27736ac495dSmrg ++__out; 27836ac495dSmrg --__m; 27936ac495dSmrg } 28036ac495dSmrg --__remaining; 28136ac495dSmrg ++__first; 28236ac495dSmrg } 28336ac495dSmrg return __out; 28436ac495dSmrg } 28536ac495dSmrg 28636ac495dSmrg /** 28736ac495dSmrg * This is an SGI extension. 28836ac495dSmrg * @ingroup SGIextensions 28936ac495dSmrg * @doctodo 29036ac495dSmrg */ 29136ac495dSmrg template<typename _ForwardIterator, typename _OutputIterator, 29236ac495dSmrg typename _Distance, typename _RandomNumberGenerator> 29336ac495dSmrg _OutputIterator 29436ac495dSmrg random_sample_n(_ForwardIterator __first, _ForwardIterator __last, 29536ac495dSmrg _OutputIterator __out, const _Distance __n, 29636ac495dSmrg _RandomNumberGenerator& __rand) 29736ac495dSmrg { 29836ac495dSmrg // concept requirements 29936ac495dSmrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 30036ac495dSmrg __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 301*8feb0f0bSmrg typename std::iterator_traits<_ForwardIterator>::value_type>) 30236ac495dSmrg __glibcxx_function_requires(_UnaryFunctionConcept< 30336ac495dSmrg _RandomNumberGenerator, _Distance, _Distance>) 30436ac495dSmrg __glibcxx_requires_valid_range(__first, __last); 30536ac495dSmrg 30636ac495dSmrg _Distance __remaining = std::distance(__first, __last); 307*8feb0f0bSmrg _Distance __m = (std::min)(__n, __remaining); 30836ac495dSmrg 30936ac495dSmrg while (__m > 0) 31036ac495dSmrg { 31136ac495dSmrg if (__rand(__remaining) < __m) 31236ac495dSmrg { 31336ac495dSmrg *__out = *__first; 31436ac495dSmrg ++__out; 31536ac495dSmrg --__m; 31636ac495dSmrg } 31736ac495dSmrg --__remaining; 31836ac495dSmrg ++__first; 31936ac495dSmrg } 32036ac495dSmrg return __out; 32136ac495dSmrg } 32236ac495dSmrg 32336ac495dSmrg template<typename _InputIterator, typename _RandomAccessIterator, 32436ac495dSmrg typename _Distance> 32536ac495dSmrg _RandomAccessIterator 32636ac495dSmrg __random_sample(_InputIterator __first, _InputIterator __last, 32736ac495dSmrg _RandomAccessIterator __out, 32836ac495dSmrg const _Distance __n) 32936ac495dSmrg { 33036ac495dSmrg _Distance __m = 0; 33136ac495dSmrg _Distance __t = __n; 33236ac495dSmrg for ( ; __first != __last && __m < __n; ++__m, ++__first) 33336ac495dSmrg __out[__m] = *__first; 33436ac495dSmrg 33536ac495dSmrg while (__first != __last) 33636ac495dSmrg { 33736ac495dSmrg ++__t; 33836ac495dSmrg _Distance __M = std::rand() % (__t); 33936ac495dSmrg if (__M < __n) 34036ac495dSmrg __out[__M] = *__first; 34136ac495dSmrg ++__first; 34236ac495dSmrg } 34336ac495dSmrg return __out + __m; 34436ac495dSmrg } 34536ac495dSmrg 34636ac495dSmrg template<typename _InputIterator, typename _RandomAccessIterator, 34736ac495dSmrg typename _RandomNumberGenerator, typename _Distance> 34836ac495dSmrg _RandomAccessIterator 34936ac495dSmrg __random_sample(_InputIterator __first, _InputIterator __last, 35036ac495dSmrg _RandomAccessIterator __out, 35136ac495dSmrg _RandomNumberGenerator& __rand, 35236ac495dSmrg const _Distance __n) 35336ac495dSmrg { 35436ac495dSmrg // concept requirements 35536ac495dSmrg __glibcxx_function_requires(_UnaryFunctionConcept< 35636ac495dSmrg _RandomNumberGenerator, _Distance, _Distance>) 35736ac495dSmrg 35836ac495dSmrg _Distance __m = 0; 35936ac495dSmrg _Distance __t = __n; 36036ac495dSmrg for ( ; __first != __last && __m < __n; ++__m, ++__first) 36136ac495dSmrg __out[__m] = *__first; 36236ac495dSmrg 36336ac495dSmrg while (__first != __last) 36436ac495dSmrg { 36536ac495dSmrg ++__t; 36636ac495dSmrg _Distance __M = __rand(__t); 36736ac495dSmrg if (__M < __n) 36836ac495dSmrg __out[__M] = *__first; 36936ac495dSmrg ++__first; 37036ac495dSmrg } 37136ac495dSmrg return __out + __m; 37236ac495dSmrg } 37336ac495dSmrg 37436ac495dSmrg /** 37536ac495dSmrg * This is an SGI extension. 37636ac495dSmrg * @ingroup SGIextensions 37736ac495dSmrg * @doctodo 37836ac495dSmrg */ 37936ac495dSmrg template<typename _InputIterator, typename _RandomAccessIterator> 38036ac495dSmrg inline _RandomAccessIterator 38136ac495dSmrg random_sample(_InputIterator __first, _InputIterator __last, 38236ac495dSmrg _RandomAccessIterator __out_first, 38336ac495dSmrg _RandomAccessIterator __out_last) 38436ac495dSmrg { 38536ac495dSmrg // concept requirements 38636ac495dSmrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 38736ac495dSmrg __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 38836ac495dSmrg _RandomAccessIterator>) 38936ac495dSmrg __glibcxx_requires_valid_range(__first, __last); 39036ac495dSmrg __glibcxx_requires_valid_range(__out_first, __out_last); 39136ac495dSmrg 39236ac495dSmrg return __random_sample(__first, __last, 39336ac495dSmrg __out_first, __out_last - __out_first); 39436ac495dSmrg } 39536ac495dSmrg 39636ac495dSmrg /** 39736ac495dSmrg * This is an SGI extension. 39836ac495dSmrg * @ingroup SGIextensions 39936ac495dSmrg * @doctodo 40036ac495dSmrg */ 40136ac495dSmrg template<typename _InputIterator, typename _RandomAccessIterator, 40236ac495dSmrg typename _RandomNumberGenerator> 40336ac495dSmrg inline _RandomAccessIterator 40436ac495dSmrg random_sample(_InputIterator __first, _InputIterator __last, 40536ac495dSmrg _RandomAccessIterator __out_first, 40636ac495dSmrg _RandomAccessIterator __out_last, 40736ac495dSmrg _RandomNumberGenerator& __rand) 40836ac495dSmrg { 40936ac495dSmrg // concept requirements 41036ac495dSmrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 41136ac495dSmrg __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 41236ac495dSmrg _RandomAccessIterator>) 41336ac495dSmrg __glibcxx_requires_valid_range(__first, __last); 41436ac495dSmrg __glibcxx_requires_valid_range(__out_first, __out_last); 41536ac495dSmrg 41636ac495dSmrg return __random_sample(__first, __last, 41736ac495dSmrg __out_first, __rand, 41836ac495dSmrg __out_last - __out_first); 41936ac495dSmrg } 42036ac495dSmrg 42136ac495dSmrg#if __cplusplus >= 201103L 42236ac495dSmrg using std::is_heap; 42336ac495dSmrg#else 42436ac495dSmrg /** 42536ac495dSmrg * This is an SGI extension. 42636ac495dSmrg * @ingroup SGIextensions 42736ac495dSmrg * @doctodo 42836ac495dSmrg */ 42936ac495dSmrg template<typename _RandomAccessIterator> 43036ac495dSmrg inline bool 43136ac495dSmrg is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 43236ac495dSmrg { 43336ac495dSmrg // concept requirements 43436ac495dSmrg __glibcxx_function_requires(_RandomAccessIteratorConcept< 43536ac495dSmrg _RandomAccessIterator>) 43636ac495dSmrg __glibcxx_function_requires(_LessThanComparableConcept< 437*8feb0f0bSmrg typename std::iterator_traits<_RandomAccessIterator>::value_type>) 43836ac495dSmrg __glibcxx_requires_valid_range(__first, __last); 43936ac495dSmrg 44036ac495dSmrg return std::__is_heap(__first, __last - __first); 44136ac495dSmrg } 44236ac495dSmrg 44336ac495dSmrg /** 44436ac495dSmrg * This is an SGI extension. 44536ac495dSmrg * @ingroup SGIextensions 44636ac495dSmrg * @doctodo 44736ac495dSmrg */ 44836ac495dSmrg template<typename _RandomAccessIterator, typename _StrictWeakOrdering> 44936ac495dSmrg inline bool 45036ac495dSmrg is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 45136ac495dSmrg _StrictWeakOrdering __comp) 45236ac495dSmrg { 45336ac495dSmrg // concept requirements 45436ac495dSmrg __glibcxx_function_requires(_RandomAccessIteratorConcept< 45536ac495dSmrg _RandomAccessIterator>) 45636ac495dSmrg __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, 457*8feb0f0bSmrg typename std::iterator_traits<_RandomAccessIterator>::value_type, 458*8feb0f0bSmrg typename std::iterator_traits<_RandomAccessIterator>::value_type>) 45936ac495dSmrg __glibcxx_requires_valid_range(__first, __last); 46036ac495dSmrg 46136ac495dSmrg return std::__is_heap(__first, __comp, __last - __first); 46236ac495dSmrg } 46336ac495dSmrg#endif 46436ac495dSmrg 46536ac495dSmrg#if __cplusplus >= 201103L 46636ac495dSmrg using std::is_sorted; 46736ac495dSmrg#else 46836ac495dSmrg // is_sorted, a predicated testing whether a range is sorted in 46936ac495dSmrg // nondescending order. This is an extension, not part of the C++ 47036ac495dSmrg // standard. 47136ac495dSmrg 47236ac495dSmrg /** 47336ac495dSmrg * This is an SGI extension. 47436ac495dSmrg * @ingroup SGIextensions 47536ac495dSmrg * @doctodo 47636ac495dSmrg */ 47736ac495dSmrg template<typename _ForwardIterator> 47836ac495dSmrg bool 47936ac495dSmrg is_sorted(_ForwardIterator __first, _ForwardIterator __last) 48036ac495dSmrg { 48136ac495dSmrg // concept requirements 48236ac495dSmrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 48336ac495dSmrg __glibcxx_function_requires(_LessThanComparableConcept< 484*8feb0f0bSmrg typename std::iterator_traits<_ForwardIterator>::value_type>) 48536ac495dSmrg __glibcxx_requires_valid_range(__first, __last); 48636ac495dSmrg 48736ac495dSmrg if (__first == __last) 48836ac495dSmrg return true; 48936ac495dSmrg 49036ac495dSmrg _ForwardIterator __next = __first; 49136ac495dSmrg for (++__next; __next != __last; __first = __next, ++__next) 49236ac495dSmrg if (*__next < *__first) 49336ac495dSmrg return false; 49436ac495dSmrg return true; 49536ac495dSmrg } 49636ac495dSmrg 49736ac495dSmrg /** 49836ac495dSmrg * This is an SGI extension. 49936ac495dSmrg * @ingroup SGIextensions 50036ac495dSmrg * @doctodo 50136ac495dSmrg */ 50236ac495dSmrg template<typename _ForwardIterator, typename _StrictWeakOrdering> 50336ac495dSmrg bool 50436ac495dSmrg is_sorted(_ForwardIterator __first, _ForwardIterator __last, 50536ac495dSmrg _StrictWeakOrdering __comp) 50636ac495dSmrg { 50736ac495dSmrg // concept requirements 50836ac495dSmrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 50936ac495dSmrg __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, 510*8feb0f0bSmrg typename std::iterator_traits<_ForwardIterator>::value_type, 511*8feb0f0bSmrg typename std::iterator_traits<_ForwardIterator>::value_type>) 51236ac495dSmrg __glibcxx_requires_valid_range(__first, __last); 51336ac495dSmrg 51436ac495dSmrg if (__first == __last) 51536ac495dSmrg return true; 51636ac495dSmrg 51736ac495dSmrg _ForwardIterator __next = __first; 51836ac495dSmrg for (++__next; __next != __last; __first = __next, ++__next) 51936ac495dSmrg if (__comp(*__next, *__first)) 52036ac495dSmrg return false; 52136ac495dSmrg return true; 52236ac495dSmrg } 52336ac495dSmrg#endif // C++11 52436ac495dSmrg 52536ac495dSmrg /** 52636ac495dSmrg * @brief Find the median of three values. 52736ac495dSmrg * @param __a A value. 52836ac495dSmrg * @param __b A value. 52936ac495dSmrg * @param __c A value. 53036ac495dSmrg * @return One of @p a, @p b or @p c. 53136ac495dSmrg * 53236ac495dSmrg * If @c {l,m,n} is some convolution of @p {a,b,c} such that @c l<=m<=n 53336ac495dSmrg * then the value returned will be @c m. 53436ac495dSmrg * This is an SGI extension. 53536ac495dSmrg * @ingroup SGIextensions 53636ac495dSmrg */ 53736ac495dSmrg template<typename _Tp> 53836ac495dSmrg const _Tp& 53936ac495dSmrg __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) 54036ac495dSmrg { 54136ac495dSmrg // concept requirements 54236ac495dSmrg __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) 54336ac495dSmrg if (__a < __b) 54436ac495dSmrg if (__b < __c) 54536ac495dSmrg return __b; 54636ac495dSmrg else if (__a < __c) 54736ac495dSmrg return __c; 54836ac495dSmrg else 54936ac495dSmrg return __a; 55036ac495dSmrg else if (__a < __c) 55136ac495dSmrg return __a; 55236ac495dSmrg else if (__b < __c) 55336ac495dSmrg return __c; 55436ac495dSmrg else 55536ac495dSmrg return __b; 55636ac495dSmrg } 55736ac495dSmrg 55836ac495dSmrg /** 55936ac495dSmrg * @brief Find the median of three values using a predicate for comparison. 56036ac495dSmrg * @param __a A value. 56136ac495dSmrg * @param __b A value. 56236ac495dSmrg * @param __c A value. 56336ac495dSmrg * @param __comp A binary predicate. 56436ac495dSmrg * @return One of @p a, @p b or @p c. 56536ac495dSmrg * 56636ac495dSmrg * If @c {l,m,n} is some convolution of @p {a,b,c} such that @p comp(l,m) 56736ac495dSmrg * and @p comp(m,n) are both true then the value returned will be @c m. 56836ac495dSmrg * This is an SGI extension. 56936ac495dSmrg * @ingroup SGIextensions 57036ac495dSmrg */ 57136ac495dSmrg template<typename _Tp, typename _Compare> 57236ac495dSmrg const _Tp& 57336ac495dSmrg __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) 57436ac495dSmrg { 57536ac495dSmrg // concept requirements 57636ac495dSmrg __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool, 57736ac495dSmrg _Tp, _Tp>) 57836ac495dSmrg if (__comp(__a, __b)) 57936ac495dSmrg if (__comp(__b, __c)) 58036ac495dSmrg return __b; 58136ac495dSmrg else if (__comp(__a, __c)) 58236ac495dSmrg return __c; 58336ac495dSmrg else 58436ac495dSmrg return __a; 58536ac495dSmrg else if (__comp(__a, __c)) 58636ac495dSmrg return __a; 58736ac495dSmrg else if (__comp(__b, __c)) 58836ac495dSmrg return __c; 58936ac495dSmrg else 59036ac495dSmrg return __b; 59136ac495dSmrg } 59236ac495dSmrg 59336ac495dSmrg_GLIBCXX_END_NAMESPACE_VERSION 59436ac495dSmrg} // namespace 59536ac495dSmrg 59636ac495dSmrg#endif /* _EXT_ALGORITHM */ 597