100db7afdSDavid E. O'Brien// Algorithm extensions -*- C++ -*- 200db7afdSDavid E. O'Brien 3*f8a1b7d9SAlexander Kabaev// Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc. 400db7afdSDavid E. O'Brien// 500db7afdSDavid E. O'Brien// This file is part of the GNU ISO C++ Library. This library is free 600db7afdSDavid E. O'Brien// software; you can redistribute it and/or modify it under the 700db7afdSDavid E. O'Brien// terms of the GNU General Public License as published by the 800db7afdSDavid E. O'Brien// Free Software Foundation; either version 2, or (at your option) 900db7afdSDavid E. O'Brien// any later version. 1000db7afdSDavid E. O'Brien 1100db7afdSDavid E. O'Brien// This library is distributed in the hope that it will be useful, 1200db7afdSDavid E. O'Brien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1300db7afdSDavid E. O'Brien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1400db7afdSDavid E. O'Brien// GNU General Public License for more details. 1500db7afdSDavid E. O'Brien 1600db7afdSDavid E. O'Brien// You should have received a copy of the GNU General Public License along 1700db7afdSDavid E. O'Brien// with this library; see the file COPYING. If not, write to the Free 18*f8a1b7d9SAlexander Kabaev// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 1900db7afdSDavid E. O'Brien// USA. 2000db7afdSDavid E. O'Brien 2100db7afdSDavid E. O'Brien// As a special exception, you may use this file as part of a free software 2200db7afdSDavid E. O'Brien// library without restriction. Specifically, if other files instantiate 2300db7afdSDavid E. O'Brien// templates or use macros or inline functions from this file, or you compile 2400db7afdSDavid E. O'Brien// this file and link it with other files to produce an executable, this 2500db7afdSDavid E. O'Brien// file does not by itself cause the resulting executable to be covered by 2600db7afdSDavid E. O'Brien// the GNU General Public License. This exception does not however 2700db7afdSDavid E. O'Brien// invalidate any other reasons why the executable file might be covered by 2800db7afdSDavid E. O'Brien// the GNU General Public License. 2900db7afdSDavid E. O'Brien 3000db7afdSDavid E. O'Brien/* 3100db7afdSDavid E. O'Brien * 3200db7afdSDavid E. O'Brien * Copyright (c) 1994 3300db7afdSDavid E. O'Brien * Hewlett-Packard Company 3400db7afdSDavid E. O'Brien * 3500db7afdSDavid E. O'Brien * Permission to use, copy, modify, distribute and sell this software 3600db7afdSDavid E. O'Brien * and its documentation for any purpose is hereby granted without fee, 3700db7afdSDavid E. O'Brien * provided that the above copyright notice appear in all copies and 3800db7afdSDavid E. O'Brien * that both that copyright notice and this permission notice appear 3900db7afdSDavid E. O'Brien * in supporting documentation. Hewlett-Packard Company makes no 4000db7afdSDavid E. O'Brien * representations about the suitability of this software for any 4100db7afdSDavid E. O'Brien * purpose. It is provided "as is" without express or implied warranty. 4200db7afdSDavid E. O'Brien * 4300db7afdSDavid E. O'Brien * 4400db7afdSDavid E. O'Brien * Copyright (c) 1996 4500db7afdSDavid E. O'Brien * Silicon Graphics Computer Systems, Inc. 4600db7afdSDavid E. O'Brien * 4700db7afdSDavid E. O'Brien * Permission to use, copy, modify, distribute and sell this software 4800db7afdSDavid E. O'Brien * and its documentation for any purpose is hereby granted without fee, 4900db7afdSDavid E. O'Brien * provided that the above copyright notice appear in all copies and 5000db7afdSDavid E. O'Brien * that both that copyright notice and this permission notice appear 5100db7afdSDavid E. O'Brien * in supporting documentation. Silicon Graphics makes no 5200db7afdSDavid E. O'Brien * representations about the suitability of this software for any 5300db7afdSDavid E. O'Brien * purpose. It is provided "as is" without express or implied warranty. 5400db7afdSDavid E. O'Brien */ 5500db7afdSDavid E. O'Brien 5600db7afdSDavid E. O'Brien/** @file ext/algorithm 5700db7afdSDavid E. O'Brien * This file is a GNU extension to the Standard C++ Library (possibly 58*f8a1b7d9SAlexander Kabaev * containing extensions from the HP/SGI STL subset). 5900db7afdSDavid E. O'Brien */ 6000db7afdSDavid E. O'Brien 6100db7afdSDavid E. O'Brien#ifndef _EXT_ALGORITHM 62ffeaf689SAlexander Kabaev#define _EXT_ALGORITHM 1 6300db7afdSDavid E. O'Brien 6400db7afdSDavid E. O'Brien#pragma GCC system_header 65ffeaf689SAlexander Kabaev 6600db7afdSDavid E. O'Brien#include <algorithm> 6700db7afdSDavid E. O'Brien 68*f8a1b7d9SAlexander Kabaev_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 69*f8a1b7d9SAlexander Kabaev 7000db7afdSDavid E. O'Brien using std::ptrdiff_t; 7100db7afdSDavid E. O'Brien using std::min; 7200db7afdSDavid E. O'Brien using std::pair; 7300db7afdSDavid E. O'Brien using std::input_iterator_tag; 7400db7afdSDavid E. O'Brien using std::random_access_iterator_tag; 7500db7afdSDavid E. O'Brien using std::iterator_traits; 7600db7afdSDavid E. O'Brien 7700db7afdSDavid E. O'Brien //-------------------------------------------------- 7800db7afdSDavid E. O'Brien // copy_n (not part of the C++ standard) 7900db7afdSDavid E. O'Brien 80ffeaf689SAlexander Kabaev template<typename _InputIterator, typename _Size, typename _OutputIterator> 81ffeaf689SAlexander Kabaev pair<_InputIterator, _OutputIterator> 82ffeaf689SAlexander Kabaev __copy_n(_InputIterator __first, _Size __count, 83ffeaf689SAlexander Kabaev _OutputIterator __result, 8400db7afdSDavid E. O'Brien input_iterator_tag) 8500db7afdSDavid E. O'Brien { 86*f8a1b7d9SAlexander Kabaev for ( ; __count > 0; --__count) 87*f8a1b7d9SAlexander Kabaev { 8800db7afdSDavid E. O'Brien *__result = *__first; 8900db7afdSDavid E. O'Brien ++__first; 9000db7afdSDavid E. O'Brien ++__result; 9100db7afdSDavid E. O'Brien } 92ffeaf689SAlexander Kabaev return pair<_InputIterator, _OutputIterator>(__first, __result); 9300db7afdSDavid E. O'Brien } 9400db7afdSDavid E. O'Brien 95ffeaf689SAlexander Kabaev template<typename _RAIterator, typename _Size, typename _OutputIterator> 96ffeaf689SAlexander Kabaev inline pair<_RAIterator, _OutputIterator> 97ffeaf689SAlexander Kabaev __copy_n(_RAIterator __first, _Size __count, 98ffeaf689SAlexander Kabaev _OutputIterator __result, 9900db7afdSDavid E. O'Brien random_access_iterator_tag) 10000db7afdSDavid E. O'Brien { 101ffeaf689SAlexander Kabaev _RAIterator __last = __first + __count; 102*f8a1b7d9SAlexander Kabaev return pair<_RAIterator, _OutputIterator>(__last, std::copy(__first, 103*f8a1b7d9SAlexander Kabaev __last, 104*f8a1b7d9SAlexander Kabaev __result)); 10500db7afdSDavid E. O'Brien } 10600db7afdSDavid E. O'Brien 10700db7afdSDavid E. O'Brien /** 10800db7afdSDavid E. O'Brien * @brief Copies the range [first,first+count) into [result,result+count). 10900db7afdSDavid E. O'Brien * @param first An input iterator. 11000db7afdSDavid E. O'Brien * @param count The number of elements to copy. 11100db7afdSDavid E. O'Brien * @param result An output iterator. 11200db7afdSDavid E. O'Brien * @return A std::pair composed of first+count and result+count. 11300db7afdSDavid E. O'Brien * 11400db7afdSDavid E. O'Brien * This is an SGI extension. 11500db7afdSDavid E. O'Brien * This inline function will boil down to a call to @c memmove whenever 11600db7afdSDavid E. O'Brien * possible. Failing that, if random access iterators are passed, then the 11700db7afdSDavid E. O'Brien * loop count will be known (and therefore a candidate for compiler 11800db7afdSDavid E. O'Brien * optimizations such as unrolling). 11900db7afdSDavid E. O'Brien * @ingroup SGIextensions 12000db7afdSDavid E. O'Brien */ 121ffeaf689SAlexander Kabaev template<typename _InputIterator, typename _Size, typename _OutputIterator> 122ffeaf689SAlexander Kabaev inline pair<_InputIterator, _OutputIterator> 123ffeaf689SAlexander Kabaev copy_n(_InputIterator __first, _Size __count, _OutputIterator __result) 12400db7afdSDavid E. O'Brien { 12500db7afdSDavid E. O'Brien // concept requirements 126ffeaf689SAlexander Kabaev __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 127ffeaf689SAlexander Kabaev __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 128ffeaf689SAlexander Kabaev typename iterator_traits<_InputIterator>::value_type>) 12900db7afdSDavid E. O'Brien 13000db7afdSDavid E. O'Brien return __copy_n(__first, __count, __result, 13100db7afdSDavid E. O'Brien std::__iterator_category(__first)); 13200db7afdSDavid E. O'Brien } 13300db7afdSDavid E. O'Brien 134ffeaf689SAlexander Kabaev template<typename _InputIterator1, typename _InputIterator2> 13500db7afdSDavid E. O'Brien int 136*f8a1b7d9SAlexander Kabaev __lexicographical_compare_3way(_InputIterator1 __first1, 137*f8a1b7d9SAlexander Kabaev _InputIterator1 __last1, 138*f8a1b7d9SAlexander Kabaev _InputIterator2 __first2, 139*f8a1b7d9SAlexander Kabaev _InputIterator2 __last2) 14000db7afdSDavid E. O'Brien { 141*f8a1b7d9SAlexander Kabaev while (__first1 != __last1 && __first2 != __last2) 142*f8a1b7d9SAlexander Kabaev { 14300db7afdSDavid E. O'Brien if (*__first1 < *__first2) 14400db7afdSDavid E. O'Brien return -1; 14500db7afdSDavid E. O'Brien if (*__first2 < *__first1) 14600db7afdSDavid E. O'Brien return 1; 14700db7afdSDavid E. O'Brien ++__first1; 14800db7afdSDavid E. O'Brien ++__first2; 14900db7afdSDavid E. O'Brien } 150*f8a1b7d9SAlexander Kabaev if (__first2 == __last2) 15100db7afdSDavid E. O'Brien return !(__first1 == __last1); 152*f8a1b7d9SAlexander Kabaev else 15300db7afdSDavid E. O'Brien return -1; 15400db7afdSDavid E. O'Brien } 15500db7afdSDavid E. O'Brien 15600db7afdSDavid E. O'Brien inline int 15700db7afdSDavid E. O'Brien __lexicographical_compare_3way(const unsigned char* __first1, 15800db7afdSDavid E. O'Brien const unsigned char* __last1, 15900db7afdSDavid E. O'Brien const unsigned char* __first2, 16000db7afdSDavid E. O'Brien const unsigned char* __last2) 16100db7afdSDavid E. O'Brien { 16200db7afdSDavid E. O'Brien const ptrdiff_t __len1 = __last1 - __first1; 16300db7afdSDavid E. O'Brien const ptrdiff_t __len2 = __last2 - __first2; 16400db7afdSDavid E. O'Brien const int __result = std::memcmp(__first1, __first2, min(__len1, __len2)); 16500db7afdSDavid E. O'Brien return __result != 0 ? __result 16600db7afdSDavid E. O'Brien : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); 16700db7afdSDavid E. O'Brien } 16800db7afdSDavid E. O'Brien 16900db7afdSDavid E. O'Brien inline int 17000db7afdSDavid E. O'Brien __lexicographical_compare_3way(const char* __first1, const char* __last1, 17100db7afdSDavid E. O'Brien const char* __first2, const char* __last2) 17200db7afdSDavid E. O'Brien { 17300db7afdSDavid E. O'Brien#if CHAR_MAX == SCHAR_MAX 174*f8a1b7d9SAlexander Kabaev return __lexicographical_compare_3way((const signed char*) __first1, 17500db7afdSDavid E. O'Brien (const signed char*) __last1, 17600db7afdSDavid E. O'Brien (const signed char*) __first2, 17700db7afdSDavid E. O'Brien (const signed char*) __last2); 17800db7afdSDavid E. O'Brien#else 17900db7afdSDavid E. O'Brien return __lexicographical_compare_3way((const unsigned char*) __first1, 18000db7afdSDavid E. O'Brien (const unsigned char*) __last1, 18100db7afdSDavid E. O'Brien (const unsigned char*) __first2, 18200db7afdSDavid E. O'Brien (const unsigned char*) __last2); 18300db7afdSDavid E. O'Brien#endif 18400db7afdSDavid E. O'Brien } 18500db7afdSDavid E. O'Brien 18600db7afdSDavid E. O'Brien /** 18700db7afdSDavid E. O'Brien * @brief @c memcmp on steroids. 18800db7afdSDavid E. O'Brien * @param first1 An input iterator. 18900db7afdSDavid E. O'Brien * @param last1 An input iterator. 19000db7afdSDavid E. O'Brien * @param first2 An input iterator. 19100db7afdSDavid E. O'Brien * @param last2 An input iterator. 19200db7afdSDavid E. O'Brien * @return An int, as with @c memcmp. 19300db7afdSDavid E. O'Brien * 19400db7afdSDavid E. O'Brien * The return value will be less than zero if the first range is 19500db7afdSDavid E. O'Brien * "lexigraphically less than" the second, greater than zero if the second 19600db7afdSDavid E. O'Brien * range is "lexigraphically less than" the first, and zero otherwise. 19700db7afdSDavid E. O'Brien * This is an SGI extension. 19800db7afdSDavid E. O'Brien * @ingroup SGIextensions 19900db7afdSDavid E. O'Brien */ 200ffeaf689SAlexander Kabaev template<typename _InputIterator1, typename _InputIterator2> 20100db7afdSDavid E. O'Brien int 202*f8a1b7d9SAlexander Kabaev lexicographical_compare_3way(_InputIterator1 __first1, 203*f8a1b7d9SAlexander Kabaev _InputIterator1 __last1, 204*f8a1b7d9SAlexander Kabaev _InputIterator2 __first2, 205*f8a1b7d9SAlexander Kabaev _InputIterator2 __last2) 20600db7afdSDavid E. O'Brien { 20700db7afdSDavid E. O'Brien // concept requirements 208ffeaf689SAlexander Kabaev __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 209ffeaf689SAlexander Kabaev __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 210ffeaf689SAlexander Kabaev __glibcxx_function_requires(_LessThanComparableConcept< 211ffeaf689SAlexander Kabaev typename iterator_traits<_InputIterator1>::value_type>) 212ffeaf689SAlexander Kabaev __glibcxx_function_requires(_LessThanComparableConcept< 213ffeaf689SAlexander Kabaev typename iterator_traits<_InputIterator2>::value_type>) 214ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first1, __last1); 215ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first2, __last2); 21600db7afdSDavid E. O'Brien 217*f8a1b7d9SAlexander Kabaev return __lexicographical_compare_3way(__first1, __last1, __first2, 218*f8a1b7d9SAlexander Kabaev __last2); 21900db7afdSDavid E. O'Brien } 22000db7afdSDavid E. O'Brien 22100db7afdSDavid E. O'Brien // count and count_if: this version, whose return type is void, was present 22200db7afdSDavid E. O'Brien // in the HP STL, and is retained as an extension for backward compatibility. 223ffeaf689SAlexander Kabaev template<typename _InputIterator, typename _Tp, typename _Size> 22400db7afdSDavid E. O'Brien void 225ffeaf689SAlexander Kabaev count(_InputIterator __first, _InputIterator __last, 22600db7afdSDavid E. O'Brien const _Tp& __value, 22700db7afdSDavid E. O'Brien _Size& __n) 22800db7afdSDavid E. O'Brien { 22900db7afdSDavid E. O'Brien // concept requirements 230ffeaf689SAlexander Kabaev __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 231ffeaf689SAlexander Kabaev __glibcxx_function_requires(_EqualityComparableConcept< 232ffeaf689SAlexander Kabaev typename iterator_traits<_InputIterator>::value_type >) 233ffeaf689SAlexander Kabaev __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) 234ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first, __last); 235ffeaf689SAlexander Kabaev 23600db7afdSDavid E. O'Brien for ( ; __first != __last; ++__first) 23700db7afdSDavid E. O'Brien if (*__first == __value) 23800db7afdSDavid E. O'Brien ++__n; 23900db7afdSDavid E. O'Brien } 24000db7afdSDavid E. O'Brien 241ffeaf689SAlexander Kabaev template<typename _InputIterator, typename _Predicate, typename _Size> 24200db7afdSDavid E. O'Brien void 243ffeaf689SAlexander Kabaev count_if(_InputIterator __first, _InputIterator __last, 24400db7afdSDavid E. O'Brien _Predicate __pred, 24500db7afdSDavid E. O'Brien _Size& __n) 24600db7afdSDavid E. O'Brien { 24700db7afdSDavid E. O'Brien // concept requirements 248ffeaf689SAlexander Kabaev __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 249ffeaf689SAlexander Kabaev __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 250ffeaf689SAlexander Kabaev typename iterator_traits<_InputIterator>::value_type>) 251ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first, __last); 252ffeaf689SAlexander Kabaev 25300db7afdSDavid E. O'Brien for ( ; __first != __last; ++__first) 25400db7afdSDavid E. O'Brien if (__pred(*__first)) 25500db7afdSDavid E. O'Brien ++__n; 25600db7afdSDavid E. O'Brien } 25700db7afdSDavid E. O'Brien 25800db7afdSDavid E. O'Brien // random_sample and random_sample_n (extensions, not part of the standard). 25900db7afdSDavid E. O'Brien 260ca6500fcSAlexander Kabaev /** 261ca6500fcSAlexander Kabaev * This is an SGI extension. 262ca6500fcSAlexander Kabaev * @ingroup SGIextensions 263ca6500fcSAlexander Kabaev * @doctodo 264ca6500fcSAlexander Kabaev */ 265*f8a1b7d9SAlexander Kabaev template<typename _ForwardIterator, typename _OutputIterator, 266*f8a1b7d9SAlexander Kabaev typename _Distance> 267ffeaf689SAlexander Kabaev _OutputIterator 268ffeaf689SAlexander Kabaev random_sample_n(_ForwardIterator __first, _ForwardIterator __last, 269ffeaf689SAlexander Kabaev _OutputIterator __out, const _Distance __n) 27000db7afdSDavid E. O'Brien { 27100db7afdSDavid E. O'Brien // concept requirements 272ffeaf689SAlexander Kabaev __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 273ffeaf689SAlexander Kabaev __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 274ffeaf689SAlexander Kabaev typename iterator_traits<_ForwardIterator>::value_type>) 275ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first, __last); 27600db7afdSDavid E. O'Brien 27700db7afdSDavid E. O'Brien _Distance __remaining = std::distance(__first, __last); 27800db7afdSDavid E. O'Brien _Distance __m = min(__n, __remaining); 27900db7afdSDavid E. O'Brien 280*f8a1b7d9SAlexander Kabaev while (__m > 0) 281*f8a1b7d9SAlexander Kabaev { 282*f8a1b7d9SAlexander Kabaev if ((std::rand() % __remaining) < __m) 283*f8a1b7d9SAlexander Kabaev { 28400db7afdSDavid E. O'Brien *__out = *__first; 28500db7afdSDavid E. O'Brien ++__out; 28600db7afdSDavid E. O'Brien --__m; 28700db7afdSDavid E. O'Brien } 28800db7afdSDavid E. O'Brien --__remaining; 28900db7afdSDavid E. O'Brien ++__first; 29000db7afdSDavid E. O'Brien } 29100db7afdSDavid E. O'Brien return __out; 29200db7afdSDavid E. O'Brien } 29300db7afdSDavid E. O'Brien 294ca6500fcSAlexander Kabaev /** 295ca6500fcSAlexander Kabaev * This is an SGI extension. 296ca6500fcSAlexander Kabaev * @ingroup SGIextensions 297ca6500fcSAlexander Kabaev * @doctodo 298ca6500fcSAlexander Kabaev */ 299*f8a1b7d9SAlexander Kabaev template<typename _ForwardIterator, typename _OutputIterator, 300*f8a1b7d9SAlexander Kabaev typename _Distance, typename _RandomNumberGenerator> 301ffeaf689SAlexander Kabaev _OutputIterator 302ffeaf689SAlexander Kabaev random_sample_n(_ForwardIterator __first, _ForwardIterator __last, 303ffeaf689SAlexander Kabaev _OutputIterator __out, const _Distance __n, 30400db7afdSDavid E. O'Brien _RandomNumberGenerator& __rand) 30500db7afdSDavid E. O'Brien { 30600db7afdSDavid E. O'Brien // concept requirements 307ffeaf689SAlexander Kabaev __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 308ffeaf689SAlexander Kabaev __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 309ffeaf689SAlexander Kabaev typename iterator_traits<_ForwardIterator>::value_type>) 310ffeaf689SAlexander Kabaev __glibcxx_function_requires(_UnaryFunctionConcept< 31100db7afdSDavid E. O'Brien _RandomNumberGenerator, _Distance, _Distance>) 312ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first, __last); 31300db7afdSDavid E. O'Brien 31400db7afdSDavid E. O'Brien _Distance __remaining = std::distance(__first, __last); 31500db7afdSDavid E. O'Brien _Distance __m = min(__n, __remaining); 31600db7afdSDavid E. O'Brien 317*f8a1b7d9SAlexander Kabaev while (__m > 0) 318*f8a1b7d9SAlexander Kabaev { 319*f8a1b7d9SAlexander Kabaev if (__rand(__remaining) < __m) 320*f8a1b7d9SAlexander Kabaev { 32100db7afdSDavid E. O'Brien *__out = *__first; 32200db7afdSDavid E. O'Brien ++__out; 32300db7afdSDavid E. O'Brien --__m; 32400db7afdSDavid E. O'Brien } 32500db7afdSDavid E. O'Brien --__remaining; 32600db7afdSDavid E. O'Brien ++__first; 32700db7afdSDavid E. O'Brien } 32800db7afdSDavid E. O'Brien return __out; 32900db7afdSDavid E. O'Brien } 33000db7afdSDavid E. O'Brien 331*f8a1b7d9SAlexander Kabaev template<typename _InputIterator, typename _RandomAccessIterator, 332*f8a1b7d9SAlexander Kabaev typename _Distance> 333ffeaf689SAlexander Kabaev _RandomAccessIterator 334ffeaf689SAlexander Kabaev __random_sample(_InputIterator __first, _InputIterator __last, 335ffeaf689SAlexander Kabaev _RandomAccessIterator __out, 33600db7afdSDavid E. O'Brien const _Distance __n) 33700db7afdSDavid E. O'Brien { 33800db7afdSDavid E. O'Brien _Distance __m = 0; 33900db7afdSDavid E. O'Brien _Distance __t = __n; 34000db7afdSDavid E. O'Brien for ( ; __first != __last && __m < __n; ++__m, ++__first) 34100db7afdSDavid E. O'Brien __out[__m] = *__first; 34200db7afdSDavid E. O'Brien 343*f8a1b7d9SAlexander Kabaev while (__first != __last) 344*f8a1b7d9SAlexander Kabaev { 34500db7afdSDavid E. O'Brien ++__t; 346ffeaf689SAlexander Kabaev _Distance __M = std::rand() % (__t); 34700db7afdSDavid E. O'Brien if (__M < __n) 34800db7afdSDavid E. O'Brien __out[__M] = *__first; 34900db7afdSDavid E. O'Brien ++__first; 35000db7afdSDavid E. O'Brien } 35100db7afdSDavid E. O'Brien return __out + __m; 35200db7afdSDavid E. O'Brien } 35300db7afdSDavid E. O'Brien 354ffeaf689SAlexander Kabaev template<typename _InputIterator, typename _RandomAccessIterator, 35500db7afdSDavid E. O'Brien typename _RandomNumberGenerator, typename _Distance> 356ffeaf689SAlexander Kabaev _RandomAccessIterator 357ffeaf689SAlexander Kabaev __random_sample(_InputIterator __first, _InputIterator __last, 358ffeaf689SAlexander Kabaev _RandomAccessIterator __out, 35900db7afdSDavid E. O'Brien _RandomNumberGenerator& __rand, 36000db7afdSDavid E. O'Brien const _Distance __n) 36100db7afdSDavid E. O'Brien { 36200db7afdSDavid E. O'Brien // concept requirements 363ffeaf689SAlexander Kabaev __glibcxx_function_requires(_UnaryFunctionConcept< 36400db7afdSDavid E. O'Brien _RandomNumberGenerator, _Distance, _Distance>) 36500db7afdSDavid E. O'Brien 36600db7afdSDavid E. O'Brien _Distance __m = 0; 36700db7afdSDavid E. O'Brien _Distance __t = __n; 36800db7afdSDavid E. O'Brien for ( ; __first != __last && __m < __n; ++__m, ++__first) 36900db7afdSDavid E. O'Brien __out[__m] = *__first; 37000db7afdSDavid E. O'Brien 371*f8a1b7d9SAlexander Kabaev while (__first != __last) 372*f8a1b7d9SAlexander Kabaev { 37300db7afdSDavid E. O'Brien ++__t; 37400db7afdSDavid E. O'Brien _Distance __M = __rand(__t); 37500db7afdSDavid E. O'Brien if (__M < __n) 37600db7afdSDavid E. O'Brien __out[__M] = *__first; 37700db7afdSDavid E. O'Brien ++__first; 37800db7afdSDavid E. O'Brien } 37900db7afdSDavid E. O'Brien return __out + __m; 38000db7afdSDavid E. O'Brien } 38100db7afdSDavid E. O'Brien 382ca6500fcSAlexander Kabaev /** 383ca6500fcSAlexander Kabaev * This is an SGI extension. 384ca6500fcSAlexander Kabaev * @ingroup SGIextensions 385ca6500fcSAlexander Kabaev * @doctodo 386ca6500fcSAlexander Kabaev */ 387ffeaf689SAlexander Kabaev template<typename _InputIterator, typename _RandomAccessIterator> 388ffeaf689SAlexander Kabaev inline _RandomAccessIterator 389ffeaf689SAlexander Kabaev random_sample(_InputIterator __first, _InputIterator __last, 390*f8a1b7d9SAlexander Kabaev _RandomAccessIterator __out_first, 391*f8a1b7d9SAlexander Kabaev _RandomAccessIterator __out_last) 39200db7afdSDavid E. O'Brien { 39300db7afdSDavid E. O'Brien // concept requirements 394ffeaf689SAlexander Kabaev __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 395ffeaf689SAlexander Kabaev __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 396ffeaf689SAlexander Kabaev _RandomAccessIterator>) 397ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first, __last); 398ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__out_first, __out_last); 39900db7afdSDavid E. O'Brien 40000db7afdSDavid E. O'Brien return __random_sample(__first, __last, 40100db7afdSDavid E. O'Brien __out_first, __out_last - __out_first); 40200db7afdSDavid E. O'Brien } 40300db7afdSDavid E. O'Brien 404ca6500fcSAlexander Kabaev /** 405ca6500fcSAlexander Kabaev * This is an SGI extension. 406ca6500fcSAlexander Kabaev * @ingroup SGIextensions 407ca6500fcSAlexander Kabaev * @doctodo 408ca6500fcSAlexander Kabaev */ 409ffeaf689SAlexander Kabaev template<typename _InputIterator, typename _RandomAccessIterator, 41000db7afdSDavid E. O'Brien typename _RandomNumberGenerator> 411ffeaf689SAlexander Kabaev inline _RandomAccessIterator 412ffeaf689SAlexander Kabaev random_sample(_InputIterator __first, _InputIterator __last, 413*f8a1b7d9SAlexander Kabaev _RandomAccessIterator __out_first, 414*f8a1b7d9SAlexander Kabaev _RandomAccessIterator __out_last, 41500db7afdSDavid E. O'Brien _RandomNumberGenerator& __rand) 41600db7afdSDavid E. O'Brien { 41700db7afdSDavid E. O'Brien // concept requirements 418ffeaf689SAlexander Kabaev __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 419ffeaf689SAlexander Kabaev __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 420ffeaf689SAlexander Kabaev _RandomAccessIterator>) 421ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first, __last); 422ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__out_first, __out_last); 42300db7afdSDavid E. O'Brien 42400db7afdSDavid E. O'Brien return __random_sample(__first, __last, 42500db7afdSDavid E. O'Brien __out_first, __rand, 42600db7afdSDavid E. O'Brien __out_last - __out_first); 42700db7afdSDavid E. O'Brien } 42800db7afdSDavid E. O'Brien 429ca6500fcSAlexander Kabaev /** 430ca6500fcSAlexander Kabaev * This is an SGI extension. 431ca6500fcSAlexander Kabaev * @ingroup SGIextensions 432ca6500fcSAlexander Kabaev * @doctodo 433ca6500fcSAlexander Kabaev */ 434ffeaf689SAlexander Kabaev template<typename _RandomAccessIterator> 43500db7afdSDavid E. O'Brien inline bool 436ffeaf689SAlexander Kabaev is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 43700db7afdSDavid E. O'Brien { 43800db7afdSDavid E. O'Brien // concept requirements 439*f8a1b7d9SAlexander Kabaev __glibcxx_function_requires(_RandomAccessIteratorConcept< 440*f8a1b7d9SAlexander Kabaev _RandomAccessIterator>) 441ffeaf689SAlexander Kabaev __glibcxx_function_requires(_LessThanComparableConcept< 442ffeaf689SAlexander Kabaev typename iterator_traits<_RandomAccessIterator>::value_type>) 443ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first, __last); 44400db7afdSDavid E. O'Brien 445ffeaf689SAlexander Kabaev return std::__is_heap(__first, __last - __first); 44600db7afdSDavid E. O'Brien } 44700db7afdSDavid E. O'Brien 448ca6500fcSAlexander Kabaev /** 449ca6500fcSAlexander Kabaev * This is an SGI extension. 450ca6500fcSAlexander Kabaev * @ingroup SGIextensions 451ca6500fcSAlexander Kabaev * @doctodo 452ca6500fcSAlexander Kabaev */ 453ffeaf689SAlexander Kabaev template<typename _RandomAccessIterator, typename _StrictWeakOrdering> 45400db7afdSDavid E. O'Brien inline bool 455ffeaf689SAlexander Kabaev is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 45600db7afdSDavid E. O'Brien _StrictWeakOrdering __comp) 45700db7afdSDavid E. O'Brien { 45800db7afdSDavid E. O'Brien // concept requirements 459*f8a1b7d9SAlexander Kabaev __glibcxx_function_requires(_RandomAccessIteratorConcept< 460*f8a1b7d9SAlexander Kabaev _RandomAccessIterator>) 461ffeaf689SAlexander Kabaev __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, 462ffeaf689SAlexander Kabaev typename iterator_traits<_RandomAccessIterator>::value_type, 463ffeaf689SAlexander Kabaev typename iterator_traits<_RandomAccessIterator>::value_type>) 464ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first, __last); 46500db7afdSDavid E. O'Brien 466ffeaf689SAlexander Kabaev return std::__is_heap(__first, __comp, __last - __first); 46700db7afdSDavid E. O'Brien } 46800db7afdSDavid E. O'Brien 46900db7afdSDavid E. O'Brien // is_sorted, a predicated testing whether a range is sorted in 47000db7afdSDavid E. O'Brien // nondescending order. This is an extension, not part of the C++ 47100db7afdSDavid E. O'Brien // standard. 47200db7afdSDavid E. O'Brien 473ca6500fcSAlexander Kabaev /** 474ca6500fcSAlexander Kabaev * This is an SGI extension. 475ca6500fcSAlexander Kabaev * @ingroup SGIextensions 476ca6500fcSAlexander Kabaev * @doctodo 477ca6500fcSAlexander Kabaev */ 478ffeaf689SAlexander Kabaev template<typename _ForwardIterator> 47900db7afdSDavid E. O'Brien bool 480ffeaf689SAlexander Kabaev is_sorted(_ForwardIterator __first, _ForwardIterator __last) 48100db7afdSDavid E. O'Brien { 48200db7afdSDavid E. O'Brien // concept requirements 483ffeaf689SAlexander Kabaev __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 484ffeaf689SAlexander Kabaev __glibcxx_function_requires(_LessThanComparableConcept< 485ffeaf689SAlexander Kabaev typename iterator_traits<_ForwardIterator>::value_type>) 486ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first, __last); 48700db7afdSDavid E. O'Brien 48800db7afdSDavid E. O'Brien if (__first == __last) 48900db7afdSDavid E. O'Brien return true; 49000db7afdSDavid E. O'Brien 491ffeaf689SAlexander Kabaev _ForwardIterator __next = __first; 492*f8a1b7d9SAlexander Kabaev for (++__next; __next != __last; __first = __next, ++__next) 49300db7afdSDavid E. O'Brien if (*__next < *__first) 49400db7afdSDavid E. O'Brien return false; 49500db7afdSDavid E. O'Brien return true; 49600db7afdSDavid E. O'Brien } 49700db7afdSDavid E. O'Brien 498ca6500fcSAlexander Kabaev /** 499ca6500fcSAlexander Kabaev * This is an SGI extension. 500ca6500fcSAlexander Kabaev * @ingroup SGIextensions 501ca6500fcSAlexander Kabaev * @doctodo 502ca6500fcSAlexander Kabaev */ 503ffeaf689SAlexander Kabaev template<typename _ForwardIterator, typename _StrictWeakOrdering> 50400db7afdSDavid E. O'Brien bool 505*f8a1b7d9SAlexander Kabaev is_sorted(_ForwardIterator __first, _ForwardIterator __last, 506*f8a1b7d9SAlexander Kabaev _StrictWeakOrdering __comp) 50700db7afdSDavid E. O'Brien { 50800db7afdSDavid E. O'Brien // concept requirements 509ffeaf689SAlexander Kabaev __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 510ffeaf689SAlexander Kabaev __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, 511ffeaf689SAlexander Kabaev typename iterator_traits<_ForwardIterator>::value_type, 512ffeaf689SAlexander Kabaev typename iterator_traits<_ForwardIterator>::value_type>) 513ffeaf689SAlexander Kabaev __glibcxx_requires_valid_range(__first, __last); 51400db7afdSDavid E. O'Brien 51500db7afdSDavid E. O'Brien if (__first == __last) 51600db7afdSDavid E. O'Brien return true; 51700db7afdSDavid E. O'Brien 518ffeaf689SAlexander Kabaev _ForwardIterator __next = __first; 519*f8a1b7d9SAlexander Kabaev for (++__next; __next != __last; __first = __next, ++__next) 52000db7afdSDavid E. O'Brien if (__comp(*__next, *__first)) 52100db7afdSDavid E. O'Brien return false; 52200db7afdSDavid E. O'Brien return true; 52300db7afdSDavid E. O'Brien } 524*f8a1b7d9SAlexander Kabaev 525*f8a1b7d9SAlexander Kabaev_GLIBCXX_END_NAMESPACE 52600db7afdSDavid E. O'Brien 52700db7afdSDavid E. O'Brien#endif /* _EXT_ALGORITHM */ 528