1*e4b17023SJohn Marino // Algorithm implementation -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 4*e4b17023SJohn Marino // 2010, 2011 5*e4b17023SJohn Marino // Free Software Foundation, Inc. 6*e4b17023SJohn Marino // 7*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free 8*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the 9*e4b17023SJohn Marino // terms of the GNU General Public License as published by the 10*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option) 11*e4b17023SJohn Marino // any later version. 12*e4b17023SJohn Marino 13*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, 14*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of 15*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*e4b17023SJohn Marino // GNU General Public License for more details. 17*e4b17023SJohn Marino 18*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional 19*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version 20*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation. 21*e4b17023SJohn Marino 22*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and 23*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program; 24*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>. 26*e4b17023SJohn Marino 27*e4b17023SJohn Marino /* 28*e4b17023SJohn Marino * 29*e4b17023SJohn Marino * Copyright (c) 1994 30*e4b17023SJohn Marino * Hewlett-Packard Company 31*e4b17023SJohn Marino * 32*e4b17023SJohn Marino * Permission to use, copy, modify, distribute and sell this software 33*e4b17023SJohn Marino * and its documentation for any purpose is hereby granted without fee, 34*e4b17023SJohn Marino * provided that the above copyright notice appear in all copies and 35*e4b17023SJohn Marino * that both that copyright notice and this permission notice appear 36*e4b17023SJohn Marino * in supporting documentation. Hewlett-Packard Company makes no 37*e4b17023SJohn Marino * representations about the suitability of this software for any 38*e4b17023SJohn Marino * purpose. It is provided "as is" without express or implied warranty. 39*e4b17023SJohn Marino * 40*e4b17023SJohn Marino * 41*e4b17023SJohn Marino * Copyright (c) 1996 42*e4b17023SJohn Marino * Silicon Graphics Computer Systems, Inc. 43*e4b17023SJohn Marino * 44*e4b17023SJohn Marino * Permission to use, copy, modify, distribute and sell this software 45*e4b17023SJohn Marino * and its documentation for any purpose is hereby granted without fee, 46*e4b17023SJohn Marino * provided that the above copyright notice appear in all copies and 47*e4b17023SJohn Marino * that both that copyright notice and this permission notice appear 48*e4b17023SJohn Marino * in supporting documentation. Silicon Graphics makes no 49*e4b17023SJohn Marino * representations about the suitability of this software for any 50*e4b17023SJohn Marino * purpose. It is provided "as is" without express or implied warranty. 51*e4b17023SJohn Marino */ 52*e4b17023SJohn Marino 53*e4b17023SJohn Marino /** @file bits/stl_algo.h 54*e4b17023SJohn Marino * This is an internal header file, included by other library headers. 55*e4b17023SJohn Marino * Do not attempt to use it directly. @headername{algorithm} 56*e4b17023SJohn Marino */ 57*e4b17023SJohn Marino 58*e4b17023SJohn Marino #ifndef _STL_ALGO_H 59*e4b17023SJohn Marino #define _STL_ALGO_H 1 60*e4b17023SJohn Marino 61*e4b17023SJohn Marino #include <cstdlib> // for rand 62*e4b17023SJohn Marino #include <bits/algorithmfwd.h> 63*e4b17023SJohn Marino #include <bits/stl_heap.h> 64*e4b17023SJohn Marino #include <bits/stl_tempbuf.h> // for _Temporary_buffer 65*e4b17023SJohn Marino 66*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 67*e4b17023SJohn Marino #include <random> // for std::uniform_int_distribution 68*e4b17023SJohn Marino #include <functional> // for std::bind 69*e4b17023SJohn Marino #endif 70*e4b17023SJohn Marino 71*e4b17023SJohn Marino // See concept_check.h for the __glibcxx_*_requires macros. 72*e4b17023SJohn Marino 73*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default) 74*e4b17023SJohn Marino { 75*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION 76*e4b17023SJohn Marino 77*e4b17023SJohn Marino /// Swaps the median value of *__a, *__b and *__c to *__a 78*e4b17023SJohn Marino template<typename _Iterator> 79*e4b17023SJohn Marino void 80*e4b17023SJohn Marino __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c) 81*e4b17023SJohn Marino { 82*e4b17023SJohn Marino // concept requirements 83*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept< 84*e4b17023SJohn Marino typename iterator_traits<_Iterator>::value_type>) 85*e4b17023SJohn Marino 86*e4b17023SJohn Marino if (*__a < *__b) 87*e4b17023SJohn Marino { 88*e4b17023SJohn Marino if (*__b < *__c) 89*e4b17023SJohn Marino std::iter_swap(__a, __b); 90*e4b17023SJohn Marino else if (*__a < *__c) 91*e4b17023SJohn Marino std::iter_swap(__a, __c); 92*e4b17023SJohn Marino } 93*e4b17023SJohn Marino else if (*__a < *__c) 94*e4b17023SJohn Marino return; 95*e4b17023SJohn Marino else if (*__b < *__c) 96*e4b17023SJohn Marino std::iter_swap(__a, __c); 97*e4b17023SJohn Marino else 98*e4b17023SJohn Marino std::iter_swap(__a, __b); 99*e4b17023SJohn Marino } 100*e4b17023SJohn Marino 101*e4b17023SJohn Marino /// Swaps the median value of *__a, *__b and *__c under __comp to *__a 102*e4b17023SJohn Marino template<typename _Iterator, typename _Compare> 103*e4b17023SJohn Marino void 104*e4b17023SJohn Marino __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c, 105*e4b17023SJohn Marino _Compare __comp) 106*e4b17023SJohn Marino { 107*e4b17023SJohn Marino // concept requirements 108*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool, 109*e4b17023SJohn Marino typename iterator_traits<_Iterator>::value_type, 110*e4b17023SJohn Marino typename iterator_traits<_Iterator>::value_type>) 111*e4b17023SJohn Marino 112*e4b17023SJohn Marino if (__comp(*__a, *__b)) 113*e4b17023SJohn Marino { 114*e4b17023SJohn Marino if (__comp(*__b, *__c)) 115*e4b17023SJohn Marino std::iter_swap(__a, __b); 116*e4b17023SJohn Marino else if (__comp(*__a, *__c)) 117*e4b17023SJohn Marino std::iter_swap(__a, __c); 118*e4b17023SJohn Marino } 119*e4b17023SJohn Marino else if (__comp(*__a, *__c)) 120*e4b17023SJohn Marino return; 121*e4b17023SJohn Marino else if (__comp(*__b, *__c)) 122*e4b17023SJohn Marino std::iter_swap(__a, __c); 123*e4b17023SJohn Marino else 124*e4b17023SJohn Marino std::iter_swap(__a, __b); 125*e4b17023SJohn Marino } 126*e4b17023SJohn Marino 127*e4b17023SJohn Marino // for_each 128*e4b17023SJohn Marino 129*e4b17023SJohn Marino /// This is an overload used by find() for the Input Iterator case. 130*e4b17023SJohn Marino template<typename _InputIterator, typename _Tp> 131*e4b17023SJohn Marino inline _InputIterator 132*e4b17023SJohn Marino __find(_InputIterator __first, _InputIterator __last, 133*e4b17023SJohn Marino const _Tp& __val, input_iterator_tag) 134*e4b17023SJohn Marino { 135*e4b17023SJohn Marino while (__first != __last && !(*__first == __val)) 136*e4b17023SJohn Marino ++__first; 137*e4b17023SJohn Marino return __first; 138*e4b17023SJohn Marino } 139*e4b17023SJohn Marino 140*e4b17023SJohn Marino /// This is an overload used by find_if() for the Input Iterator case. 141*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 142*e4b17023SJohn Marino inline _InputIterator 143*e4b17023SJohn Marino __find_if(_InputIterator __first, _InputIterator __last, 144*e4b17023SJohn Marino _Predicate __pred, input_iterator_tag) 145*e4b17023SJohn Marino { 146*e4b17023SJohn Marino while (__first != __last && !bool(__pred(*__first))) 147*e4b17023SJohn Marino ++__first; 148*e4b17023SJohn Marino return __first; 149*e4b17023SJohn Marino } 150*e4b17023SJohn Marino 151*e4b17023SJohn Marino /// This is an overload used by find() for the RAI case. 152*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Tp> 153*e4b17023SJohn Marino _RandomAccessIterator 154*e4b17023SJohn Marino __find(_RandomAccessIterator __first, _RandomAccessIterator __last, 155*e4b17023SJohn Marino const _Tp& __val, random_access_iterator_tag) 156*e4b17023SJohn Marino { 157*e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::difference_type 158*e4b17023SJohn Marino __trip_count = (__last - __first) >> 2; 159*e4b17023SJohn Marino 160*e4b17023SJohn Marino for (; __trip_count > 0; --__trip_count) 161*e4b17023SJohn Marino { 162*e4b17023SJohn Marino if (*__first == __val) 163*e4b17023SJohn Marino return __first; 164*e4b17023SJohn Marino ++__first; 165*e4b17023SJohn Marino 166*e4b17023SJohn Marino if (*__first == __val) 167*e4b17023SJohn Marino return __first; 168*e4b17023SJohn Marino ++__first; 169*e4b17023SJohn Marino 170*e4b17023SJohn Marino if (*__first == __val) 171*e4b17023SJohn Marino return __first; 172*e4b17023SJohn Marino ++__first; 173*e4b17023SJohn Marino 174*e4b17023SJohn Marino if (*__first == __val) 175*e4b17023SJohn Marino return __first; 176*e4b17023SJohn Marino ++__first; 177*e4b17023SJohn Marino } 178*e4b17023SJohn Marino 179*e4b17023SJohn Marino switch (__last - __first) 180*e4b17023SJohn Marino { 181*e4b17023SJohn Marino case 3: 182*e4b17023SJohn Marino if (*__first == __val) 183*e4b17023SJohn Marino return __first; 184*e4b17023SJohn Marino ++__first; 185*e4b17023SJohn Marino case 2: 186*e4b17023SJohn Marino if (*__first == __val) 187*e4b17023SJohn Marino return __first; 188*e4b17023SJohn Marino ++__first; 189*e4b17023SJohn Marino case 1: 190*e4b17023SJohn Marino if (*__first == __val) 191*e4b17023SJohn Marino return __first; 192*e4b17023SJohn Marino ++__first; 193*e4b17023SJohn Marino case 0: 194*e4b17023SJohn Marino default: 195*e4b17023SJohn Marino return __last; 196*e4b17023SJohn Marino } 197*e4b17023SJohn Marino } 198*e4b17023SJohn Marino 199*e4b17023SJohn Marino /// This is an overload used by find_if() for the RAI case. 200*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Predicate> 201*e4b17023SJohn Marino _RandomAccessIterator 202*e4b17023SJohn Marino __find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, 203*e4b17023SJohn Marino _Predicate __pred, random_access_iterator_tag) 204*e4b17023SJohn Marino { 205*e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::difference_type 206*e4b17023SJohn Marino __trip_count = (__last - __first) >> 2; 207*e4b17023SJohn Marino 208*e4b17023SJohn Marino for (; __trip_count > 0; --__trip_count) 209*e4b17023SJohn Marino { 210*e4b17023SJohn Marino if (__pred(*__first)) 211*e4b17023SJohn Marino return __first; 212*e4b17023SJohn Marino ++__first; 213*e4b17023SJohn Marino 214*e4b17023SJohn Marino if (__pred(*__first)) 215*e4b17023SJohn Marino return __first; 216*e4b17023SJohn Marino ++__first; 217*e4b17023SJohn Marino 218*e4b17023SJohn Marino if (__pred(*__first)) 219*e4b17023SJohn Marino return __first; 220*e4b17023SJohn Marino ++__first; 221*e4b17023SJohn Marino 222*e4b17023SJohn Marino if (__pred(*__first)) 223*e4b17023SJohn Marino return __first; 224*e4b17023SJohn Marino ++__first; 225*e4b17023SJohn Marino } 226*e4b17023SJohn Marino 227*e4b17023SJohn Marino switch (__last - __first) 228*e4b17023SJohn Marino { 229*e4b17023SJohn Marino case 3: 230*e4b17023SJohn Marino if (__pred(*__first)) 231*e4b17023SJohn Marino return __first; 232*e4b17023SJohn Marino ++__first; 233*e4b17023SJohn Marino case 2: 234*e4b17023SJohn Marino if (__pred(*__first)) 235*e4b17023SJohn Marino return __first; 236*e4b17023SJohn Marino ++__first; 237*e4b17023SJohn Marino case 1: 238*e4b17023SJohn Marino if (__pred(*__first)) 239*e4b17023SJohn Marino return __first; 240*e4b17023SJohn Marino ++__first; 241*e4b17023SJohn Marino case 0: 242*e4b17023SJohn Marino default: 243*e4b17023SJohn Marino return __last; 244*e4b17023SJohn Marino } 245*e4b17023SJohn Marino } 246*e4b17023SJohn Marino 247*e4b17023SJohn Marino /// This is an overload used by find_if_not() for the Input Iterator case. 248*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 249*e4b17023SJohn Marino inline _InputIterator 250*e4b17023SJohn Marino __find_if_not(_InputIterator __first, _InputIterator __last, 251*e4b17023SJohn Marino _Predicate __pred, input_iterator_tag) 252*e4b17023SJohn Marino { 253*e4b17023SJohn Marino while (__first != __last && bool(__pred(*__first))) 254*e4b17023SJohn Marino ++__first; 255*e4b17023SJohn Marino return __first; 256*e4b17023SJohn Marino } 257*e4b17023SJohn Marino 258*e4b17023SJohn Marino /// This is an overload used by find_if_not() for the RAI case. 259*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Predicate> 260*e4b17023SJohn Marino _RandomAccessIterator 261*e4b17023SJohn Marino __find_if_not(_RandomAccessIterator __first, _RandomAccessIterator __last, 262*e4b17023SJohn Marino _Predicate __pred, random_access_iterator_tag) 263*e4b17023SJohn Marino { 264*e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::difference_type 265*e4b17023SJohn Marino __trip_count = (__last - __first) >> 2; 266*e4b17023SJohn Marino 267*e4b17023SJohn Marino for (; __trip_count > 0; --__trip_count) 268*e4b17023SJohn Marino { 269*e4b17023SJohn Marino if (!bool(__pred(*__first))) 270*e4b17023SJohn Marino return __first; 271*e4b17023SJohn Marino ++__first; 272*e4b17023SJohn Marino 273*e4b17023SJohn Marino if (!bool(__pred(*__first))) 274*e4b17023SJohn Marino return __first; 275*e4b17023SJohn Marino ++__first; 276*e4b17023SJohn Marino 277*e4b17023SJohn Marino if (!bool(__pred(*__first))) 278*e4b17023SJohn Marino return __first; 279*e4b17023SJohn Marino ++__first; 280*e4b17023SJohn Marino 281*e4b17023SJohn Marino if (!bool(__pred(*__first))) 282*e4b17023SJohn Marino return __first; 283*e4b17023SJohn Marino ++__first; 284*e4b17023SJohn Marino } 285*e4b17023SJohn Marino 286*e4b17023SJohn Marino switch (__last - __first) 287*e4b17023SJohn Marino { 288*e4b17023SJohn Marino case 3: 289*e4b17023SJohn Marino if (!bool(__pred(*__first))) 290*e4b17023SJohn Marino return __first; 291*e4b17023SJohn Marino ++__first; 292*e4b17023SJohn Marino case 2: 293*e4b17023SJohn Marino if (!bool(__pred(*__first))) 294*e4b17023SJohn Marino return __first; 295*e4b17023SJohn Marino ++__first; 296*e4b17023SJohn Marino case 1: 297*e4b17023SJohn Marino if (!bool(__pred(*__first))) 298*e4b17023SJohn Marino return __first; 299*e4b17023SJohn Marino ++__first; 300*e4b17023SJohn Marino case 0: 301*e4b17023SJohn Marino default: 302*e4b17023SJohn Marino return __last; 303*e4b17023SJohn Marino } 304*e4b17023SJohn Marino } 305*e4b17023SJohn Marino 306*e4b17023SJohn Marino /// Provided for stable_partition to use. 307*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 308*e4b17023SJohn Marino inline _InputIterator 309*e4b17023SJohn Marino __find_if_not(_InputIterator __first, _InputIterator __last, 310*e4b17023SJohn Marino _Predicate __pred) 311*e4b17023SJohn Marino { 312*e4b17023SJohn Marino return std::__find_if_not(__first, __last, __pred, 313*e4b17023SJohn Marino std::__iterator_category(__first)); 314*e4b17023SJohn Marino } 315*e4b17023SJohn Marino 316*e4b17023SJohn Marino /// Like find_if_not(), but uses and updates a count of the 317*e4b17023SJohn Marino /// remaining range length instead of comparing against an end 318*e4b17023SJohn Marino /// iterator. 319*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate, typename _Distance> 320*e4b17023SJohn Marino _InputIterator 321*e4b17023SJohn Marino __find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate __pred) 322*e4b17023SJohn Marino { 323*e4b17023SJohn Marino for (; __len; --__len, ++__first) 324*e4b17023SJohn Marino if (!bool(__pred(*__first))) 325*e4b17023SJohn Marino break; 326*e4b17023SJohn Marino return __first; 327*e4b17023SJohn Marino } 328*e4b17023SJohn Marino 329*e4b17023SJohn Marino // set_difference 330*e4b17023SJohn Marino // set_intersection 331*e4b17023SJohn Marino // set_symmetric_difference 332*e4b17023SJohn Marino // set_union 333*e4b17023SJohn Marino // for_each 334*e4b17023SJohn Marino // find 335*e4b17023SJohn Marino // find_if 336*e4b17023SJohn Marino // find_first_of 337*e4b17023SJohn Marino // adjacent_find 338*e4b17023SJohn Marino // count 339*e4b17023SJohn Marino // count_if 340*e4b17023SJohn Marino // search 341*e4b17023SJohn Marino 342*e4b17023SJohn Marino /** 343*e4b17023SJohn Marino * This is an uglified 344*e4b17023SJohn Marino * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) 345*e4b17023SJohn Marino * overloaded for forward iterators. 346*e4b17023SJohn Marino */ 347*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Integer, typename _Tp> 348*e4b17023SJohn Marino _ForwardIterator 349*e4b17023SJohn Marino __search_n(_ForwardIterator __first, _ForwardIterator __last, 350*e4b17023SJohn Marino _Integer __count, const _Tp& __val, 351*e4b17023SJohn Marino std::forward_iterator_tag) 352*e4b17023SJohn Marino { 353*e4b17023SJohn Marino __first = _GLIBCXX_STD_A::find(__first, __last, __val); 354*e4b17023SJohn Marino while (__first != __last) 355*e4b17023SJohn Marino { 356*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::difference_type 357*e4b17023SJohn Marino __n = __count; 358*e4b17023SJohn Marino _ForwardIterator __i = __first; 359*e4b17023SJohn Marino ++__i; 360*e4b17023SJohn Marino while (__i != __last && __n != 1 && *__i == __val) 361*e4b17023SJohn Marino { 362*e4b17023SJohn Marino ++__i; 363*e4b17023SJohn Marino --__n; 364*e4b17023SJohn Marino } 365*e4b17023SJohn Marino if (__n == 1) 366*e4b17023SJohn Marino return __first; 367*e4b17023SJohn Marino if (__i == __last) 368*e4b17023SJohn Marino return __last; 369*e4b17023SJohn Marino __first = _GLIBCXX_STD_A::find(++__i, __last, __val); 370*e4b17023SJohn Marino } 371*e4b17023SJohn Marino return __last; 372*e4b17023SJohn Marino } 373*e4b17023SJohn Marino 374*e4b17023SJohn Marino /** 375*e4b17023SJohn Marino * This is an uglified 376*e4b17023SJohn Marino * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) 377*e4b17023SJohn Marino * overloaded for random access iterators. 378*e4b17023SJohn Marino */ 379*e4b17023SJohn Marino template<typename _RandomAccessIter, typename _Integer, typename _Tp> 380*e4b17023SJohn Marino _RandomAccessIter 381*e4b17023SJohn Marino __search_n(_RandomAccessIter __first, _RandomAccessIter __last, 382*e4b17023SJohn Marino _Integer __count, const _Tp& __val, 383*e4b17023SJohn Marino std::random_access_iterator_tag) 384*e4b17023SJohn Marino { 385*e4b17023SJohn Marino 386*e4b17023SJohn Marino typedef typename std::iterator_traits<_RandomAccessIter>::difference_type 387*e4b17023SJohn Marino _DistanceType; 388*e4b17023SJohn Marino 389*e4b17023SJohn Marino _DistanceType __tailSize = __last - __first; 390*e4b17023SJohn Marino const _DistanceType __pattSize = __count; 391*e4b17023SJohn Marino 392*e4b17023SJohn Marino if (__tailSize < __pattSize) 393*e4b17023SJohn Marino return __last; 394*e4b17023SJohn Marino 395*e4b17023SJohn Marino const _DistanceType __skipOffset = __pattSize - 1; 396*e4b17023SJohn Marino _RandomAccessIter __lookAhead = __first + __skipOffset; 397*e4b17023SJohn Marino __tailSize -= __pattSize; 398*e4b17023SJohn Marino 399*e4b17023SJohn Marino while (1) // the main loop... 400*e4b17023SJohn Marino { 401*e4b17023SJohn Marino // __lookAhead here is always pointing to the last element of next 402*e4b17023SJohn Marino // possible match. 403*e4b17023SJohn Marino while (!(*__lookAhead == __val)) // the skip loop... 404*e4b17023SJohn Marino { 405*e4b17023SJohn Marino if (__tailSize < __pattSize) 406*e4b17023SJohn Marino return __last; // Failure 407*e4b17023SJohn Marino __lookAhead += __pattSize; 408*e4b17023SJohn Marino __tailSize -= __pattSize; 409*e4b17023SJohn Marino } 410*e4b17023SJohn Marino _DistanceType __remainder = __skipOffset; 411*e4b17023SJohn Marino for (_RandomAccessIter __backTrack = __lookAhead - 1; 412*e4b17023SJohn Marino *__backTrack == __val; --__backTrack) 413*e4b17023SJohn Marino { 414*e4b17023SJohn Marino if (--__remainder == 0) 415*e4b17023SJohn Marino return (__lookAhead - __skipOffset); // Success 416*e4b17023SJohn Marino } 417*e4b17023SJohn Marino if (__remainder > __tailSize) 418*e4b17023SJohn Marino return __last; // Failure 419*e4b17023SJohn Marino __lookAhead += __remainder; 420*e4b17023SJohn Marino __tailSize -= __remainder; 421*e4b17023SJohn Marino } 422*e4b17023SJohn Marino } 423*e4b17023SJohn Marino 424*e4b17023SJohn Marino // search_n 425*e4b17023SJohn Marino 426*e4b17023SJohn Marino /** 427*e4b17023SJohn Marino * This is an uglified 428*e4b17023SJohn Marino * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&, 429*e4b17023SJohn Marino * _BinaryPredicate) 430*e4b17023SJohn Marino * overloaded for forward iterators. 431*e4b17023SJohn Marino */ 432*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Integer, typename _Tp, 433*e4b17023SJohn Marino typename _BinaryPredicate> 434*e4b17023SJohn Marino _ForwardIterator 435*e4b17023SJohn Marino __search_n(_ForwardIterator __first, _ForwardIterator __last, 436*e4b17023SJohn Marino _Integer __count, const _Tp& __val, 437*e4b17023SJohn Marino _BinaryPredicate __binary_pred, std::forward_iterator_tag) 438*e4b17023SJohn Marino { 439*e4b17023SJohn Marino while (__first != __last && !bool(__binary_pred(*__first, __val))) 440*e4b17023SJohn Marino ++__first; 441*e4b17023SJohn Marino 442*e4b17023SJohn Marino while (__first != __last) 443*e4b17023SJohn Marino { 444*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::difference_type 445*e4b17023SJohn Marino __n = __count; 446*e4b17023SJohn Marino _ForwardIterator __i = __first; 447*e4b17023SJohn Marino ++__i; 448*e4b17023SJohn Marino while (__i != __last && __n != 1 && bool(__binary_pred(*__i, __val))) 449*e4b17023SJohn Marino { 450*e4b17023SJohn Marino ++__i; 451*e4b17023SJohn Marino --__n; 452*e4b17023SJohn Marino } 453*e4b17023SJohn Marino if (__n == 1) 454*e4b17023SJohn Marino return __first; 455*e4b17023SJohn Marino if (__i == __last) 456*e4b17023SJohn Marino return __last; 457*e4b17023SJohn Marino __first = ++__i; 458*e4b17023SJohn Marino while (__first != __last 459*e4b17023SJohn Marino && !bool(__binary_pred(*__first, __val))) 460*e4b17023SJohn Marino ++__first; 461*e4b17023SJohn Marino } 462*e4b17023SJohn Marino return __last; 463*e4b17023SJohn Marino } 464*e4b17023SJohn Marino 465*e4b17023SJohn Marino /** 466*e4b17023SJohn Marino * This is an uglified 467*e4b17023SJohn Marino * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&, 468*e4b17023SJohn Marino * _BinaryPredicate) 469*e4b17023SJohn Marino * overloaded for random access iterators. 470*e4b17023SJohn Marino */ 471*e4b17023SJohn Marino template<typename _RandomAccessIter, typename _Integer, typename _Tp, 472*e4b17023SJohn Marino typename _BinaryPredicate> 473*e4b17023SJohn Marino _RandomAccessIter 474*e4b17023SJohn Marino __search_n(_RandomAccessIter __first, _RandomAccessIter __last, 475*e4b17023SJohn Marino _Integer __count, const _Tp& __val, 476*e4b17023SJohn Marino _BinaryPredicate __binary_pred, std::random_access_iterator_tag) 477*e4b17023SJohn Marino { 478*e4b17023SJohn Marino 479*e4b17023SJohn Marino typedef typename std::iterator_traits<_RandomAccessIter>::difference_type 480*e4b17023SJohn Marino _DistanceType; 481*e4b17023SJohn Marino 482*e4b17023SJohn Marino _DistanceType __tailSize = __last - __first; 483*e4b17023SJohn Marino const _DistanceType __pattSize = __count; 484*e4b17023SJohn Marino 485*e4b17023SJohn Marino if (__tailSize < __pattSize) 486*e4b17023SJohn Marino return __last; 487*e4b17023SJohn Marino 488*e4b17023SJohn Marino const _DistanceType __skipOffset = __pattSize - 1; 489*e4b17023SJohn Marino _RandomAccessIter __lookAhead = __first + __skipOffset; 490*e4b17023SJohn Marino __tailSize -= __pattSize; 491*e4b17023SJohn Marino 492*e4b17023SJohn Marino while (1) // the main loop... 493*e4b17023SJohn Marino { 494*e4b17023SJohn Marino // __lookAhead here is always pointing to the last element of next 495*e4b17023SJohn Marino // possible match. 496*e4b17023SJohn Marino while (!bool(__binary_pred(*__lookAhead, __val))) // the skip loop... 497*e4b17023SJohn Marino { 498*e4b17023SJohn Marino if (__tailSize < __pattSize) 499*e4b17023SJohn Marino return __last; // Failure 500*e4b17023SJohn Marino __lookAhead += __pattSize; 501*e4b17023SJohn Marino __tailSize -= __pattSize; 502*e4b17023SJohn Marino } 503*e4b17023SJohn Marino _DistanceType __remainder = __skipOffset; 504*e4b17023SJohn Marino for (_RandomAccessIter __backTrack = __lookAhead - 1; 505*e4b17023SJohn Marino __binary_pred(*__backTrack, __val); --__backTrack) 506*e4b17023SJohn Marino { 507*e4b17023SJohn Marino if (--__remainder == 0) 508*e4b17023SJohn Marino return (__lookAhead - __skipOffset); // Success 509*e4b17023SJohn Marino } 510*e4b17023SJohn Marino if (__remainder > __tailSize) 511*e4b17023SJohn Marino return __last; // Failure 512*e4b17023SJohn Marino __lookAhead += __remainder; 513*e4b17023SJohn Marino __tailSize -= __remainder; 514*e4b17023SJohn Marino } 515*e4b17023SJohn Marino } 516*e4b17023SJohn Marino 517*e4b17023SJohn Marino // find_end for forward iterators. 518*e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2> 519*e4b17023SJohn Marino _ForwardIterator1 520*e4b17023SJohn Marino __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 521*e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2, 522*e4b17023SJohn Marino forward_iterator_tag, forward_iterator_tag) 523*e4b17023SJohn Marino { 524*e4b17023SJohn Marino if (__first2 == __last2) 525*e4b17023SJohn Marino return __last1; 526*e4b17023SJohn Marino else 527*e4b17023SJohn Marino { 528*e4b17023SJohn Marino _ForwardIterator1 __result = __last1; 529*e4b17023SJohn Marino while (1) 530*e4b17023SJohn Marino { 531*e4b17023SJohn Marino _ForwardIterator1 __new_result 532*e4b17023SJohn Marino = _GLIBCXX_STD_A::search(__first1, __last1, __first2, __last2); 533*e4b17023SJohn Marino if (__new_result == __last1) 534*e4b17023SJohn Marino return __result; 535*e4b17023SJohn Marino else 536*e4b17023SJohn Marino { 537*e4b17023SJohn Marino __result = __new_result; 538*e4b17023SJohn Marino __first1 = __new_result; 539*e4b17023SJohn Marino ++__first1; 540*e4b17023SJohn Marino } 541*e4b17023SJohn Marino } 542*e4b17023SJohn Marino } 543*e4b17023SJohn Marino } 544*e4b17023SJohn Marino 545*e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2, 546*e4b17023SJohn Marino typename _BinaryPredicate> 547*e4b17023SJohn Marino _ForwardIterator1 548*e4b17023SJohn Marino __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 549*e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2, 550*e4b17023SJohn Marino forward_iterator_tag, forward_iterator_tag, 551*e4b17023SJohn Marino _BinaryPredicate __comp) 552*e4b17023SJohn Marino { 553*e4b17023SJohn Marino if (__first2 == __last2) 554*e4b17023SJohn Marino return __last1; 555*e4b17023SJohn Marino else 556*e4b17023SJohn Marino { 557*e4b17023SJohn Marino _ForwardIterator1 __result = __last1; 558*e4b17023SJohn Marino while (1) 559*e4b17023SJohn Marino { 560*e4b17023SJohn Marino _ForwardIterator1 __new_result 561*e4b17023SJohn Marino = _GLIBCXX_STD_A::search(__first1, __last1, __first2, 562*e4b17023SJohn Marino __last2, __comp); 563*e4b17023SJohn Marino if (__new_result == __last1) 564*e4b17023SJohn Marino return __result; 565*e4b17023SJohn Marino else 566*e4b17023SJohn Marino { 567*e4b17023SJohn Marino __result = __new_result; 568*e4b17023SJohn Marino __first1 = __new_result; 569*e4b17023SJohn Marino ++__first1; 570*e4b17023SJohn Marino } 571*e4b17023SJohn Marino } 572*e4b17023SJohn Marino } 573*e4b17023SJohn Marino } 574*e4b17023SJohn Marino 575*e4b17023SJohn Marino // find_end for bidirectional iterators (much faster). 576*e4b17023SJohn Marino template<typename _BidirectionalIterator1, typename _BidirectionalIterator2> 577*e4b17023SJohn Marino _BidirectionalIterator1 578*e4b17023SJohn Marino __find_end(_BidirectionalIterator1 __first1, 579*e4b17023SJohn Marino _BidirectionalIterator1 __last1, 580*e4b17023SJohn Marino _BidirectionalIterator2 __first2, 581*e4b17023SJohn Marino _BidirectionalIterator2 __last2, 582*e4b17023SJohn Marino bidirectional_iterator_tag, bidirectional_iterator_tag) 583*e4b17023SJohn Marino { 584*e4b17023SJohn Marino // concept requirements 585*e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept< 586*e4b17023SJohn Marino _BidirectionalIterator1>) 587*e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept< 588*e4b17023SJohn Marino _BidirectionalIterator2>) 589*e4b17023SJohn Marino 590*e4b17023SJohn Marino typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; 591*e4b17023SJohn Marino typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; 592*e4b17023SJohn Marino 593*e4b17023SJohn Marino _RevIterator1 __rlast1(__first1); 594*e4b17023SJohn Marino _RevIterator2 __rlast2(__first2); 595*e4b17023SJohn Marino _RevIterator1 __rresult = _GLIBCXX_STD_A::search(_RevIterator1(__last1), 596*e4b17023SJohn Marino __rlast1, 597*e4b17023SJohn Marino _RevIterator2(__last2), 598*e4b17023SJohn Marino __rlast2); 599*e4b17023SJohn Marino 600*e4b17023SJohn Marino if (__rresult == __rlast1) 601*e4b17023SJohn Marino return __last1; 602*e4b17023SJohn Marino else 603*e4b17023SJohn Marino { 604*e4b17023SJohn Marino _BidirectionalIterator1 __result = __rresult.base(); 605*e4b17023SJohn Marino std::advance(__result, -std::distance(__first2, __last2)); 606*e4b17023SJohn Marino return __result; 607*e4b17023SJohn Marino } 608*e4b17023SJohn Marino } 609*e4b17023SJohn Marino 610*e4b17023SJohn Marino template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, 611*e4b17023SJohn Marino typename _BinaryPredicate> 612*e4b17023SJohn Marino _BidirectionalIterator1 613*e4b17023SJohn Marino __find_end(_BidirectionalIterator1 __first1, 614*e4b17023SJohn Marino _BidirectionalIterator1 __last1, 615*e4b17023SJohn Marino _BidirectionalIterator2 __first2, 616*e4b17023SJohn Marino _BidirectionalIterator2 __last2, 617*e4b17023SJohn Marino bidirectional_iterator_tag, bidirectional_iterator_tag, 618*e4b17023SJohn Marino _BinaryPredicate __comp) 619*e4b17023SJohn Marino { 620*e4b17023SJohn Marino // concept requirements 621*e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept< 622*e4b17023SJohn Marino _BidirectionalIterator1>) 623*e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept< 624*e4b17023SJohn Marino _BidirectionalIterator2>) 625*e4b17023SJohn Marino 626*e4b17023SJohn Marino typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; 627*e4b17023SJohn Marino typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; 628*e4b17023SJohn Marino 629*e4b17023SJohn Marino _RevIterator1 __rlast1(__first1); 630*e4b17023SJohn Marino _RevIterator2 __rlast2(__first2); 631*e4b17023SJohn Marino _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1, 632*e4b17023SJohn Marino _RevIterator2(__last2), __rlast2, 633*e4b17023SJohn Marino __comp); 634*e4b17023SJohn Marino 635*e4b17023SJohn Marino if (__rresult == __rlast1) 636*e4b17023SJohn Marino return __last1; 637*e4b17023SJohn Marino else 638*e4b17023SJohn Marino { 639*e4b17023SJohn Marino _BidirectionalIterator1 __result = __rresult.base(); 640*e4b17023SJohn Marino std::advance(__result, -std::distance(__first2, __last2)); 641*e4b17023SJohn Marino return __result; 642*e4b17023SJohn Marino } 643*e4b17023SJohn Marino } 644*e4b17023SJohn Marino 645*e4b17023SJohn Marino /** 646*e4b17023SJohn Marino * @brief Find last matching subsequence in a sequence. 647*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 648*e4b17023SJohn Marino * @param __first1 Start of range to search. 649*e4b17023SJohn Marino * @param __last1 End of range to search. 650*e4b17023SJohn Marino * @param __first2 Start of sequence to match. 651*e4b17023SJohn Marino * @param __last2 End of sequence to match. 652*e4b17023SJohn Marino * @return The last iterator @c i in the range 653*e4b17023SJohn Marino * @p [__first1,__last1-(__last2-__first2)) such that @c *(i+N) == 654*e4b17023SJohn Marino * @p *(__first2+N) for each @c N in the range @p 655*e4b17023SJohn Marino * [0,__last2-__first2), or @p __last1 if no such iterator exists. 656*e4b17023SJohn Marino * 657*e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for a sub-sequence that 658*e4b17023SJohn Marino * compares equal value-by-value with the sequence given by @p 659*e4b17023SJohn Marino * [__first2,__last2) and returns an iterator to the __first 660*e4b17023SJohn Marino * element of the sub-sequence, or @p __last1 if the sub-sequence 661*e4b17023SJohn Marino * is not found. The sub-sequence will be the last such 662*e4b17023SJohn Marino * subsequence contained in [__first,__last1). 663*e4b17023SJohn Marino * 664*e4b17023SJohn Marino * Because the sub-sequence must lie completely within the range @p 665*e4b17023SJohn Marino * [__first1,__last1) it must start at a position less than @p 666*e4b17023SJohn Marino * __last1-(__last2-__first2) where @p __last2-__first2 is the 667*e4b17023SJohn Marino * length of the sub-sequence. This means that the returned 668*e4b17023SJohn Marino * iterator @c i will be in the range @p 669*e4b17023SJohn Marino * [__first1,__last1-(__last2-__first2)) 670*e4b17023SJohn Marino */ 671*e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2> 672*e4b17023SJohn Marino inline _ForwardIterator1 673*e4b17023SJohn Marino find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 674*e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2) 675*e4b17023SJohn Marino { 676*e4b17023SJohn Marino // concept requirements 677*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) 678*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) 679*e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept< 680*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator1>::value_type, 681*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator2>::value_type>) 682*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1); 683*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2); 684*e4b17023SJohn Marino 685*e4b17023SJohn Marino return std::__find_end(__first1, __last1, __first2, __last2, 686*e4b17023SJohn Marino std::__iterator_category(__first1), 687*e4b17023SJohn Marino std::__iterator_category(__first2)); 688*e4b17023SJohn Marino } 689*e4b17023SJohn Marino 690*e4b17023SJohn Marino /** 691*e4b17023SJohn Marino * @brief Find last matching subsequence in a sequence using a predicate. 692*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 693*e4b17023SJohn Marino * @param __first1 Start of range to search. 694*e4b17023SJohn Marino * @param __last1 End of range to search. 695*e4b17023SJohn Marino * @param __first2 Start of sequence to match. 696*e4b17023SJohn Marino * @param __last2 End of sequence to match. 697*e4b17023SJohn Marino * @param __comp The predicate to use. 698*e4b17023SJohn Marino * @return The last iterator @c i in the range @p 699*e4b17023SJohn Marino * [__first1,__last1-(__last2-__first2)) such that @c 700*e4b17023SJohn Marino * predicate(*(i+N), @p (__first2+N)) is true for each @c N in the 701*e4b17023SJohn Marino * range @p [0,__last2-__first2), or @p __last1 if no such iterator 702*e4b17023SJohn Marino * exists. 703*e4b17023SJohn Marino * 704*e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for a sub-sequence that 705*e4b17023SJohn Marino * compares equal value-by-value with the sequence given by @p 706*e4b17023SJohn Marino * [__first2,__last2) using comp as a predicate and returns an 707*e4b17023SJohn Marino * iterator to the first element of the sub-sequence, or @p __last1 708*e4b17023SJohn Marino * if the sub-sequence is not found. The sub-sequence will be the 709*e4b17023SJohn Marino * last such subsequence contained in [__first,__last1). 710*e4b17023SJohn Marino * 711*e4b17023SJohn Marino * Because the sub-sequence must lie completely within the range @p 712*e4b17023SJohn Marino * [__first1,__last1) it must start at a position less than @p 713*e4b17023SJohn Marino * __last1-(__last2-__first2) where @p __last2-__first2 is the 714*e4b17023SJohn Marino * length of the sub-sequence. This means that the returned 715*e4b17023SJohn Marino * iterator @c i will be in the range @p 716*e4b17023SJohn Marino * [__first1,__last1-(__last2-__first2)) 717*e4b17023SJohn Marino */ 718*e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2, 719*e4b17023SJohn Marino typename _BinaryPredicate> 720*e4b17023SJohn Marino inline _ForwardIterator1 721*e4b17023SJohn Marino find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 722*e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2, 723*e4b17023SJohn Marino _BinaryPredicate __comp) 724*e4b17023SJohn Marino { 725*e4b17023SJohn Marino // concept requirements 726*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) 727*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) 728*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 729*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator1>::value_type, 730*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator2>::value_type>) 731*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1); 732*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2); 733*e4b17023SJohn Marino 734*e4b17023SJohn Marino return std::__find_end(__first1, __last1, __first2, __last2, 735*e4b17023SJohn Marino std::__iterator_category(__first1), 736*e4b17023SJohn Marino std::__iterator_category(__first2), 737*e4b17023SJohn Marino __comp); 738*e4b17023SJohn Marino } 739*e4b17023SJohn Marino 740*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 741*e4b17023SJohn Marino /** 742*e4b17023SJohn Marino * @brief Checks that a predicate is true for all the elements 743*e4b17023SJohn Marino * of a sequence. 744*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 745*e4b17023SJohn Marino * @param __first An input iterator. 746*e4b17023SJohn Marino * @param __last An input iterator. 747*e4b17023SJohn Marino * @param __pred A predicate. 748*e4b17023SJohn Marino * @return True if the check is true, false otherwise. 749*e4b17023SJohn Marino * 750*e4b17023SJohn Marino * Returns true if @p __pred is true for each element in the range 751*e4b17023SJohn Marino * @p [__first,__last), and false otherwise. 752*e4b17023SJohn Marino */ 753*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 754*e4b17023SJohn Marino inline bool 755*e4b17023SJohn Marino all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 756*e4b17023SJohn Marino { return __last == std::find_if_not(__first, __last, __pred); } 757*e4b17023SJohn Marino 758*e4b17023SJohn Marino /** 759*e4b17023SJohn Marino * @brief Checks that a predicate is false for all the elements 760*e4b17023SJohn Marino * of a sequence. 761*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 762*e4b17023SJohn Marino * @param __first An input iterator. 763*e4b17023SJohn Marino * @param __last An input iterator. 764*e4b17023SJohn Marino * @param __pred A predicate. 765*e4b17023SJohn Marino * @return True if the check is true, false otherwise. 766*e4b17023SJohn Marino * 767*e4b17023SJohn Marino * Returns true if @p __pred is false for each element in the range 768*e4b17023SJohn Marino * @p [__first,__last), and false otherwise. 769*e4b17023SJohn Marino */ 770*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 771*e4b17023SJohn Marino inline bool 772*e4b17023SJohn Marino none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 773*e4b17023SJohn Marino { return __last == _GLIBCXX_STD_A::find_if(__first, __last, __pred); } 774*e4b17023SJohn Marino 775*e4b17023SJohn Marino /** 776*e4b17023SJohn Marino * @brief Checks that a predicate is false for at least an element 777*e4b17023SJohn Marino * of a sequence. 778*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 779*e4b17023SJohn Marino * @param __first An input iterator. 780*e4b17023SJohn Marino * @param __last An input iterator. 781*e4b17023SJohn Marino * @param __pred A predicate. 782*e4b17023SJohn Marino * @return True if the check is true, false otherwise. 783*e4b17023SJohn Marino * 784*e4b17023SJohn Marino * Returns true if an element exists in the range @p 785*e4b17023SJohn Marino * [__first,__last) such that @p __pred is true, and false 786*e4b17023SJohn Marino * otherwise. 787*e4b17023SJohn Marino */ 788*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 789*e4b17023SJohn Marino inline bool 790*e4b17023SJohn Marino any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 791*e4b17023SJohn Marino { return !std::none_of(__first, __last, __pred); } 792*e4b17023SJohn Marino 793*e4b17023SJohn Marino /** 794*e4b17023SJohn Marino * @brief Find the first element in a sequence for which a 795*e4b17023SJohn Marino * predicate is false. 796*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 797*e4b17023SJohn Marino * @param __first An input iterator. 798*e4b17023SJohn Marino * @param __last An input iterator. 799*e4b17023SJohn Marino * @param __pred A predicate. 800*e4b17023SJohn Marino * @return The first iterator @c i in the range @p [__first,__last) 801*e4b17023SJohn Marino * such that @p __pred(*i) is false, or @p __last if no such iterator exists. 802*e4b17023SJohn Marino */ 803*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 804*e4b17023SJohn Marino inline _InputIterator 805*e4b17023SJohn Marino find_if_not(_InputIterator __first, _InputIterator __last, 806*e4b17023SJohn Marino _Predicate __pred) 807*e4b17023SJohn Marino { 808*e4b17023SJohn Marino // concept requirements 809*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 810*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 811*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 812*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 813*e4b17023SJohn Marino return std::__find_if_not(__first, __last, __pred); 814*e4b17023SJohn Marino } 815*e4b17023SJohn Marino 816*e4b17023SJohn Marino /** 817*e4b17023SJohn Marino * @brief Checks whether the sequence is partitioned. 818*e4b17023SJohn Marino * @ingroup mutating_algorithms 819*e4b17023SJohn Marino * @param __first An input iterator. 820*e4b17023SJohn Marino * @param __last An input iterator. 821*e4b17023SJohn Marino * @param __pred A predicate. 822*e4b17023SJohn Marino * @return True if the range @p [__first,__last) is partioned by @p __pred, 823*e4b17023SJohn Marino * i.e. if all elements that satisfy @p __pred appear before those that 824*e4b17023SJohn Marino * do not. 825*e4b17023SJohn Marino */ 826*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 827*e4b17023SJohn Marino inline bool 828*e4b17023SJohn Marino is_partitioned(_InputIterator __first, _InputIterator __last, 829*e4b17023SJohn Marino _Predicate __pred) 830*e4b17023SJohn Marino { 831*e4b17023SJohn Marino __first = std::find_if_not(__first, __last, __pred); 832*e4b17023SJohn Marino return std::none_of(__first, __last, __pred); 833*e4b17023SJohn Marino } 834*e4b17023SJohn Marino 835*e4b17023SJohn Marino /** 836*e4b17023SJohn Marino * @brief Find the partition point of a partitioned range. 837*e4b17023SJohn Marino * @ingroup mutating_algorithms 838*e4b17023SJohn Marino * @param __first An iterator. 839*e4b17023SJohn Marino * @param __last Another iterator. 840*e4b17023SJohn Marino * @param __pred A predicate. 841*e4b17023SJohn Marino * @return An iterator @p mid such that @p all_of(__first, mid, __pred) 842*e4b17023SJohn Marino * and @p none_of(mid, __last, __pred) are both true. 843*e4b17023SJohn Marino */ 844*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate> 845*e4b17023SJohn Marino _ForwardIterator 846*e4b17023SJohn Marino partition_point(_ForwardIterator __first, _ForwardIterator __last, 847*e4b17023SJohn Marino _Predicate __pred) 848*e4b17023SJohn Marino { 849*e4b17023SJohn Marino // concept requirements 850*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 851*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 852*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 853*e4b17023SJohn Marino 854*e4b17023SJohn Marino // A specific debug-mode test will be necessary... 855*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 856*e4b17023SJohn Marino 857*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type 858*e4b17023SJohn Marino _DistanceType; 859*e4b17023SJohn Marino 860*e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last); 861*e4b17023SJohn Marino _DistanceType __half; 862*e4b17023SJohn Marino _ForwardIterator __middle; 863*e4b17023SJohn Marino 864*e4b17023SJohn Marino while (__len > 0) 865*e4b17023SJohn Marino { 866*e4b17023SJohn Marino __half = __len >> 1; 867*e4b17023SJohn Marino __middle = __first; 868*e4b17023SJohn Marino std::advance(__middle, __half); 869*e4b17023SJohn Marino if (__pred(*__middle)) 870*e4b17023SJohn Marino { 871*e4b17023SJohn Marino __first = __middle; 872*e4b17023SJohn Marino ++__first; 873*e4b17023SJohn Marino __len = __len - __half - 1; 874*e4b17023SJohn Marino } 875*e4b17023SJohn Marino else 876*e4b17023SJohn Marino __len = __half; 877*e4b17023SJohn Marino } 878*e4b17023SJohn Marino return __first; 879*e4b17023SJohn Marino } 880*e4b17023SJohn Marino #endif 881*e4b17023SJohn Marino 882*e4b17023SJohn Marino 883*e4b17023SJohn Marino /** 884*e4b17023SJohn Marino * @brief Copy a sequence, removing elements of a given value. 885*e4b17023SJohn Marino * @ingroup mutating_algorithms 886*e4b17023SJohn Marino * @param __first An input iterator. 887*e4b17023SJohn Marino * @param __last An input iterator. 888*e4b17023SJohn Marino * @param __result An output iterator. 889*e4b17023SJohn Marino * @param __value The value to be removed. 890*e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence. 891*e4b17023SJohn Marino * 892*e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) not equal 893*e4b17023SJohn Marino * to @p __value to the range beginning at @p __result. 894*e4b17023SJohn Marino * remove_copy() is stable, so the relative order of elements that 895*e4b17023SJohn Marino * are copied is unchanged. 896*e4b17023SJohn Marino */ 897*e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator, typename _Tp> 898*e4b17023SJohn Marino _OutputIterator 899*e4b17023SJohn Marino remove_copy(_InputIterator __first, _InputIterator __last, 900*e4b17023SJohn Marino _OutputIterator __result, const _Tp& __value) 901*e4b17023SJohn Marino { 902*e4b17023SJohn Marino // concept requirements 903*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 904*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 905*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 906*e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept< 907*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type, _Tp>) 908*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 909*e4b17023SJohn Marino 910*e4b17023SJohn Marino for (; __first != __last; ++__first) 911*e4b17023SJohn Marino if (!(*__first == __value)) 912*e4b17023SJohn Marino { 913*e4b17023SJohn Marino *__result = *__first; 914*e4b17023SJohn Marino ++__result; 915*e4b17023SJohn Marino } 916*e4b17023SJohn Marino return __result; 917*e4b17023SJohn Marino } 918*e4b17023SJohn Marino 919*e4b17023SJohn Marino /** 920*e4b17023SJohn Marino * @brief Copy a sequence, removing elements for which a predicate is true. 921*e4b17023SJohn Marino * @ingroup mutating_algorithms 922*e4b17023SJohn Marino * @param __first An input iterator. 923*e4b17023SJohn Marino * @param __last An input iterator. 924*e4b17023SJohn Marino * @param __result An output iterator. 925*e4b17023SJohn Marino * @param __pred A predicate. 926*e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence. 927*e4b17023SJohn Marino * 928*e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) for which 929*e4b17023SJohn Marino * @p __pred returns false to the range beginning at @p __result. 930*e4b17023SJohn Marino * 931*e4b17023SJohn Marino * remove_copy_if() is stable, so the relative order of elements that are 932*e4b17023SJohn Marino * copied is unchanged. 933*e4b17023SJohn Marino */ 934*e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator, 935*e4b17023SJohn Marino typename _Predicate> 936*e4b17023SJohn Marino _OutputIterator 937*e4b17023SJohn Marino remove_copy_if(_InputIterator __first, _InputIterator __last, 938*e4b17023SJohn Marino _OutputIterator __result, _Predicate __pred) 939*e4b17023SJohn Marino { 940*e4b17023SJohn Marino // concept requirements 941*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 942*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 943*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 944*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 945*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 946*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 947*e4b17023SJohn Marino 948*e4b17023SJohn Marino for (; __first != __last; ++__first) 949*e4b17023SJohn Marino if (!bool(__pred(*__first))) 950*e4b17023SJohn Marino { 951*e4b17023SJohn Marino *__result = *__first; 952*e4b17023SJohn Marino ++__result; 953*e4b17023SJohn Marino } 954*e4b17023SJohn Marino return __result; 955*e4b17023SJohn Marino } 956*e4b17023SJohn Marino 957*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 958*e4b17023SJohn Marino /** 959*e4b17023SJohn Marino * @brief Copy the elements of a sequence for which a predicate is true. 960*e4b17023SJohn Marino * @ingroup mutating_algorithms 961*e4b17023SJohn Marino * @param __first An input iterator. 962*e4b17023SJohn Marino * @param __last An input iterator. 963*e4b17023SJohn Marino * @param __result An output iterator. 964*e4b17023SJohn Marino * @param __pred A predicate. 965*e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence. 966*e4b17023SJohn Marino * 967*e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) for which 968*e4b17023SJohn Marino * @p __pred returns true to the range beginning at @p __result. 969*e4b17023SJohn Marino * 970*e4b17023SJohn Marino * copy_if() is stable, so the relative order of elements that are 971*e4b17023SJohn Marino * copied is unchanged. 972*e4b17023SJohn Marino */ 973*e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator, 974*e4b17023SJohn Marino typename _Predicate> 975*e4b17023SJohn Marino _OutputIterator 976*e4b17023SJohn Marino copy_if(_InputIterator __first, _InputIterator __last, 977*e4b17023SJohn Marino _OutputIterator __result, _Predicate __pred) 978*e4b17023SJohn Marino { 979*e4b17023SJohn Marino // concept requirements 980*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 981*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 982*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 983*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 984*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 985*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 986*e4b17023SJohn Marino 987*e4b17023SJohn Marino for (; __first != __last; ++__first) 988*e4b17023SJohn Marino if (__pred(*__first)) 989*e4b17023SJohn Marino { 990*e4b17023SJohn Marino *__result = *__first; 991*e4b17023SJohn Marino ++__result; 992*e4b17023SJohn Marino } 993*e4b17023SJohn Marino return __result; 994*e4b17023SJohn Marino } 995*e4b17023SJohn Marino 996*e4b17023SJohn Marino 997*e4b17023SJohn Marino template<typename _InputIterator, typename _Size, typename _OutputIterator> 998*e4b17023SJohn Marino _OutputIterator 999*e4b17023SJohn Marino __copy_n(_InputIterator __first, _Size __n, 1000*e4b17023SJohn Marino _OutputIterator __result, input_iterator_tag) 1001*e4b17023SJohn Marino { 1002*e4b17023SJohn Marino if (__n > 0) 1003*e4b17023SJohn Marino { 1004*e4b17023SJohn Marino while (true) 1005*e4b17023SJohn Marino { 1006*e4b17023SJohn Marino *__result = *__first; 1007*e4b17023SJohn Marino ++__result; 1008*e4b17023SJohn Marino if (--__n > 0) 1009*e4b17023SJohn Marino ++__first; 1010*e4b17023SJohn Marino else 1011*e4b17023SJohn Marino break; 1012*e4b17023SJohn Marino } 1013*e4b17023SJohn Marino } 1014*e4b17023SJohn Marino return __result; 1015*e4b17023SJohn Marino } 1016*e4b17023SJohn Marino 1017*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Size, 1018*e4b17023SJohn Marino typename _OutputIterator> 1019*e4b17023SJohn Marino inline _OutputIterator 1020*e4b17023SJohn Marino __copy_n(_RandomAccessIterator __first, _Size __n, 1021*e4b17023SJohn Marino _OutputIterator __result, random_access_iterator_tag) 1022*e4b17023SJohn Marino { return std::copy(__first, __first + __n, __result); } 1023*e4b17023SJohn Marino 1024*e4b17023SJohn Marino /** 1025*e4b17023SJohn Marino * @brief Copies the range [first,first+n) into [result,result+n). 1026*e4b17023SJohn Marino * @ingroup mutating_algorithms 1027*e4b17023SJohn Marino * @param __first An input iterator. 1028*e4b17023SJohn Marino * @param __n The number of elements to copy. 1029*e4b17023SJohn Marino * @param __result An output iterator. 1030*e4b17023SJohn Marino * @return result+n. 1031*e4b17023SJohn Marino * 1032*e4b17023SJohn Marino * This inline function will boil down to a call to @c memmove whenever 1033*e4b17023SJohn Marino * possible. Failing that, if random access iterators are passed, then the 1034*e4b17023SJohn Marino * loop count will be known (and therefore a candidate for compiler 1035*e4b17023SJohn Marino * optimizations such as unrolling). 1036*e4b17023SJohn Marino */ 1037*e4b17023SJohn Marino template<typename _InputIterator, typename _Size, typename _OutputIterator> 1038*e4b17023SJohn Marino inline _OutputIterator 1039*e4b17023SJohn Marino copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) 1040*e4b17023SJohn Marino { 1041*e4b17023SJohn Marino // concept requirements 1042*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 1043*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 1044*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 1045*e4b17023SJohn Marino 1046*e4b17023SJohn Marino return std::__copy_n(__first, __n, __result, 1047*e4b17023SJohn Marino std::__iterator_category(__first)); 1048*e4b17023SJohn Marino } 1049*e4b17023SJohn Marino 1050*e4b17023SJohn Marino /** 1051*e4b17023SJohn Marino * @brief Copy the elements of a sequence to separate output sequences 1052*e4b17023SJohn Marino * depending on the truth value of a predicate. 1053*e4b17023SJohn Marino * @ingroup mutating_algorithms 1054*e4b17023SJohn Marino * @param __first An input iterator. 1055*e4b17023SJohn Marino * @param __last An input iterator. 1056*e4b17023SJohn Marino * @param __out_true An output iterator. 1057*e4b17023SJohn Marino * @param __out_false An output iterator. 1058*e4b17023SJohn Marino * @param __pred A predicate. 1059*e4b17023SJohn Marino * @return A pair designating the ends of the resulting sequences. 1060*e4b17023SJohn Marino * 1061*e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) for which 1062*e4b17023SJohn Marino * @p __pred returns true to the range beginning at @p out_true 1063*e4b17023SJohn Marino * and each element for which @p __pred returns false to @p __out_false. 1064*e4b17023SJohn Marino */ 1065*e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator1, 1066*e4b17023SJohn Marino typename _OutputIterator2, typename _Predicate> 1067*e4b17023SJohn Marino pair<_OutputIterator1, _OutputIterator2> 1068*e4b17023SJohn Marino partition_copy(_InputIterator __first, _InputIterator __last, 1069*e4b17023SJohn Marino _OutputIterator1 __out_true, _OutputIterator2 __out_false, 1070*e4b17023SJohn Marino _Predicate __pred) 1071*e4b17023SJohn Marino { 1072*e4b17023SJohn Marino // concept requirements 1073*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 1074*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator1, 1075*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 1076*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator2, 1077*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 1078*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 1079*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 1080*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 1081*e4b17023SJohn Marino 1082*e4b17023SJohn Marino for (; __first != __last; ++__first) 1083*e4b17023SJohn Marino if (__pred(*__first)) 1084*e4b17023SJohn Marino { 1085*e4b17023SJohn Marino *__out_true = *__first; 1086*e4b17023SJohn Marino ++__out_true; 1087*e4b17023SJohn Marino } 1088*e4b17023SJohn Marino else 1089*e4b17023SJohn Marino { 1090*e4b17023SJohn Marino *__out_false = *__first; 1091*e4b17023SJohn Marino ++__out_false; 1092*e4b17023SJohn Marino } 1093*e4b17023SJohn Marino 1094*e4b17023SJohn Marino return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); 1095*e4b17023SJohn Marino } 1096*e4b17023SJohn Marino #endif 1097*e4b17023SJohn Marino 1098*e4b17023SJohn Marino /** 1099*e4b17023SJohn Marino * @brief Remove elements from a sequence. 1100*e4b17023SJohn Marino * @ingroup mutating_algorithms 1101*e4b17023SJohn Marino * @param __first An input iterator. 1102*e4b17023SJohn Marino * @param __last An input iterator. 1103*e4b17023SJohn Marino * @param __value The value to be removed. 1104*e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence. 1105*e4b17023SJohn Marino * 1106*e4b17023SJohn Marino * All elements equal to @p __value are removed from the range 1107*e4b17023SJohn Marino * @p [__first,__last). 1108*e4b17023SJohn Marino * 1109*e4b17023SJohn Marino * remove() is stable, so the relative order of elements that are 1110*e4b17023SJohn Marino * not removed is unchanged. 1111*e4b17023SJohn Marino * 1112*e4b17023SJohn Marino * Elements between the end of the resulting sequence and @p __last 1113*e4b17023SJohn Marino * are still present, but their value is unspecified. 1114*e4b17023SJohn Marino */ 1115*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp> 1116*e4b17023SJohn Marino _ForwardIterator 1117*e4b17023SJohn Marino remove(_ForwardIterator __first, _ForwardIterator __last, 1118*e4b17023SJohn Marino const _Tp& __value) 1119*e4b17023SJohn Marino { 1120*e4b17023SJohn Marino // concept requirements 1121*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 1122*e4b17023SJohn Marino _ForwardIterator>) 1123*e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept< 1124*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, _Tp>) 1125*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 1126*e4b17023SJohn Marino 1127*e4b17023SJohn Marino __first = _GLIBCXX_STD_A::find(__first, __last, __value); 1128*e4b17023SJohn Marino if(__first == __last) 1129*e4b17023SJohn Marino return __first; 1130*e4b17023SJohn Marino _ForwardIterator __result = __first; 1131*e4b17023SJohn Marino ++__first; 1132*e4b17023SJohn Marino for(; __first != __last; ++__first) 1133*e4b17023SJohn Marino if(!(*__first == __value)) 1134*e4b17023SJohn Marino { 1135*e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first); 1136*e4b17023SJohn Marino ++__result; 1137*e4b17023SJohn Marino } 1138*e4b17023SJohn Marino return __result; 1139*e4b17023SJohn Marino } 1140*e4b17023SJohn Marino 1141*e4b17023SJohn Marino /** 1142*e4b17023SJohn Marino * @brief Remove elements from a sequence using a predicate. 1143*e4b17023SJohn Marino * @ingroup mutating_algorithms 1144*e4b17023SJohn Marino * @param __first A forward iterator. 1145*e4b17023SJohn Marino * @param __last A forward iterator. 1146*e4b17023SJohn Marino * @param __pred A predicate. 1147*e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence. 1148*e4b17023SJohn Marino * 1149*e4b17023SJohn Marino * All elements for which @p __pred returns true are removed from the range 1150*e4b17023SJohn Marino * @p [__first,__last). 1151*e4b17023SJohn Marino * 1152*e4b17023SJohn Marino * remove_if() is stable, so the relative order of elements that are 1153*e4b17023SJohn Marino * not removed is unchanged. 1154*e4b17023SJohn Marino * 1155*e4b17023SJohn Marino * Elements between the end of the resulting sequence and @p __last 1156*e4b17023SJohn Marino * are still present, but their value is unspecified. 1157*e4b17023SJohn Marino */ 1158*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate> 1159*e4b17023SJohn Marino _ForwardIterator 1160*e4b17023SJohn Marino remove_if(_ForwardIterator __first, _ForwardIterator __last, 1161*e4b17023SJohn Marino _Predicate __pred) 1162*e4b17023SJohn Marino { 1163*e4b17023SJohn Marino // concept requirements 1164*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 1165*e4b17023SJohn Marino _ForwardIterator>) 1166*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 1167*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 1168*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 1169*e4b17023SJohn Marino 1170*e4b17023SJohn Marino __first = _GLIBCXX_STD_A::find_if(__first, __last, __pred); 1171*e4b17023SJohn Marino if(__first == __last) 1172*e4b17023SJohn Marino return __first; 1173*e4b17023SJohn Marino _ForwardIterator __result = __first; 1174*e4b17023SJohn Marino ++__first; 1175*e4b17023SJohn Marino for(; __first != __last; ++__first) 1176*e4b17023SJohn Marino if(!bool(__pred(*__first))) 1177*e4b17023SJohn Marino { 1178*e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first); 1179*e4b17023SJohn Marino ++__result; 1180*e4b17023SJohn Marino } 1181*e4b17023SJohn Marino return __result; 1182*e4b17023SJohn Marino } 1183*e4b17023SJohn Marino 1184*e4b17023SJohn Marino /** 1185*e4b17023SJohn Marino * @brief Remove consecutive duplicate values from a sequence. 1186*e4b17023SJohn Marino * @ingroup mutating_algorithms 1187*e4b17023SJohn Marino * @param __first A forward iterator. 1188*e4b17023SJohn Marino * @param __last A forward iterator. 1189*e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence. 1190*e4b17023SJohn Marino * 1191*e4b17023SJohn Marino * Removes all but the first element from each group of consecutive 1192*e4b17023SJohn Marino * values that compare equal. 1193*e4b17023SJohn Marino * unique() is stable, so the relative order of elements that are 1194*e4b17023SJohn Marino * not removed is unchanged. 1195*e4b17023SJohn Marino * Elements between the end of the resulting sequence and @p __last 1196*e4b17023SJohn Marino * are still present, but their value is unspecified. 1197*e4b17023SJohn Marino */ 1198*e4b17023SJohn Marino template<typename _ForwardIterator> 1199*e4b17023SJohn Marino _ForwardIterator 1200*e4b17023SJohn Marino unique(_ForwardIterator __first, _ForwardIterator __last) 1201*e4b17023SJohn Marino { 1202*e4b17023SJohn Marino // concept requirements 1203*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 1204*e4b17023SJohn Marino _ForwardIterator>) 1205*e4b17023SJohn Marino __glibcxx_function_requires(_EqualityComparableConcept< 1206*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 1207*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 1208*e4b17023SJohn Marino 1209*e4b17023SJohn Marino // Skip the beginning, if already unique. 1210*e4b17023SJohn Marino __first = _GLIBCXX_STD_A::adjacent_find(__first, __last); 1211*e4b17023SJohn Marino if (__first == __last) 1212*e4b17023SJohn Marino return __last; 1213*e4b17023SJohn Marino 1214*e4b17023SJohn Marino // Do the real copy work. 1215*e4b17023SJohn Marino _ForwardIterator __dest = __first; 1216*e4b17023SJohn Marino ++__first; 1217*e4b17023SJohn Marino while (++__first != __last) 1218*e4b17023SJohn Marino if (!(*__dest == *__first)) 1219*e4b17023SJohn Marino *++__dest = _GLIBCXX_MOVE(*__first); 1220*e4b17023SJohn Marino return ++__dest; 1221*e4b17023SJohn Marino } 1222*e4b17023SJohn Marino 1223*e4b17023SJohn Marino /** 1224*e4b17023SJohn Marino * @brief Remove consecutive values from a sequence using a predicate. 1225*e4b17023SJohn Marino * @ingroup mutating_algorithms 1226*e4b17023SJohn Marino * @param __first A forward iterator. 1227*e4b17023SJohn Marino * @param __last A forward iterator. 1228*e4b17023SJohn Marino * @param __binary_pred A binary predicate. 1229*e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence. 1230*e4b17023SJohn Marino * 1231*e4b17023SJohn Marino * Removes all but the first element from each group of consecutive 1232*e4b17023SJohn Marino * values for which @p __binary_pred returns true. 1233*e4b17023SJohn Marino * unique() is stable, so the relative order of elements that are 1234*e4b17023SJohn Marino * not removed is unchanged. 1235*e4b17023SJohn Marino * Elements between the end of the resulting sequence and @p __last 1236*e4b17023SJohn Marino * are still present, but their value is unspecified. 1237*e4b17023SJohn Marino */ 1238*e4b17023SJohn Marino template<typename _ForwardIterator, typename _BinaryPredicate> 1239*e4b17023SJohn Marino _ForwardIterator 1240*e4b17023SJohn Marino unique(_ForwardIterator __first, _ForwardIterator __last, 1241*e4b17023SJohn Marino _BinaryPredicate __binary_pred) 1242*e4b17023SJohn Marino { 1243*e4b17023SJohn Marino // concept requirements 1244*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 1245*e4b17023SJohn Marino _ForwardIterator>) 1246*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 1247*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, 1248*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 1249*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 1250*e4b17023SJohn Marino 1251*e4b17023SJohn Marino // Skip the beginning, if already unique. 1252*e4b17023SJohn Marino __first = _GLIBCXX_STD_A::adjacent_find(__first, __last, __binary_pred); 1253*e4b17023SJohn Marino if (__first == __last) 1254*e4b17023SJohn Marino return __last; 1255*e4b17023SJohn Marino 1256*e4b17023SJohn Marino // Do the real copy work. 1257*e4b17023SJohn Marino _ForwardIterator __dest = __first; 1258*e4b17023SJohn Marino ++__first; 1259*e4b17023SJohn Marino while (++__first != __last) 1260*e4b17023SJohn Marino if (!bool(__binary_pred(*__dest, *__first))) 1261*e4b17023SJohn Marino *++__dest = _GLIBCXX_MOVE(*__first); 1262*e4b17023SJohn Marino return ++__dest; 1263*e4b17023SJohn Marino } 1264*e4b17023SJohn Marino 1265*e4b17023SJohn Marino /** 1266*e4b17023SJohn Marino * This is an uglified unique_copy(_InputIterator, _InputIterator, 1267*e4b17023SJohn Marino * _OutputIterator) 1268*e4b17023SJohn Marino * overloaded for forward iterators and output iterator as result. 1269*e4b17023SJohn Marino */ 1270*e4b17023SJohn Marino template<typename _ForwardIterator, typename _OutputIterator> 1271*e4b17023SJohn Marino _OutputIterator 1272*e4b17023SJohn Marino __unique_copy(_ForwardIterator __first, _ForwardIterator __last, 1273*e4b17023SJohn Marino _OutputIterator __result, 1274*e4b17023SJohn Marino forward_iterator_tag, output_iterator_tag) 1275*e4b17023SJohn Marino { 1276*e4b17023SJohn Marino // concept requirements -- taken care of in dispatching function 1277*e4b17023SJohn Marino _ForwardIterator __next = __first; 1278*e4b17023SJohn Marino *__result = *__first; 1279*e4b17023SJohn Marino while (++__next != __last) 1280*e4b17023SJohn Marino if (!(*__first == *__next)) 1281*e4b17023SJohn Marino { 1282*e4b17023SJohn Marino __first = __next; 1283*e4b17023SJohn Marino *++__result = *__first; 1284*e4b17023SJohn Marino } 1285*e4b17023SJohn Marino return ++__result; 1286*e4b17023SJohn Marino } 1287*e4b17023SJohn Marino 1288*e4b17023SJohn Marino /** 1289*e4b17023SJohn Marino * This is an uglified unique_copy(_InputIterator, _InputIterator, 1290*e4b17023SJohn Marino * _OutputIterator) 1291*e4b17023SJohn Marino * overloaded for input iterators and output iterator as result. 1292*e4b17023SJohn Marino */ 1293*e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator> 1294*e4b17023SJohn Marino _OutputIterator 1295*e4b17023SJohn Marino __unique_copy(_InputIterator __first, _InputIterator __last, 1296*e4b17023SJohn Marino _OutputIterator __result, 1297*e4b17023SJohn Marino input_iterator_tag, output_iterator_tag) 1298*e4b17023SJohn Marino { 1299*e4b17023SJohn Marino // concept requirements -- taken care of in dispatching function 1300*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type __value = *__first; 1301*e4b17023SJohn Marino *__result = __value; 1302*e4b17023SJohn Marino while (++__first != __last) 1303*e4b17023SJohn Marino if (!(__value == *__first)) 1304*e4b17023SJohn Marino { 1305*e4b17023SJohn Marino __value = *__first; 1306*e4b17023SJohn Marino *++__result = __value; 1307*e4b17023SJohn Marino } 1308*e4b17023SJohn Marino return ++__result; 1309*e4b17023SJohn Marino } 1310*e4b17023SJohn Marino 1311*e4b17023SJohn Marino /** 1312*e4b17023SJohn Marino * This is an uglified unique_copy(_InputIterator, _InputIterator, 1313*e4b17023SJohn Marino * _OutputIterator) 1314*e4b17023SJohn Marino * overloaded for input iterators and forward iterator as result. 1315*e4b17023SJohn Marino */ 1316*e4b17023SJohn Marino template<typename _InputIterator, typename _ForwardIterator> 1317*e4b17023SJohn Marino _ForwardIterator 1318*e4b17023SJohn Marino __unique_copy(_InputIterator __first, _InputIterator __last, 1319*e4b17023SJohn Marino _ForwardIterator __result, 1320*e4b17023SJohn Marino input_iterator_tag, forward_iterator_tag) 1321*e4b17023SJohn Marino { 1322*e4b17023SJohn Marino // concept requirements -- taken care of in dispatching function 1323*e4b17023SJohn Marino *__result = *__first; 1324*e4b17023SJohn Marino while (++__first != __last) 1325*e4b17023SJohn Marino if (!(*__result == *__first)) 1326*e4b17023SJohn Marino *++__result = *__first; 1327*e4b17023SJohn Marino return ++__result; 1328*e4b17023SJohn Marino } 1329*e4b17023SJohn Marino 1330*e4b17023SJohn Marino /** 1331*e4b17023SJohn Marino * This is an uglified 1332*e4b17023SJohn Marino * unique_copy(_InputIterator, _InputIterator, _OutputIterator, 1333*e4b17023SJohn Marino * _BinaryPredicate) 1334*e4b17023SJohn Marino * overloaded for forward iterators and output iterator as result. 1335*e4b17023SJohn Marino */ 1336*e4b17023SJohn Marino template<typename _ForwardIterator, typename _OutputIterator, 1337*e4b17023SJohn Marino typename _BinaryPredicate> 1338*e4b17023SJohn Marino _OutputIterator 1339*e4b17023SJohn Marino __unique_copy(_ForwardIterator __first, _ForwardIterator __last, 1340*e4b17023SJohn Marino _OutputIterator __result, _BinaryPredicate __binary_pred, 1341*e4b17023SJohn Marino forward_iterator_tag, output_iterator_tag) 1342*e4b17023SJohn Marino { 1343*e4b17023SJohn Marino // concept requirements -- iterators already checked 1344*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 1345*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, 1346*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 1347*e4b17023SJohn Marino 1348*e4b17023SJohn Marino _ForwardIterator __next = __first; 1349*e4b17023SJohn Marino *__result = *__first; 1350*e4b17023SJohn Marino while (++__next != __last) 1351*e4b17023SJohn Marino if (!bool(__binary_pred(*__first, *__next))) 1352*e4b17023SJohn Marino { 1353*e4b17023SJohn Marino __first = __next; 1354*e4b17023SJohn Marino *++__result = *__first; 1355*e4b17023SJohn Marino } 1356*e4b17023SJohn Marino return ++__result; 1357*e4b17023SJohn Marino } 1358*e4b17023SJohn Marino 1359*e4b17023SJohn Marino /** 1360*e4b17023SJohn Marino * This is an uglified 1361*e4b17023SJohn Marino * unique_copy(_InputIterator, _InputIterator, _OutputIterator, 1362*e4b17023SJohn Marino * _BinaryPredicate) 1363*e4b17023SJohn Marino * overloaded for input iterators and output iterator as result. 1364*e4b17023SJohn Marino */ 1365*e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator, 1366*e4b17023SJohn Marino typename _BinaryPredicate> 1367*e4b17023SJohn Marino _OutputIterator 1368*e4b17023SJohn Marino __unique_copy(_InputIterator __first, _InputIterator __last, 1369*e4b17023SJohn Marino _OutputIterator __result, _BinaryPredicate __binary_pred, 1370*e4b17023SJohn Marino input_iterator_tag, output_iterator_tag) 1371*e4b17023SJohn Marino { 1372*e4b17023SJohn Marino // concept requirements -- iterators already checked 1373*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 1374*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type, 1375*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 1376*e4b17023SJohn Marino 1377*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type __value = *__first; 1378*e4b17023SJohn Marino *__result = __value; 1379*e4b17023SJohn Marino while (++__first != __last) 1380*e4b17023SJohn Marino if (!bool(__binary_pred(__value, *__first))) 1381*e4b17023SJohn Marino { 1382*e4b17023SJohn Marino __value = *__first; 1383*e4b17023SJohn Marino *++__result = __value; 1384*e4b17023SJohn Marino } 1385*e4b17023SJohn Marino return ++__result; 1386*e4b17023SJohn Marino } 1387*e4b17023SJohn Marino 1388*e4b17023SJohn Marino /** 1389*e4b17023SJohn Marino * This is an uglified 1390*e4b17023SJohn Marino * unique_copy(_InputIterator, _InputIterator, _OutputIterator, 1391*e4b17023SJohn Marino * _BinaryPredicate) 1392*e4b17023SJohn Marino * overloaded for input iterators and forward iterator as result. 1393*e4b17023SJohn Marino */ 1394*e4b17023SJohn Marino template<typename _InputIterator, typename _ForwardIterator, 1395*e4b17023SJohn Marino typename _BinaryPredicate> 1396*e4b17023SJohn Marino _ForwardIterator 1397*e4b17023SJohn Marino __unique_copy(_InputIterator __first, _InputIterator __last, 1398*e4b17023SJohn Marino _ForwardIterator __result, _BinaryPredicate __binary_pred, 1399*e4b17023SJohn Marino input_iterator_tag, forward_iterator_tag) 1400*e4b17023SJohn Marino { 1401*e4b17023SJohn Marino // concept requirements -- iterators already checked 1402*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 1403*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, 1404*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 1405*e4b17023SJohn Marino 1406*e4b17023SJohn Marino *__result = *__first; 1407*e4b17023SJohn Marino while (++__first != __last) 1408*e4b17023SJohn Marino if (!bool(__binary_pred(*__result, *__first))) 1409*e4b17023SJohn Marino *++__result = *__first; 1410*e4b17023SJohn Marino return ++__result; 1411*e4b17023SJohn Marino } 1412*e4b17023SJohn Marino 1413*e4b17023SJohn Marino /** 1414*e4b17023SJohn Marino * This is an uglified reverse(_BidirectionalIterator, 1415*e4b17023SJohn Marino * _BidirectionalIterator) 1416*e4b17023SJohn Marino * overloaded for bidirectional iterators. 1417*e4b17023SJohn Marino */ 1418*e4b17023SJohn Marino template<typename _BidirectionalIterator> 1419*e4b17023SJohn Marino void 1420*e4b17023SJohn Marino __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, 1421*e4b17023SJohn Marino bidirectional_iterator_tag) 1422*e4b17023SJohn Marino { 1423*e4b17023SJohn Marino while (true) 1424*e4b17023SJohn Marino if (__first == __last || __first == --__last) 1425*e4b17023SJohn Marino return; 1426*e4b17023SJohn Marino else 1427*e4b17023SJohn Marino { 1428*e4b17023SJohn Marino std::iter_swap(__first, __last); 1429*e4b17023SJohn Marino ++__first; 1430*e4b17023SJohn Marino } 1431*e4b17023SJohn Marino } 1432*e4b17023SJohn Marino 1433*e4b17023SJohn Marino /** 1434*e4b17023SJohn Marino * This is an uglified reverse(_BidirectionalIterator, 1435*e4b17023SJohn Marino * _BidirectionalIterator) 1436*e4b17023SJohn Marino * overloaded for random access iterators. 1437*e4b17023SJohn Marino */ 1438*e4b17023SJohn Marino template<typename _RandomAccessIterator> 1439*e4b17023SJohn Marino void 1440*e4b17023SJohn Marino __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, 1441*e4b17023SJohn Marino random_access_iterator_tag) 1442*e4b17023SJohn Marino { 1443*e4b17023SJohn Marino if (__first == __last) 1444*e4b17023SJohn Marino return; 1445*e4b17023SJohn Marino --__last; 1446*e4b17023SJohn Marino while (__first < __last) 1447*e4b17023SJohn Marino { 1448*e4b17023SJohn Marino std::iter_swap(__first, __last); 1449*e4b17023SJohn Marino ++__first; 1450*e4b17023SJohn Marino --__last; 1451*e4b17023SJohn Marino } 1452*e4b17023SJohn Marino } 1453*e4b17023SJohn Marino 1454*e4b17023SJohn Marino /** 1455*e4b17023SJohn Marino * @brief Reverse a sequence. 1456*e4b17023SJohn Marino * @ingroup mutating_algorithms 1457*e4b17023SJohn Marino * @param __first A bidirectional iterator. 1458*e4b17023SJohn Marino * @param __last A bidirectional iterator. 1459*e4b17023SJohn Marino * @return reverse() returns no value. 1460*e4b17023SJohn Marino * 1461*e4b17023SJohn Marino * Reverses the order of the elements in the range @p [__first,__last), 1462*e4b17023SJohn Marino * so that the first element becomes the last etc. 1463*e4b17023SJohn Marino * For every @c i such that @p 0<=i<=(__last-__first)/2), @p reverse() 1464*e4b17023SJohn Marino * swaps @p *(__first+i) and @p *(__last-(i+1)) 1465*e4b17023SJohn Marino */ 1466*e4b17023SJohn Marino template<typename _BidirectionalIterator> 1467*e4b17023SJohn Marino inline void 1468*e4b17023SJohn Marino reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) 1469*e4b17023SJohn Marino { 1470*e4b17023SJohn Marino // concept requirements 1471*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< 1472*e4b17023SJohn Marino _BidirectionalIterator>) 1473*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 1474*e4b17023SJohn Marino std::__reverse(__first, __last, std::__iterator_category(__first)); 1475*e4b17023SJohn Marino } 1476*e4b17023SJohn Marino 1477*e4b17023SJohn Marino /** 1478*e4b17023SJohn Marino * @brief Copy a sequence, reversing its elements. 1479*e4b17023SJohn Marino * @ingroup mutating_algorithms 1480*e4b17023SJohn Marino * @param __first A bidirectional iterator. 1481*e4b17023SJohn Marino * @param __last A bidirectional iterator. 1482*e4b17023SJohn Marino * @param __result An output iterator. 1483*e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence. 1484*e4b17023SJohn Marino * 1485*e4b17023SJohn Marino * Copies the elements in the range @p [__first,__last) to the 1486*e4b17023SJohn Marino * range @p [__result,__result+(__last-__first)) such that the 1487*e4b17023SJohn Marino * order of the elements is reversed. For every @c i such that @p 1488*e4b17023SJohn Marino * 0<=i<=(__last-__first), @p reverse_copy() performs the 1489*e4b17023SJohn Marino * assignment @p *(__result+(__last-__first)-i) = *(__first+i). 1490*e4b17023SJohn Marino * The ranges @p [__first,__last) and @p 1491*e4b17023SJohn Marino * [__result,__result+(__last-__first)) must not overlap. 1492*e4b17023SJohn Marino */ 1493*e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _OutputIterator> 1494*e4b17023SJohn Marino _OutputIterator 1495*e4b17023SJohn Marino reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, 1496*e4b17023SJohn Marino _OutputIterator __result) 1497*e4b17023SJohn Marino { 1498*e4b17023SJohn Marino // concept requirements 1499*e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept< 1500*e4b17023SJohn Marino _BidirectionalIterator>) 1501*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 1502*e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type>) 1503*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 1504*e4b17023SJohn Marino 1505*e4b17023SJohn Marino while (__first != __last) 1506*e4b17023SJohn Marino { 1507*e4b17023SJohn Marino --__last; 1508*e4b17023SJohn Marino *__result = *__last; 1509*e4b17023SJohn Marino ++__result; 1510*e4b17023SJohn Marino } 1511*e4b17023SJohn Marino return __result; 1512*e4b17023SJohn Marino } 1513*e4b17023SJohn Marino 1514*e4b17023SJohn Marino /** 1515*e4b17023SJohn Marino * This is a helper function for the rotate algorithm specialized on RAIs. 1516*e4b17023SJohn Marino * It returns the greatest common divisor of two integer values. 1517*e4b17023SJohn Marino */ 1518*e4b17023SJohn Marino template<typename _EuclideanRingElement> 1519*e4b17023SJohn Marino _EuclideanRingElement 1520*e4b17023SJohn Marino __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n) 1521*e4b17023SJohn Marino { 1522*e4b17023SJohn Marino while (__n != 0) 1523*e4b17023SJohn Marino { 1524*e4b17023SJohn Marino _EuclideanRingElement __t = __m % __n; 1525*e4b17023SJohn Marino __m = __n; 1526*e4b17023SJohn Marino __n = __t; 1527*e4b17023SJohn Marino } 1528*e4b17023SJohn Marino return __m; 1529*e4b17023SJohn Marino } 1530*e4b17023SJohn Marino 1531*e4b17023SJohn Marino /// This is a helper function for the rotate algorithm. 1532*e4b17023SJohn Marino template<typename _ForwardIterator> 1533*e4b17023SJohn Marino void 1534*e4b17023SJohn Marino __rotate(_ForwardIterator __first, 1535*e4b17023SJohn Marino _ForwardIterator __middle, 1536*e4b17023SJohn Marino _ForwardIterator __last, 1537*e4b17023SJohn Marino forward_iterator_tag) 1538*e4b17023SJohn Marino { 1539*e4b17023SJohn Marino if (__first == __middle || __last == __middle) 1540*e4b17023SJohn Marino return; 1541*e4b17023SJohn Marino 1542*e4b17023SJohn Marino _ForwardIterator __first2 = __middle; 1543*e4b17023SJohn Marino do 1544*e4b17023SJohn Marino { 1545*e4b17023SJohn Marino std::iter_swap(__first, __first2); 1546*e4b17023SJohn Marino ++__first; 1547*e4b17023SJohn Marino ++__first2; 1548*e4b17023SJohn Marino if (__first == __middle) 1549*e4b17023SJohn Marino __middle = __first2; 1550*e4b17023SJohn Marino } 1551*e4b17023SJohn Marino while (__first2 != __last); 1552*e4b17023SJohn Marino 1553*e4b17023SJohn Marino __first2 = __middle; 1554*e4b17023SJohn Marino 1555*e4b17023SJohn Marino while (__first2 != __last) 1556*e4b17023SJohn Marino { 1557*e4b17023SJohn Marino std::iter_swap(__first, __first2); 1558*e4b17023SJohn Marino ++__first; 1559*e4b17023SJohn Marino ++__first2; 1560*e4b17023SJohn Marino if (__first == __middle) 1561*e4b17023SJohn Marino __middle = __first2; 1562*e4b17023SJohn Marino else if (__first2 == __last) 1563*e4b17023SJohn Marino __first2 = __middle; 1564*e4b17023SJohn Marino } 1565*e4b17023SJohn Marino } 1566*e4b17023SJohn Marino 1567*e4b17023SJohn Marino /// This is a helper function for the rotate algorithm. 1568*e4b17023SJohn Marino template<typename _BidirectionalIterator> 1569*e4b17023SJohn Marino void 1570*e4b17023SJohn Marino __rotate(_BidirectionalIterator __first, 1571*e4b17023SJohn Marino _BidirectionalIterator __middle, 1572*e4b17023SJohn Marino _BidirectionalIterator __last, 1573*e4b17023SJohn Marino bidirectional_iterator_tag) 1574*e4b17023SJohn Marino { 1575*e4b17023SJohn Marino // concept requirements 1576*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< 1577*e4b17023SJohn Marino _BidirectionalIterator>) 1578*e4b17023SJohn Marino 1579*e4b17023SJohn Marino if (__first == __middle || __last == __middle) 1580*e4b17023SJohn Marino return; 1581*e4b17023SJohn Marino 1582*e4b17023SJohn Marino std::__reverse(__first, __middle, bidirectional_iterator_tag()); 1583*e4b17023SJohn Marino std::__reverse(__middle, __last, bidirectional_iterator_tag()); 1584*e4b17023SJohn Marino 1585*e4b17023SJohn Marino while (__first != __middle && __middle != __last) 1586*e4b17023SJohn Marino { 1587*e4b17023SJohn Marino std::iter_swap(__first, --__last); 1588*e4b17023SJohn Marino ++__first; 1589*e4b17023SJohn Marino } 1590*e4b17023SJohn Marino 1591*e4b17023SJohn Marino if (__first == __middle) 1592*e4b17023SJohn Marino std::__reverse(__middle, __last, bidirectional_iterator_tag()); 1593*e4b17023SJohn Marino else 1594*e4b17023SJohn Marino std::__reverse(__first, __middle, bidirectional_iterator_tag()); 1595*e4b17023SJohn Marino } 1596*e4b17023SJohn Marino 1597*e4b17023SJohn Marino /// This is a helper function for the rotate algorithm. 1598*e4b17023SJohn Marino template<typename _RandomAccessIterator> 1599*e4b17023SJohn Marino void 1600*e4b17023SJohn Marino __rotate(_RandomAccessIterator __first, 1601*e4b17023SJohn Marino _RandomAccessIterator __middle, 1602*e4b17023SJohn Marino _RandomAccessIterator __last, 1603*e4b17023SJohn Marino random_access_iterator_tag) 1604*e4b17023SJohn Marino { 1605*e4b17023SJohn Marino // concept requirements 1606*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 1607*e4b17023SJohn Marino _RandomAccessIterator>) 1608*e4b17023SJohn Marino 1609*e4b17023SJohn Marino if (__first == __middle || __last == __middle) 1610*e4b17023SJohn Marino return; 1611*e4b17023SJohn Marino 1612*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type 1613*e4b17023SJohn Marino _Distance; 1614*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 1615*e4b17023SJohn Marino _ValueType; 1616*e4b17023SJohn Marino 1617*e4b17023SJohn Marino _Distance __n = __last - __first; 1618*e4b17023SJohn Marino _Distance __k = __middle - __first; 1619*e4b17023SJohn Marino 1620*e4b17023SJohn Marino if (__k == __n - __k) 1621*e4b17023SJohn Marino { 1622*e4b17023SJohn Marino std::swap_ranges(__first, __middle, __middle); 1623*e4b17023SJohn Marino return; 1624*e4b17023SJohn Marino } 1625*e4b17023SJohn Marino 1626*e4b17023SJohn Marino _RandomAccessIterator __p = __first; 1627*e4b17023SJohn Marino 1628*e4b17023SJohn Marino for (;;) 1629*e4b17023SJohn Marino { 1630*e4b17023SJohn Marino if (__k < __n - __k) 1631*e4b17023SJohn Marino { 1632*e4b17023SJohn Marino if (__is_pod(_ValueType) && __k == 1) 1633*e4b17023SJohn Marino { 1634*e4b17023SJohn Marino _ValueType __t = _GLIBCXX_MOVE(*__p); 1635*e4b17023SJohn Marino _GLIBCXX_MOVE3(__p + 1, __p + __n, __p); 1636*e4b17023SJohn Marino *(__p + __n - 1) = _GLIBCXX_MOVE(__t); 1637*e4b17023SJohn Marino return; 1638*e4b17023SJohn Marino } 1639*e4b17023SJohn Marino _RandomAccessIterator __q = __p + __k; 1640*e4b17023SJohn Marino for (_Distance __i = 0; __i < __n - __k; ++ __i) 1641*e4b17023SJohn Marino { 1642*e4b17023SJohn Marino std::iter_swap(__p, __q); 1643*e4b17023SJohn Marino ++__p; 1644*e4b17023SJohn Marino ++__q; 1645*e4b17023SJohn Marino } 1646*e4b17023SJohn Marino __n %= __k; 1647*e4b17023SJohn Marino if (__n == 0) 1648*e4b17023SJohn Marino return; 1649*e4b17023SJohn Marino std::swap(__n, __k); 1650*e4b17023SJohn Marino __k = __n - __k; 1651*e4b17023SJohn Marino } 1652*e4b17023SJohn Marino else 1653*e4b17023SJohn Marino { 1654*e4b17023SJohn Marino __k = __n - __k; 1655*e4b17023SJohn Marino if (__is_pod(_ValueType) && __k == 1) 1656*e4b17023SJohn Marino { 1657*e4b17023SJohn Marino _ValueType __t = _GLIBCXX_MOVE(*(__p + __n - 1)); 1658*e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__p, __p + __n - 1, __p + __n); 1659*e4b17023SJohn Marino *__p = _GLIBCXX_MOVE(__t); 1660*e4b17023SJohn Marino return; 1661*e4b17023SJohn Marino } 1662*e4b17023SJohn Marino _RandomAccessIterator __q = __p + __n; 1663*e4b17023SJohn Marino __p = __q - __k; 1664*e4b17023SJohn Marino for (_Distance __i = 0; __i < __n - __k; ++ __i) 1665*e4b17023SJohn Marino { 1666*e4b17023SJohn Marino --__p; 1667*e4b17023SJohn Marino --__q; 1668*e4b17023SJohn Marino std::iter_swap(__p, __q); 1669*e4b17023SJohn Marino } 1670*e4b17023SJohn Marino __n %= __k; 1671*e4b17023SJohn Marino if (__n == 0) 1672*e4b17023SJohn Marino return; 1673*e4b17023SJohn Marino std::swap(__n, __k); 1674*e4b17023SJohn Marino } 1675*e4b17023SJohn Marino } 1676*e4b17023SJohn Marino } 1677*e4b17023SJohn Marino 1678*e4b17023SJohn Marino /** 1679*e4b17023SJohn Marino * @brief Rotate the elements of a sequence. 1680*e4b17023SJohn Marino * @ingroup mutating_algorithms 1681*e4b17023SJohn Marino * @param __first A forward iterator. 1682*e4b17023SJohn Marino * @param __middle A forward iterator. 1683*e4b17023SJohn Marino * @param __last A forward iterator. 1684*e4b17023SJohn Marino * @return Nothing. 1685*e4b17023SJohn Marino * 1686*e4b17023SJohn Marino * Rotates the elements of the range @p [__first,__last) by 1687*e4b17023SJohn Marino * @p (__middle - __first) positions so that the element at @p __middle 1688*e4b17023SJohn Marino * is moved to @p __first, the element at @p __middle+1 is moved to 1689*e4b17023SJohn Marino * @p __first+1 and so on for each element in the range 1690*e4b17023SJohn Marino * @p [__first,__last). 1691*e4b17023SJohn Marino * 1692*e4b17023SJohn Marino * This effectively swaps the ranges @p [__first,__middle) and 1693*e4b17023SJohn Marino * @p [__middle,__last). 1694*e4b17023SJohn Marino * 1695*e4b17023SJohn Marino * Performs 1696*e4b17023SJohn Marino * @p *(__first+(n+(__last-__middle))%(__last-__first))=*(__first+n) 1697*e4b17023SJohn Marino * for each @p n in the range @p [0,__last-__first). 1698*e4b17023SJohn Marino */ 1699*e4b17023SJohn Marino template<typename _ForwardIterator> 1700*e4b17023SJohn Marino inline void 1701*e4b17023SJohn Marino rotate(_ForwardIterator __first, _ForwardIterator __middle, 1702*e4b17023SJohn Marino _ForwardIterator __last) 1703*e4b17023SJohn Marino { 1704*e4b17023SJohn Marino // concept requirements 1705*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 1706*e4b17023SJohn Marino _ForwardIterator>) 1707*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __middle); 1708*e4b17023SJohn Marino __glibcxx_requires_valid_range(__middle, __last); 1709*e4b17023SJohn Marino 1710*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::iterator_category 1711*e4b17023SJohn Marino _IterType; 1712*e4b17023SJohn Marino std::__rotate(__first, __middle, __last, _IterType()); 1713*e4b17023SJohn Marino } 1714*e4b17023SJohn Marino 1715*e4b17023SJohn Marino /** 1716*e4b17023SJohn Marino * @brief Copy a sequence, rotating its elements. 1717*e4b17023SJohn Marino * @ingroup mutating_algorithms 1718*e4b17023SJohn Marino * @param __first A forward iterator. 1719*e4b17023SJohn Marino * @param __middle A forward iterator. 1720*e4b17023SJohn Marino * @param __last A forward iterator. 1721*e4b17023SJohn Marino * @param __result An output iterator. 1722*e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence. 1723*e4b17023SJohn Marino * 1724*e4b17023SJohn Marino * Copies the elements of the range @p [__first,__last) to the 1725*e4b17023SJohn Marino * range beginning at @result, rotating the copied elements by 1726*e4b17023SJohn Marino * @p (__middle-__first) positions so that the element at @p __middle 1727*e4b17023SJohn Marino * is moved to @p __result, the element at @p __middle+1 is moved 1728*e4b17023SJohn Marino * to @p __result+1 and so on for each element in the range @p 1729*e4b17023SJohn Marino * [__first,__last). 1730*e4b17023SJohn Marino * 1731*e4b17023SJohn Marino * Performs 1732*e4b17023SJohn Marino * @p *(__result+(n+(__last-__middle))%(__last-__first))=*(__first+n) 1733*e4b17023SJohn Marino * for each @p n in the range @p [0,__last-__first). 1734*e4b17023SJohn Marino */ 1735*e4b17023SJohn Marino template<typename _ForwardIterator, typename _OutputIterator> 1736*e4b17023SJohn Marino _OutputIterator 1737*e4b17023SJohn Marino rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, 1738*e4b17023SJohn Marino _ForwardIterator __last, _OutputIterator __result) 1739*e4b17023SJohn Marino { 1740*e4b17023SJohn Marino // concept requirements 1741*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 1742*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 1743*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 1744*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __middle); 1745*e4b17023SJohn Marino __glibcxx_requires_valid_range(__middle, __last); 1746*e4b17023SJohn Marino 1747*e4b17023SJohn Marino return std::copy(__first, __middle, 1748*e4b17023SJohn Marino std::copy(__middle, __last, __result)); 1749*e4b17023SJohn Marino } 1750*e4b17023SJohn Marino 1751*e4b17023SJohn Marino /// This is a helper function... 1752*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate> 1753*e4b17023SJohn Marino _ForwardIterator 1754*e4b17023SJohn Marino __partition(_ForwardIterator __first, _ForwardIterator __last, 1755*e4b17023SJohn Marino _Predicate __pred, forward_iterator_tag) 1756*e4b17023SJohn Marino { 1757*e4b17023SJohn Marino if (__first == __last) 1758*e4b17023SJohn Marino return __first; 1759*e4b17023SJohn Marino 1760*e4b17023SJohn Marino while (__pred(*__first)) 1761*e4b17023SJohn Marino if (++__first == __last) 1762*e4b17023SJohn Marino return __first; 1763*e4b17023SJohn Marino 1764*e4b17023SJohn Marino _ForwardIterator __next = __first; 1765*e4b17023SJohn Marino 1766*e4b17023SJohn Marino while (++__next != __last) 1767*e4b17023SJohn Marino if (__pred(*__next)) 1768*e4b17023SJohn Marino { 1769*e4b17023SJohn Marino std::iter_swap(__first, __next); 1770*e4b17023SJohn Marino ++__first; 1771*e4b17023SJohn Marino } 1772*e4b17023SJohn Marino 1773*e4b17023SJohn Marino return __first; 1774*e4b17023SJohn Marino } 1775*e4b17023SJohn Marino 1776*e4b17023SJohn Marino /// This is a helper function... 1777*e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Predicate> 1778*e4b17023SJohn Marino _BidirectionalIterator 1779*e4b17023SJohn Marino __partition(_BidirectionalIterator __first, _BidirectionalIterator __last, 1780*e4b17023SJohn Marino _Predicate __pred, bidirectional_iterator_tag) 1781*e4b17023SJohn Marino { 1782*e4b17023SJohn Marino while (true) 1783*e4b17023SJohn Marino { 1784*e4b17023SJohn Marino while (true) 1785*e4b17023SJohn Marino if (__first == __last) 1786*e4b17023SJohn Marino return __first; 1787*e4b17023SJohn Marino else if (__pred(*__first)) 1788*e4b17023SJohn Marino ++__first; 1789*e4b17023SJohn Marino else 1790*e4b17023SJohn Marino break; 1791*e4b17023SJohn Marino --__last; 1792*e4b17023SJohn Marino while (true) 1793*e4b17023SJohn Marino if (__first == __last) 1794*e4b17023SJohn Marino return __first; 1795*e4b17023SJohn Marino else if (!bool(__pred(*__last))) 1796*e4b17023SJohn Marino --__last; 1797*e4b17023SJohn Marino else 1798*e4b17023SJohn Marino break; 1799*e4b17023SJohn Marino std::iter_swap(__first, __last); 1800*e4b17023SJohn Marino ++__first; 1801*e4b17023SJohn Marino } 1802*e4b17023SJohn Marino } 1803*e4b17023SJohn Marino 1804*e4b17023SJohn Marino // partition 1805*e4b17023SJohn Marino 1806*e4b17023SJohn Marino /// This is a helper function... 1807*e4b17023SJohn Marino /// Requires __len != 0 and !__pred(*__first), 1808*e4b17023SJohn Marino /// same as __stable_partition_adaptive. 1809*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate, typename _Distance> 1810*e4b17023SJohn Marino _ForwardIterator 1811*e4b17023SJohn Marino __inplace_stable_partition(_ForwardIterator __first, 1812*e4b17023SJohn Marino _Predicate __pred, _Distance __len) 1813*e4b17023SJohn Marino { 1814*e4b17023SJohn Marino if (__len == 1) 1815*e4b17023SJohn Marino return __first; 1816*e4b17023SJohn Marino _ForwardIterator __middle = __first; 1817*e4b17023SJohn Marino std::advance(__middle, __len / 2); 1818*e4b17023SJohn Marino _ForwardIterator __left_split = 1819*e4b17023SJohn Marino std::__inplace_stable_partition(__first, __pred, __len / 2); 1820*e4b17023SJohn Marino // Advance past true-predicate values to satisfy this 1821*e4b17023SJohn Marino // function's preconditions. 1822*e4b17023SJohn Marino _Distance __right_len = __len - __len / 2; 1823*e4b17023SJohn Marino _ForwardIterator __right_split = 1824*e4b17023SJohn Marino std::__find_if_not_n(__middle, __right_len, __pred); 1825*e4b17023SJohn Marino if (__right_len) 1826*e4b17023SJohn Marino __right_split = std::__inplace_stable_partition(__middle, 1827*e4b17023SJohn Marino __pred, 1828*e4b17023SJohn Marino __right_len); 1829*e4b17023SJohn Marino std::rotate(__left_split, __middle, __right_split); 1830*e4b17023SJohn Marino std::advance(__left_split, std::distance(__middle, __right_split)); 1831*e4b17023SJohn Marino return __left_split; 1832*e4b17023SJohn Marino } 1833*e4b17023SJohn Marino 1834*e4b17023SJohn Marino /// This is a helper function... 1835*e4b17023SJohn Marino /// Requires __first != __last and !__pred(*__first) 1836*e4b17023SJohn Marino /// and __len == distance(__first, __last). 1837*e4b17023SJohn Marino /// 1838*e4b17023SJohn Marino /// !__pred(*__first) allows us to guarantee that we don't 1839*e4b17023SJohn Marino /// move-assign an element onto itself. 1840*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Pointer, typename _Predicate, 1841*e4b17023SJohn Marino typename _Distance> 1842*e4b17023SJohn Marino _ForwardIterator 1843*e4b17023SJohn Marino __stable_partition_adaptive(_ForwardIterator __first, 1844*e4b17023SJohn Marino _ForwardIterator __last, 1845*e4b17023SJohn Marino _Predicate __pred, _Distance __len, 1846*e4b17023SJohn Marino _Pointer __buffer, 1847*e4b17023SJohn Marino _Distance __buffer_size) 1848*e4b17023SJohn Marino { 1849*e4b17023SJohn Marino if (__len <= __buffer_size) 1850*e4b17023SJohn Marino { 1851*e4b17023SJohn Marino _ForwardIterator __result1 = __first; 1852*e4b17023SJohn Marino _Pointer __result2 = __buffer; 1853*e4b17023SJohn Marino // The precondition guarantees that !__pred(*__first), so 1854*e4b17023SJohn Marino // move that element to the buffer before starting the loop. 1855*e4b17023SJohn Marino // This ensures that we only call __pred once per element. 1856*e4b17023SJohn Marino *__result2 = _GLIBCXX_MOVE(*__first); 1857*e4b17023SJohn Marino ++__result2; 1858*e4b17023SJohn Marino ++__first; 1859*e4b17023SJohn Marino for (; __first != __last; ++__first) 1860*e4b17023SJohn Marino if (__pred(*__first)) 1861*e4b17023SJohn Marino { 1862*e4b17023SJohn Marino *__result1 = _GLIBCXX_MOVE(*__first); 1863*e4b17023SJohn Marino ++__result1; 1864*e4b17023SJohn Marino } 1865*e4b17023SJohn Marino else 1866*e4b17023SJohn Marino { 1867*e4b17023SJohn Marino *__result2 = _GLIBCXX_MOVE(*__first); 1868*e4b17023SJohn Marino ++__result2; 1869*e4b17023SJohn Marino } 1870*e4b17023SJohn Marino _GLIBCXX_MOVE3(__buffer, __result2, __result1); 1871*e4b17023SJohn Marino return __result1; 1872*e4b17023SJohn Marino } 1873*e4b17023SJohn Marino else 1874*e4b17023SJohn Marino { 1875*e4b17023SJohn Marino _ForwardIterator __middle = __first; 1876*e4b17023SJohn Marino std::advance(__middle, __len / 2); 1877*e4b17023SJohn Marino _ForwardIterator __left_split = 1878*e4b17023SJohn Marino std::__stable_partition_adaptive(__first, __middle, __pred, 1879*e4b17023SJohn Marino __len / 2, __buffer, 1880*e4b17023SJohn Marino __buffer_size); 1881*e4b17023SJohn Marino // Advance past true-predicate values to satisfy this 1882*e4b17023SJohn Marino // function's preconditions. 1883*e4b17023SJohn Marino _Distance __right_len = __len - __len / 2; 1884*e4b17023SJohn Marino _ForwardIterator __right_split = 1885*e4b17023SJohn Marino std::__find_if_not_n(__middle, __right_len, __pred); 1886*e4b17023SJohn Marino if (__right_len) 1887*e4b17023SJohn Marino __right_split = 1888*e4b17023SJohn Marino std::__stable_partition_adaptive(__right_split, __last, __pred, 1889*e4b17023SJohn Marino __right_len, 1890*e4b17023SJohn Marino __buffer, __buffer_size); 1891*e4b17023SJohn Marino std::rotate(__left_split, __middle, __right_split); 1892*e4b17023SJohn Marino std::advance(__left_split, std::distance(__middle, __right_split)); 1893*e4b17023SJohn Marino return __left_split; 1894*e4b17023SJohn Marino } 1895*e4b17023SJohn Marino } 1896*e4b17023SJohn Marino 1897*e4b17023SJohn Marino /** 1898*e4b17023SJohn Marino * @brief Move elements for which a predicate is true to the beginning 1899*e4b17023SJohn Marino * of a sequence, preserving relative ordering. 1900*e4b17023SJohn Marino * @ingroup mutating_algorithms 1901*e4b17023SJohn Marino * @param __first A forward iterator. 1902*e4b17023SJohn Marino * @param __last A forward iterator. 1903*e4b17023SJohn Marino * @param __pred A predicate functor. 1904*e4b17023SJohn Marino * @return An iterator @p middle such that @p __pred(i) is true for each 1905*e4b17023SJohn Marino * iterator @p i in the range @p [first,middle) and false for each @p i 1906*e4b17023SJohn Marino * in the range @p [middle,last). 1907*e4b17023SJohn Marino * 1908*e4b17023SJohn Marino * Performs the same function as @p partition() with the additional 1909*e4b17023SJohn Marino * guarantee that the relative ordering of elements in each group is 1910*e4b17023SJohn Marino * preserved, so any two elements @p x and @p y in the range 1911*e4b17023SJohn Marino * @p [__first,__last) such that @p __pred(x)==__pred(y) will have the same 1912*e4b17023SJohn Marino * relative ordering after calling @p stable_partition(). 1913*e4b17023SJohn Marino */ 1914*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate> 1915*e4b17023SJohn Marino _ForwardIterator 1916*e4b17023SJohn Marino stable_partition(_ForwardIterator __first, _ForwardIterator __last, 1917*e4b17023SJohn Marino _Predicate __pred) 1918*e4b17023SJohn Marino { 1919*e4b17023SJohn Marino // concept requirements 1920*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 1921*e4b17023SJohn Marino _ForwardIterator>) 1922*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 1923*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 1924*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 1925*e4b17023SJohn Marino 1926*e4b17023SJohn Marino __first = std::__find_if_not(__first, __last, __pred); 1927*e4b17023SJohn Marino 1928*e4b17023SJohn Marino if (__first == __last) 1929*e4b17023SJohn Marino return __first; 1930*e4b17023SJohn Marino else 1931*e4b17023SJohn Marino { 1932*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type 1933*e4b17023SJohn Marino _ValueType; 1934*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type 1935*e4b17023SJohn Marino _DistanceType; 1936*e4b17023SJohn Marino 1937*e4b17023SJohn Marino _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, 1938*e4b17023SJohn Marino __last); 1939*e4b17023SJohn Marino if (__buf.size() > 0) 1940*e4b17023SJohn Marino return 1941*e4b17023SJohn Marino std::__stable_partition_adaptive(__first, __last, __pred, 1942*e4b17023SJohn Marino _DistanceType(__buf.requested_size()), 1943*e4b17023SJohn Marino __buf.begin(), 1944*e4b17023SJohn Marino _DistanceType(__buf.size())); 1945*e4b17023SJohn Marino else 1946*e4b17023SJohn Marino return 1947*e4b17023SJohn Marino std::__inplace_stable_partition(__first, __pred, 1948*e4b17023SJohn Marino _DistanceType(__buf.requested_size())); 1949*e4b17023SJohn Marino } 1950*e4b17023SJohn Marino } 1951*e4b17023SJohn Marino 1952*e4b17023SJohn Marino /// This is a helper function for the sort routines. 1953*e4b17023SJohn Marino template<typename _RandomAccessIterator> 1954*e4b17023SJohn Marino void 1955*e4b17023SJohn Marino __heap_select(_RandomAccessIterator __first, 1956*e4b17023SJohn Marino _RandomAccessIterator __middle, 1957*e4b17023SJohn Marino _RandomAccessIterator __last) 1958*e4b17023SJohn Marino { 1959*e4b17023SJohn Marino std::make_heap(__first, __middle); 1960*e4b17023SJohn Marino for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) 1961*e4b17023SJohn Marino if (*__i < *__first) 1962*e4b17023SJohn Marino std::__pop_heap(__first, __middle, __i); 1963*e4b17023SJohn Marino } 1964*e4b17023SJohn Marino 1965*e4b17023SJohn Marino /// This is a helper function for the sort routines. 1966*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare> 1967*e4b17023SJohn Marino void 1968*e4b17023SJohn Marino __heap_select(_RandomAccessIterator __first, 1969*e4b17023SJohn Marino _RandomAccessIterator __middle, 1970*e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp) 1971*e4b17023SJohn Marino { 1972*e4b17023SJohn Marino std::make_heap(__first, __middle, __comp); 1973*e4b17023SJohn Marino for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) 1974*e4b17023SJohn Marino if (__comp(*__i, *__first)) 1975*e4b17023SJohn Marino std::__pop_heap(__first, __middle, __i, __comp); 1976*e4b17023SJohn Marino } 1977*e4b17023SJohn Marino 1978*e4b17023SJohn Marino // partial_sort 1979*e4b17023SJohn Marino 1980*e4b17023SJohn Marino /** 1981*e4b17023SJohn Marino * @brief Copy the smallest elements of a sequence. 1982*e4b17023SJohn Marino * @ingroup sorting_algorithms 1983*e4b17023SJohn Marino * @param __first An iterator. 1984*e4b17023SJohn Marino * @param __last Another iterator. 1985*e4b17023SJohn Marino * @param __result_first A random-access iterator. 1986*e4b17023SJohn Marino * @param __result_last Another random-access iterator. 1987*e4b17023SJohn Marino * @return An iterator indicating the end of the resulting sequence. 1988*e4b17023SJohn Marino * 1989*e4b17023SJohn Marino * Copies and sorts the smallest N values from the range @p [__first,__last) 1990*e4b17023SJohn Marino * to the range beginning at @p __result_first, where the number of 1991*e4b17023SJohn Marino * elements to be copied, @p N, is the smaller of @p (__last-__first) and 1992*e4b17023SJohn Marino * @p (__result_last-__result_first). 1993*e4b17023SJohn Marino * After the sort if @e i and @e j are iterators in the range 1994*e4b17023SJohn Marino * @p [__result_first,__result_first+N) such that i precedes j then 1995*e4b17023SJohn Marino * *j<*i is false. 1996*e4b17023SJohn Marino * The value returned is @p __result_first+N. 1997*e4b17023SJohn Marino */ 1998*e4b17023SJohn Marino template<typename _InputIterator, typename _RandomAccessIterator> 1999*e4b17023SJohn Marino _RandomAccessIterator 2000*e4b17023SJohn Marino partial_sort_copy(_InputIterator __first, _InputIterator __last, 2001*e4b17023SJohn Marino _RandomAccessIterator __result_first, 2002*e4b17023SJohn Marino _RandomAccessIterator __result_last) 2003*e4b17023SJohn Marino { 2004*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator>::value_type 2005*e4b17023SJohn Marino _InputValueType; 2006*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 2007*e4b17023SJohn Marino _OutputValueType; 2008*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type 2009*e4b17023SJohn Marino _DistanceType; 2010*e4b17023SJohn Marino 2011*e4b17023SJohn Marino // concept requirements 2012*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 2013*e4b17023SJohn Marino __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, 2014*e4b17023SJohn Marino _OutputValueType>) 2015*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_InputValueType, 2016*e4b17023SJohn Marino _OutputValueType>) 2017*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>) 2018*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 2019*e4b17023SJohn Marino __glibcxx_requires_valid_range(__result_first, __result_last); 2020*e4b17023SJohn Marino 2021*e4b17023SJohn Marino if (__result_first == __result_last) 2022*e4b17023SJohn Marino return __result_last; 2023*e4b17023SJohn Marino _RandomAccessIterator __result_real_last = __result_first; 2024*e4b17023SJohn Marino while(__first != __last && __result_real_last != __result_last) 2025*e4b17023SJohn Marino { 2026*e4b17023SJohn Marino *__result_real_last = *__first; 2027*e4b17023SJohn Marino ++__result_real_last; 2028*e4b17023SJohn Marino ++__first; 2029*e4b17023SJohn Marino } 2030*e4b17023SJohn Marino std::make_heap(__result_first, __result_real_last); 2031*e4b17023SJohn Marino while (__first != __last) 2032*e4b17023SJohn Marino { 2033*e4b17023SJohn Marino if (*__first < *__result_first) 2034*e4b17023SJohn Marino std::__adjust_heap(__result_first, _DistanceType(0), 2035*e4b17023SJohn Marino _DistanceType(__result_real_last 2036*e4b17023SJohn Marino - __result_first), 2037*e4b17023SJohn Marino _InputValueType(*__first)); 2038*e4b17023SJohn Marino ++__first; 2039*e4b17023SJohn Marino } 2040*e4b17023SJohn Marino std::sort_heap(__result_first, __result_real_last); 2041*e4b17023SJohn Marino return __result_real_last; 2042*e4b17023SJohn Marino } 2043*e4b17023SJohn Marino 2044*e4b17023SJohn Marino /** 2045*e4b17023SJohn Marino * @brief Copy the smallest elements of a sequence using a predicate for 2046*e4b17023SJohn Marino * comparison. 2047*e4b17023SJohn Marino * @ingroup sorting_algorithms 2048*e4b17023SJohn Marino * @param __first An input iterator. 2049*e4b17023SJohn Marino * @param __last Another input iterator. 2050*e4b17023SJohn Marino * @param __result_first A random-access iterator. 2051*e4b17023SJohn Marino * @param __result_last Another random-access iterator. 2052*e4b17023SJohn Marino * @param __comp A comparison functor. 2053*e4b17023SJohn Marino * @return An iterator indicating the end of the resulting sequence. 2054*e4b17023SJohn Marino * 2055*e4b17023SJohn Marino * Copies and sorts the smallest N values from the range @p [__first,__last) 2056*e4b17023SJohn Marino * to the range beginning at @p result_first, where the number of 2057*e4b17023SJohn Marino * elements to be copied, @p N, is the smaller of @p (__last-__first) and 2058*e4b17023SJohn Marino * @p (__result_last-__result_first). 2059*e4b17023SJohn Marino * After the sort if @e i and @e j are iterators in the range 2060*e4b17023SJohn Marino * @p [__result_first,__result_first+N) such that i precedes j then 2061*e4b17023SJohn Marino * @p __comp(*j,*i) is false. 2062*e4b17023SJohn Marino * The value returned is @p __result_first+N. 2063*e4b17023SJohn Marino */ 2064*e4b17023SJohn Marino template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare> 2065*e4b17023SJohn Marino _RandomAccessIterator 2066*e4b17023SJohn Marino partial_sort_copy(_InputIterator __first, _InputIterator __last, 2067*e4b17023SJohn Marino _RandomAccessIterator __result_first, 2068*e4b17023SJohn Marino _RandomAccessIterator __result_last, 2069*e4b17023SJohn Marino _Compare __comp) 2070*e4b17023SJohn Marino { 2071*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator>::value_type 2072*e4b17023SJohn Marino _InputValueType; 2073*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 2074*e4b17023SJohn Marino _OutputValueType; 2075*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type 2076*e4b17023SJohn Marino _DistanceType; 2077*e4b17023SJohn Marino 2078*e4b17023SJohn Marino // concept requirements 2079*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 2080*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 2081*e4b17023SJohn Marino _RandomAccessIterator>) 2082*e4b17023SJohn Marino __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, 2083*e4b17023SJohn Marino _OutputValueType>) 2084*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2085*e4b17023SJohn Marino _InputValueType, _OutputValueType>) 2086*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2087*e4b17023SJohn Marino _OutputValueType, _OutputValueType>) 2088*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 2089*e4b17023SJohn Marino __glibcxx_requires_valid_range(__result_first, __result_last); 2090*e4b17023SJohn Marino 2091*e4b17023SJohn Marino if (__result_first == __result_last) 2092*e4b17023SJohn Marino return __result_last; 2093*e4b17023SJohn Marino _RandomAccessIterator __result_real_last = __result_first; 2094*e4b17023SJohn Marino while(__first != __last && __result_real_last != __result_last) 2095*e4b17023SJohn Marino { 2096*e4b17023SJohn Marino *__result_real_last = *__first; 2097*e4b17023SJohn Marino ++__result_real_last; 2098*e4b17023SJohn Marino ++__first; 2099*e4b17023SJohn Marino } 2100*e4b17023SJohn Marino std::make_heap(__result_first, __result_real_last, __comp); 2101*e4b17023SJohn Marino while (__first != __last) 2102*e4b17023SJohn Marino { 2103*e4b17023SJohn Marino if (__comp(*__first, *__result_first)) 2104*e4b17023SJohn Marino std::__adjust_heap(__result_first, _DistanceType(0), 2105*e4b17023SJohn Marino _DistanceType(__result_real_last 2106*e4b17023SJohn Marino - __result_first), 2107*e4b17023SJohn Marino _InputValueType(*__first), 2108*e4b17023SJohn Marino __comp); 2109*e4b17023SJohn Marino ++__first; 2110*e4b17023SJohn Marino } 2111*e4b17023SJohn Marino std::sort_heap(__result_first, __result_real_last, __comp); 2112*e4b17023SJohn Marino return __result_real_last; 2113*e4b17023SJohn Marino } 2114*e4b17023SJohn Marino 2115*e4b17023SJohn Marino /// This is a helper function for the sort routine. 2116*e4b17023SJohn Marino template<typename _RandomAccessIterator> 2117*e4b17023SJohn Marino void 2118*e4b17023SJohn Marino __unguarded_linear_insert(_RandomAccessIterator __last) 2119*e4b17023SJohn Marino { 2120*e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::value_type 2121*e4b17023SJohn Marino __val = _GLIBCXX_MOVE(*__last); 2122*e4b17023SJohn Marino _RandomAccessIterator __next = __last; 2123*e4b17023SJohn Marino --__next; 2124*e4b17023SJohn Marino while (__val < *__next) 2125*e4b17023SJohn Marino { 2126*e4b17023SJohn Marino *__last = _GLIBCXX_MOVE(*__next); 2127*e4b17023SJohn Marino __last = __next; 2128*e4b17023SJohn Marino --__next; 2129*e4b17023SJohn Marino } 2130*e4b17023SJohn Marino *__last = _GLIBCXX_MOVE(__val); 2131*e4b17023SJohn Marino } 2132*e4b17023SJohn Marino 2133*e4b17023SJohn Marino /// This is a helper function for the sort routine. 2134*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare> 2135*e4b17023SJohn Marino void 2136*e4b17023SJohn Marino __unguarded_linear_insert(_RandomAccessIterator __last, 2137*e4b17023SJohn Marino _Compare __comp) 2138*e4b17023SJohn Marino { 2139*e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::value_type 2140*e4b17023SJohn Marino __val = _GLIBCXX_MOVE(*__last); 2141*e4b17023SJohn Marino _RandomAccessIterator __next = __last; 2142*e4b17023SJohn Marino --__next; 2143*e4b17023SJohn Marino while (__comp(__val, *__next)) 2144*e4b17023SJohn Marino { 2145*e4b17023SJohn Marino *__last = _GLIBCXX_MOVE(*__next); 2146*e4b17023SJohn Marino __last = __next; 2147*e4b17023SJohn Marino --__next; 2148*e4b17023SJohn Marino } 2149*e4b17023SJohn Marino *__last = _GLIBCXX_MOVE(__val); 2150*e4b17023SJohn Marino } 2151*e4b17023SJohn Marino 2152*e4b17023SJohn Marino /// This is a helper function for the sort routine. 2153*e4b17023SJohn Marino template<typename _RandomAccessIterator> 2154*e4b17023SJohn Marino void 2155*e4b17023SJohn Marino __insertion_sort(_RandomAccessIterator __first, 2156*e4b17023SJohn Marino _RandomAccessIterator __last) 2157*e4b17023SJohn Marino { 2158*e4b17023SJohn Marino if (__first == __last) 2159*e4b17023SJohn Marino return; 2160*e4b17023SJohn Marino 2161*e4b17023SJohn Marino for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) 2162*e4b17023SJohn Marino { 2163*e4b17023SJohn Marino if (*__i < *__first) 2164*e4b17023SJohn Marino { 2165*e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::value_type 2166*e4b17023SJohn Marino __val = _GLIBCXX_MOVE(*__i); 2167*e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1); 2168*e4b17023SJohn Marino *__first = _GLIBCXX_MOVE(__val); 2169*e4b17023SJohn Marino } 2170*e4b17023SJohn Marino else 2171*e4b17023SJohn Marino std::__unguarded_linear_insert(__i); 2172*e4b17023SJohn Marino } 2173*e4b17023SJohn Marino } 2174*e4b17023SJohn Marino 2175*e4b17023SJohn Marino /// This is a helper function for the sort routine. 2176*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare> 2177*e4b17023SJohn Marino void 2178*e4b17023SJohn Marino __insertion_sort(_RandomAccessIterator __first, 2179*e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp) 2180*e4b17023SJohn Marino { 2181*e4b17023SJohn Marino if (__first == __last) return; 2182*e4b17023SJohn Marino 2183*e4b17023SJohn Marino for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) 2184*e4b17023SJohn Marino { 2185*e4b17023SJohn Marino if (__comp(*__i, *__first)) 2186*e4b17023SJohn Marino { 2187*e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::value_type 2188*e4b17023SJohn Marino __val = _GLIBCXX_MOVE(*__i); 2189*e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1); 2190*e4b17023SJohn Marino *__first = _GLIBCXX_MOVE(__val); 2191*e4b17023SJohn Marino } 2192*e4b17023SJohn Marino else 2193*e4b17023SJohn Marino std::__unguarded_linear_insert(__i, __comp); 2194*e4b17023SJohn Marino } 2195*e4b17023SJohn Marino } 2196*e4b17023SJohn Marino 2197*e4b17023SJohn Marino /// This is a helper function for the sort routine. 2198*e4b17023SJohn Marino template<typename _RandomAccessIterator> 2199*e4b17023SJohn Marino inline void 2200*e4b17023SJohn Marino __unguarded_insertion_sort(_RandomAccessIterator __first, 2201*e4b17023SJohn Marino _RandomAccessIterator __last) 2202*e4b17023SJohn Marino { 2203*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 2204*e4b17023SJohn Marino _ValueType; 2205*e4b17023SJohn Marino 2206*e4b17023SJohn Marino for (_RandomAccessIterator __i = __first; __i != __last; ++__i) 2207*e4b17023SJohn Marino std::__unguarded_linear_insert(__i); 2208*e4b17023SJohn Marino } 2209*e4b17023SJohn Marino 2210*e4b17023SJohn Marino /// This is a helper function for the sort routine. 2211*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare> 2212*e4b17023SJohn Marino inline void 2213*e4b17023SJohn Marino __unguarded_insertion_sort(_RandomAccessIterator __first, 2214*e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp) 2215*e4b17023SJohn Marino { 2216*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 2217*e4b17023SJohn Marino _ValueType; 2218*e4b17023SJohn Marino 2219*e4b17023SJohn Marino for (_RandomAccessIterator __i = __first; __i != __last; ++__i) 2220*e4b17023SJohn Marino std::__unguarded_linear_insert(__i, __comp); 2221*e4b17023SJohn Marino } 2222*e4b17023SJohn Marino 2223*e4b17023SJohn Marino /** 2224*e4b17023SJohn Marino * @doctodo 2225*e4b17023SJohn Marino * This controls some aspect of the sort routines. 2226*e4b17023SJohn Marino */ 2227*e4b17023SJohn Marino enum { _S_threshold = 16 }; 2228*e4b17023SJohn Marino 2229*e4b17023SJohn Marino /// This is a helper function for the sort routine. 2230*e4b17023SJohn Marino template<typename _RandomAccessIterator> 2231*e4b17023SJohn Marino void 2232*e4b17023SJohn Marino __final_insertion_sort(_RandomAccessIterator __first, 2233*e4b17023SJohn Marino _RandomAccessIterator __last) 2234*e4b17023SJohn Marino { 2235*e4b17023SJohn Marino if (__last - __first > int(_S_threshold)) 2236*e4b17023SJohn Marino { 2237*e4b17023SJohn Marino std::__insertion_sort(__first, __first + int(_S_threshold)); 2238*e4b17023SJohn Marino std::__unguarded_insertion_sort(__first + int(_S_threshold), __last); 2239*e4b17023SJohn Marino } 2240*e4b17023SJohn Marino else 2241*e4b17023SJohn Marino std::__insertion_sort(__first, __last); 2242*e4b17023SJohn Marino } 2243*e4b17023SJohn Marino 2244*e4b17023SJohn Marino /// This is a helper function for the sort routine. 2245*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare> 2246*e4b17023SJohn Marino void 2247*e4b17023SJohn Marino __final_insertion_sort(_RandomAccessIterator __first, 2248*e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp) 2249*e4b17023SJohn Marino { 2250*e4b17023SJohn Marino if (__last - __first > int(_S_threshold)) 2251*e4b17023SJohn Marino { 2252*e4b17023SJohn Marino std::__insertion_sort(__first, __first + int(_S_threshold), __comp); 2253*e4b17023SJohn Marino std::__unguarded_insertion_sort(__first + int(_S_threshold), __last, 2254*e4b17023SJohn Marino __comp); 2255*e4b17023SJohn Marino } 2256*e4b17023SJohn Marino else 2257*e4b17023SJohn Marino std::__insertion_sort(__first, __last, __comp); 2258*e4b17023SJohn Marino } 2259*e4b17023SJohn Marino 2260*e4b17023SJohn Marino /// This is a helper function... 2261*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Tp> 2262*e4b17023SJohn Marino _RandomAccessIterator 2263*e4b17023SJohn Marino __unguarded_partition(_RandomAccessIterator __first, 2264*e4b17023SJohn Marino _RandomAccessIterator __last, const _Tp& __pivot) 2265*e4b17023SJohn Marino { 2266*e4b17023SJohn Marino while (true) 2267*e4b17023SJohn Marino { 2268*e4b17023SJohn Marino while (*__first < __pivot) 2269*e4b17023SJohn Marino ++__first; 2270*e4b17023SJohn Marino --__last; 2271*e4b17023SJohn Marino while (__pivot < *__last) 2272*e4b17023SJohn Marino --__last; 2273*e4b17023SJohn Marino if (!(__first < __last)) 2274*e4b17023SJohn Marino return __first; 2275*e4b17023SJohn Marino std::iter_swap(__first, __last); 2276*e4b17023SJohn Marino ++__first; 2277*e4b17023SJohn Marino } 2278*e4b17023SJohn Marino } 2279*e4b17023SJohn Marino 2280*e4b17023SJohn Marino /// This is a helper function... 2281*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Tp, typename _Compare> 2282*e4b17023SJohn Marino _RandomAccessIterator 2283*e4b17023SJohn Marino __unguarded_partition(_RandomAccessIterator __first, 2284*e4b17023SJohn Marino _RandomAccessIterator __last, 2285*e4b17023SJohn Marino const _Tp& __pivot, _Compare __comp) 2286*e4b17023SJohn Marino { 2287*e4b17023SJohn Marino while (true) 2288*e4b17023SJohn Marino { 2289*e4b17023SJohn Marino while (__comp(*__first, __pivot)) 2290*e4b17023SJohn Marino ++__first; 2291*e4b17023SJohn Marino --__last; 2292*e4b17023SJohn Marino while (__comp(__pivot, *__last)) 2293*e4b17023SJohn Marino --__last; 2294*e4b17023SJohn Marino if (!(__first < __last)) 2295*e4b17023SJohn Marino return __first; 2296*e4b17023SJohn Marino std::iter_swap(__first, __last); 2297*e4b17023SJohn Marino ++__first; 2298*e4b17023SJohn Marino } 2299*e4b17023SJohn Marino } 2300*e4b17023SJohn Marino 2301*e4b17023SJohn Marino /// This is a helper function... 2302*e4b17023SJohn Marino template<typename _RandomAccessIterator> 2303*e4b17023SJohn Marino inline _RandomAccessIterator 2304*e4b17023SJohn Marino __unguarded_partition_pivot(_RandomAccessIterator __first, 2305*e4b17023SJohn Marino _RandomAccessIterator __last) 2306*e4b17023SJohn Marino { 2307*e4b17023SJohn Marino _RandomAccessIterator __mid = __first + (__last - __first) / 2; 2308*e4b17023SJohn Marino std::__move_median_first(__first, __mid, (__last - 1)); 2309*e4b17023SJohn Marino return std::__unguarded_partition(__first + 1, __last, *__first); 2310*e4b17023SJohn Marino } 2311*e4b17023SJohn Marino 2312*e4b17023SJohn Marino 2313*e4b17023SJohn Marino /// This is a helper function... 2314*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare> 2315*e4b17023SJohn Marino inline _RandomAccessIterator 2316*e4b17023SJohn Marino __unguarded_partition_pivot(_RandomAccessIterator __first, 2317*e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp) 2318*e4b17023SJohn Marino { 2319*e4b17023SJohn Marino _RandomAccessIterator __mid = __first + (__last - __first) / 2; 2320*e4b17023SJohn Marino std::__move_median_first(__first, __mid, (__last - 1), __comp); 2321*e4b17023SJohn Marino return std::__unguarded_partition(__first + 1, __last, *__first, __comp); 2322*e4b17023SJohn Marino } 2323*e4b17023SJohn Marino 2324*e4b17023SJohn Marino /// This is a helper function for the sort routine. 2325*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Size> 2326*e4b17023SJohn Marino void 2327*e4b17023SJohn Marino __introsort_loop(_RandomAccessIterator __first, 2328*e4b17023SJohn Marino _RandomAccessIterator __last, 2329*e4b17023SJohn Marino _Size __depth_limit) 2330*e4b17023SJohn Marino { 2331*e4b17023SJohn Marino while (__last - __first > int(_S_threshold)) 2332*e4b17023SJohn Marino { 2333*e4b17023SJohn Marino if (__depth_limit == 0) 2334*e4b17023SJohn Marino { 2335*e4b17023SJohn Marino _GLIBCXX_STD_A::partial_sort(__first, __last, __last); 2336*e4b17023SJohn Marino return; 2337*e4b17023SJohn Marino } 2338*e4b17023SJohn Marino --__depth_limit; 2339*e4b17023SJohn Marino _RandomAccessIterator __cut = 2340*e4b17023SJohn Marino std::__unguarded_partition_pivot(__first, __last); 2341*e4b17023SJohn Marino std::__introsort_loop(__cut, __last, __depth_limit); 2342*e4b17023SJohn Marino __last = __cut; 2343*e4b17023SJohn Marino } 2344*e4b17023SJohn Marino } 2345*e4b17023SJohn Marino 2346*e4b17023SJohn Marino /// This is a helper function for the sort routine. 2347*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Size, typename _Compare> 2348*e4b17023SJohn Marino void 2349*e4b17023SJohn Marino __introsort_loop(_RandomAccessIterator __first, 2350*e4b17023SJohn Marino _RandomAccessIterator __last, 2351*e4b17023SJohn Marino _Size __depth_limit, _Compare __comp) 2352*e4b17023SJohn Marino { 2353*e4b17023SJohn Marino while (__last - __first > int(_S_threshold)) 2354*e4b17023SJohn Marino { 2355*e4b17023SJohn Marino if (__depth_limit == 0) 2356*e4b17023SJohn Marino { 2357*e4b17023SJohn Marino _GLIBCXX_STD_A::partial_sort(__first, __last, __last, __comp); 2358*e4b17023SJohn Marino return; 2359*e4b17023SJohn Marino } 2360*e4b17023SJohn Marino --__depth_limit; 2361*e4b17023SJohn Marino _RandomAccessIterator __cut = 2362*e4b17023SJohn Marino std::__unguarded_partition_pivot(__first, __last, __comp); 2363*e4b17023SJohn Marino std::__introsort_loop(__cut, __last, __depth_limit, __comp); 2364*e4b17023SJohn Marino __last = __cut; 2365*e4b17023SJohn Marino } 2366*e4b17023SJohn Marino } 2367*e4b17023SJohn Marino 2368*e4b17023SJohn Marino // sort 2369*e4b17023SJohn Marino 2370*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Size> 2371*e4b17023SJohn Marino void 2372*e4b17023SJohn Marino __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth, 2373*e4b17023SJohn Marino _RandomAccessIterator __last, _Size __depth_limit) 2374*e4b17023SJohn Marino { 2375*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 2376*e4b17023SJohn Marino _ValueType; 2377*e4b17023SJohn Marino 2378*e4b17023SJohn Marino while (__last - __first > 3) 2379*e4b17023SJohn Marino { 2380*e4b17023SJohn Marino if (__depth_limit == 0) 2381*e4b17023SJohn Marino { 2382*e4b17023SJohn Marino std::__heap_select(__first, __nth + 1, __last); 2383*e4b17023SJohn Marino 2384*e4b17023SJohn Marino // Place the nth largest element in its final position. 2385*e4b17023SJohn Marino std::iter_swap(__first, __nth); 2386*e4b17023SJohn Marino return; 2387*e4b17023SJohn Marino } 2388*e4b17023SJohn Marino --__depth_limit; 2389*e4b17023SJohn Marino _RandomAccessIterator __cut = 2390*e4b17023SJohn Marino std::__unguarded_partition_pivot(__first, __last); 2391*e4b17023SJohn Marino if (__cut <= __nth) 2392*e4b17023SJohn Marino __first = __cut; 2393*e4b17023SJohn Marino else 2394*e4b17023SJohn Marino __last = __cut; 2395*e4b17023SJohn Marino } 2396*e4b17023SJohn Marino std::__insertion_sort(__first, __last); 2397*e4b17023SJohn Marino } 2398*e4b17023SJohn Marino 2399*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Size, typename _Compare> 2400*e4b17023SJohn Marino void 2401*e4b17023SJohn Marino __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth, 2402*e4b17023SJohn Marino _RandomAccessIterator __last, _Size __depth_limit, 2403*e4b17023SJohn Marino _Compare __comp) 2404*e4b17023SJohn Marino { 2405*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 2406*e4b17023SJohn Marino _ValueType; 2407*e4b17023SJohn Marino 2408*e4b17023SJohn Marino while (__last - __first > 3) 2409*e4b17023SJohn Marino { 2410*e4b17023SJohn Marino if (__depth_limit == 0) 2411*e4b17023SJohn Marino { 2412*e4b17023SJohn Marino std::__heap_select(__first, __nth + 1, __last, __comp); 2413*e4b17023SJohn Marino // Place the nth largest element in its final position. 2414*e4b17023SJohn Marino std::iter_swap(__first, __nth); 2415*e4b17023SJohn Marino return; 2416*e4b17023SJohn Marino } 2417*e4b17023SJohn Marino --__depth_limit; 2418*e4b17023SJohn Marino _RandomAccessIterator __cut = 2419*e4b17023SJohn Marino std::__unguarded_partition_pivot(__first, __last, __comp); 2420*e4b17023SJohn Marino if (__cut <= __nth) 2421*e4b17023SJohn Marino __first = __cut; 2422*e4b17023SJohn Marino else 2423*e4b17023SJohn Marino __last = __cut; 2424*e4b17023SJohn Marino } 2425*e4b17023SJohn Marino std::__insertion_sort(__first, __last, __comp); 2426*e4b17023SJohn Marino } 2427*e4b17023SJohn Marino 2428*e4b17023SJohn Marino // nth_element 2429*e4b17023SJohn Marino 2430*e4b17023SJohn Marino // lower_bound moved to stl_algobase.h 2431*e4b17023SJohn Marino 2432*e4b17023SJohn Marino /** 2433*e4b17023SJohn Marino * @brief Finds the first position in which @p __val could be inserted 2434*e4b17023SJohn Marino * without changing the ordering. 2435*e4b17023SJohn Marino * @ingroup binary_search_algorithms 2436*e4b17023SJohn Marino * @param __first An iterator. 2437*e4b17023SJohn Marino * @param __last Another iterator. 2438*e4b17023SJohn Marino * @param __val The search term. 2439*e4b17023SJohn Marino * @param __comp A functor to use for comparisons. 2440*e4b17023SJohn Marino * @return An iterator pointing to the first element <em>not less 2441*e4b17023SJohn Marino * than</em> @p __val, or end() if every element is less 2442*e4b17023SJohn Marino * than @p __val. 2443*e4b17023SJohn Marino * @ingroup binary_search_algorithms 2444*e4b17023SJohn Marino * 2445*e4b17023SJohn Marino * The comparison function should have the same effects on ordering as 2446*e4b17023SJohn Marino * the function used for the initial sort. 2447*e4b17023SJohn Marino */ 2448*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp, typename _Compare> 2449*e4b17023SJohn Marino _ForwardIterator 2450*e4b17023SJohn Marino lower_bound(_ForwardIterator __first, _ForwardIterator __last, 2451*e4b17023SJohn Marino const _Tp& __val, _Compare __comp) 2452*e4b17023SJohn Marino { 2453*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type 2454*e4b17023SJohn Marino _ValueType; 2455*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type 2456*e4b17023SJohn Marino _DistanceType; 2457*e4b17023SJohn Marino 2458*e4b17023SJohn Marino // concept requirements 2459*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2460*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2461*e4b17023SJohn Marino _ValueType, _Tp>) 2462*e4b17023SJohn Marino __glibcxx_requires_partitioned_lower_pred(__first, __last, 2463*e4b17023SJohn Marino __val, __comp); 2464*e4b17023SJohn Marino 2465*e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last); 2466*e4b17023SJohn Marino 2467*e4b17023SJohn Marino while (__len > 0) 2468*e4b17023SJohn Marino { 2469*e4b17023SJohn Marino _DistanceType __half = __len >> 1; 2470*e4b17023SJohn Marino _ForwardIterator __middle = __first; 2471*e4b17023SJohn Marino std::advance(__middle, __half); 2472*e4b17023SJohn Marino if (__comp(*__middle, __val)) 2473*e4b17023SJohn Marino { 2474*e4b17023SJohn Marino __first = __middle; 2475*e4b17023SJohn Marino ++__first; 2476*e4b17023SJohn Marino __len = __len - __half - 1; 2477*e4b17023SJohn Marino } 2478*e4b17023SJohn Marino else 2479*e4b17023SJohn Marino __len = __half; 2480*e4b17023SJohn Marino } 2481*e4b17023SJohn Marino return __first; 2482*e4b17023SJohn Marino } 2483*e4b17023SJohn Marino 2484*e4b17023SJohn Marino /** 2485*e4b17023SJohn Marino * @brief Finds the last position in which @p __val could be inserted 2486*e4b17023SJohn Marino * without changing the ordering. 2487*e4b17023SJohn Marino * @ingroup binary_search_algorithms 2488*e4b17023SJohn Marino * @param __first An iterator. 2489*e4b17023SJohn Marino * @param __last Another iterator. 2490*e4b17023SJohn Marino * @param __val The search term. 2491*e4b17023SJohn Marino * @return An iterator pointing to the first element greater than @p __val, 2492*e4b17023SJohn Marino * or end() if no elements are greater than @p __val. 2493*e4b17023SJohn Marino * @ingroup binary_search_algorithms 2494*e4b17023SJohn Marino */ 2495*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp> 2496*e4b17023SJohn Marino _ForwardIterator 2497*e4b17023SJohn Marino upper_bound(_ForwardIterator __first, _ForwardIterator __last, 2498*e4b17023SJohn Marino const _Tp& __val) 2499*e4b17023SJohn Marino { 2500*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type 2501*e4b17023SJohn Marino _ValueType; 2502*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type 2503*e4b17023SJohn Marino _DistanceType; 2504*e4b17023SJohn Marino 2505*e4b17023SJohn Marino // concept requirements 2506*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2507*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) 2508*e4b17023SJohn Marino __glibcxx_requires_partitioned_upper(__first, __last, __val); 2509*e4b17023SJohn Marino 2510*e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last); 2511*e4b17023SJohn Marino 2512*e4b17023SJohn Marino while (__len > 0) 2513*e4b17023SJohn Marino { 2514*e4b17023SJohn Marino _DistanceType __half = __len >> 1; 2515*e4b17023SJohn Marino _ForwardIterator __middle = __first; 2516*e4b17023SJohn Marino std::advance(__middle, __half); 2517*e4b17023SJohn Marino if (__val < *__middle) 2518*e4b17023SJohn Marino __len = __half; 2519*e4b17023SJohn Marino else 2520*e4b17023SJohn Marino { 2521*e4b17023SJohn Marino __first = __middle; 2522*e4b17023SJohn Marino ++__first; 2523*e4b17023SJohn Marino __len = __len - __half - 1; 2524*e4b17023SJohn Marino } 2525*e4b17023SJohn Marino } 2526*e4b17023SJohn Marino return __first; 2527*e4b17023SJohn Marino } 2528*e4b17023SJohn Marino 2529*e4b17023SJohn Marino /** 2530*e4b17023SJohn Marino * @brief Finds the last position in which @p __val could be inserted 2531*e4b17023SJohn Marino * without changing the ordering. 2532*e4b17023SJohn Marino * @ingroup binary_search_algorithms 2533*e4b17023SJohn Marino * @param __first An iterator. 2534*e4b17023SJohn Marino * @param __last Another iterator. 2535*e4b17023SJohn Marino * @param __val The search term. 2536*e4b17023SJohn Marino * @param __comp A functor to use for comparisons. 2537*e4b17023SJohn Marino * @return An iterator pointing to the first element greater than @p __val, 2538*e4b17023SJohn Marino * or end() if no elements are greater than @p __val. 2539*e4b17023SJohn Marino * @ingroup binary_search_algorithms 2540*e4b17023SJohn Marino * 2541*e4b17023SJohn Marino * The comparison function should have the same effects on ordering as 2542*e4b17023SJohn Marino * the function used for the initial sort. 2543*e4b17023SJohn Marino */ 2544*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp, typename _Compare> 2545*e4b17023SJohn Marino _ForwardIterator 2546*e4b17023SJohn Marino upper_bound(_ForwardIterator __first, _ForwardIterator __last, 2547*e4b17023SJohn Marino const _Tp& __val, _Compare __comp) 2548*e4b17023SJohn Marino { 2549*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type 2550*e4b17023SJohn Marino _ValueType; 2551*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type 2552*e4b17023SJohn Marino _DistanceType; 2553*e4b17023SJohn Marino 2554*e4b17023SJohn Marino // concept requirements 2555*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2556*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2557*e4b17023SJohn Marino _Tp, _ValueType>) 2558*e4b17023SJohn Marino __glibcxx_requires_partitioned_upper_pred(__first, __last, 2559*e4b17023SJohn Marino __val, __comp); 2560*e4b17023SJohn Marino 2561*e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last); 2562*e4b17023SJohn Marino 2563*e4b17023SJohn Marino while (__len > 0) 2564*e4b17023SJohn Marino { 2565*e4b17023SJohn Marino _DistanceType __half = __len >> 1; 2566*e4b17023SJohn Marino _ForwardIterator __middle = __first; 2567*e4b17023SJohn Marino std::advance(__middle, __half); 2568*e4b17023SJohn Marino if (__comp(__val, *__middle)) 2569*e4b17023SJohn Marino __len = __half; 2570*e4b17023SJohn Marino else 2571*e4b17023SJohn Marino { 2572*e4b17023SJohn Marino __first = __middle; 2573*e4b17023SJohn Marino ++__first; 2574*e4b17023SJohn Marino __len = __len - __half - 1; 2575*e4b17023SJohn Marino } 2576*e4b17023SJohn Marino } 2577*e4b17023SJohn Marino return __first; 2578*e4b17023SJohn Marino } 2579*e4b17023SJohn Marino 2580*e4b17023SJohn Marino /** 2581*e4b17023SJohn Marino * @brief Finds the largest subrange in which @p __val could be inserted 2582*e4b17023SJohn Marino * at any place in it without changing the ordering. 2583*e4b17023SJohn Marino * @ingroup binary_search_algorithms 2584*e4b17023SJohn Marino * @param __first An iterator. 2585*e4b17023SJohn Marino * @param __last Another iterator. 2586*e4b17023SJohn Marino * @param __val The search term. 2587*e4b17023SJohn Marino * @return An pair of iterators defining the subrange. 2588*e4b17023SJohn Marino * @ingroup binary_search_algorithms 2589*e4b17023SJohn Marino * 2590*e4b17023SJohn Marino * This is equivalent to 2591*e4b17023SJohn Marino * @code 2592*e4b17023SJohn Marino * std::make_pair(lower_bound(__first, __last, __val), 2593*e4b17023SJohn Marino * upper_bound(__first, __last, __val)) 2594*e4b17023SJohn Marino * @endcode 2595*e4b17023SJohn Marino * but does not actually call those functions. 2596*e4b17023SJohn Marino */ 2597*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp> 2598*e4b17023SJohn Marino pair<_ForwardIterator, _ForwardIterator> 2599*e4b17023SJohn Marino equal_range(_ForwardIterator __first, _ForwardIterator __last, 2600*e4b17023SJohn Marino const _Tp& __val) 2601*e4b17023SJohn Marino { 2602*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type 2603*e4b17023SJohn Marino _ValueType; 2604*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type 2605*e4b17023SJohn Marino _DistanceType; 2606*e4b17023SJohn Marino 2607*e4b17023SJohn Marino // concept requirements 2608*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2609*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>) 2610*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) 2611*e4b17023SJohn Marino __glibcxx_requires_partitioned_lower(__first, __last, __val); 2612*e4b17023SJohn Marino __glibcxx_requires_partitioned_upper(__first, __last, __val); 2613*e4b17023SJohn Marino 2614*e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last); 2615*e4b17023SJohn Marino 2616*e4b17023SJohn Marino while (__len > 0) 2617*e4b17023SJohn Marino { 2618*e4b17023SJohn Marino _DistanceType __half = __len >> 1; 2619*e4b17023SJohn Marino _ForwardIterator __middle = __first; 2620*e4b17023SJohn Marino std::advance(__middle, __half); 2621*e4b17023SJohn Marino if (*__middle < __val) 2622*e4b17023SJohn Marino { 2623*e4b17023SJohn Marino __first = __middle; 2624*e4b17023SJohn Marino ++__first; 2625*e4b17023SJohn Marino __len = __len - __half - 1; 2626*e4b17023SJohn Marino } 2627*e4b17023SJohn Marino else if (__val < *__middle) 2628*e4b17023SJohn Marino __len = __half; 2629*e4b17023SJohn Marino else 2630*e4b17023SJohn Marino { 2631*e4b17023SJohn Marino _ForwardIterator __left = std::lower_bound(__first, __middle, 2632*e4b17023SJohn Marino __val); 2633*e4b17023SJohn Marino std::advance(__first, __len); 2634*e4b17023SJohn Marino _ForwardIterator __right = std::upper_bound(++__middle, __first, 2635*e4b17023SJohn Marino __val); 2636*e4b17023SJohn Marino return pair<_ForwardIterator, _ForwardIterator>(__left, __right); 2637*e4b17023SJohn Marino } 2638*e4b17023SJohn Marino } 2639*e4b17023SJohn Marino return pair<_ForwardIterator, _ForwardIterator>(__first, __first); 2640*e4b17023SJohn Marino } 2641*e4b17023SJohn Marino 2642*e4b17023SJohn Marino /** 2643*e4b17023SJohn Marino * @brief Finds the largest subrange in which @p __val could be inserted 2644*e4b17023SJohn Marino * at any place in it without changing the ordering. 2645*e4b17023SJohn Marino * @param __first An iterator. 2646*e4b17023SJohn Marino * @param __last Another iterator. 2647*e4b17023SJohn Marino * @param __val The search term. 2648*e4b17023SJohn Marino * @param __comp A functor to use for comparisons. 2649*e4b17023SJohn Marino * @return An pair of iterators defining the subrange. 2650*e4b17023SJohn Marino * @ingroup binary_search_algorithms 2651*e4b17023SJohn Marino * 2652*e4b17023SJohn Marino * This is equivalent to 2653*e4b17023SJohn Marino * @code 2654*e4b17023SJohn Marino * std::make_pair(lower_bound(__first, __last, __val, __comp), 2655*e4b17023SJohn Marino * upper_bound(__first, __last, __val, __comp)) 2656*e4b17023SJohn Marino * @endcode 2657*e4b17023SJohn Marino * but does not actually call those functions. 2658*e4b17023SJohn Marino */ 2659*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp, typename _Compare> 2660*e4b17023SJohn Marino pair<_ForwardIterator, _ForwardIterator> 2661*e4b17023SJohn Marino equal_range(_ForwardIterator __first, _ForwardIterator __last, 2662*e4b17023SJohn Marino const _Tp& __val, _Compare __comp) 2663*e4b17023SJohn Marino { 2664*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type 2665*e4b17023SJohn Marino _ValueType; 2666*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type 2667*e4b17023SJohn Marino _DistanceType; 2668*e4b17023SJohn Marino 2669*e4b17023SJohn Marino // concept requirements 2670*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2671*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2672*e4b17023SJohn Marino _ValueType, _Tp>) 2673*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2674*e4b17023SJohn Marino _Tp, _ValueType>) 2675*e4b17023SJohn Marino __glibcxx_requires_partitioned_lower_pred(__first, __last, 2676*e4b17023SJohn Marino __val, __comp); 2677*e4b17023SJohn Marino __glibcxx_requires_partitioned_upper_pred(__first, __last, 2678*e4b17023SJohn Marino __val, __comp); 2679*e4b17023SJohn Marino 2680*e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last); 2681*e4b17023SJohn Marino 2682*e4b17023SJohn Marino while (__len > 0) 2683*e4b17023SJohn Marino { 2684*e4b17023SJohn Marino _DistanceType __half = __len >> 1; 2685*e4b17023SJohn Marino _ForwardIterator __middle = __first; 2686*e4b17023SJohn Marino std::advance(__middle, __half); 2687*e4b17023SJohn Marino if (__comp(*__middle, __val)) 2688*e4b17023SJohn Marino { 2689*e4b17023SJohn Marino __first = __middle; 2690*e4b17023SJohn Marino ++__first; 2691*e4b17023SJohn Marino __len = __len - __half - 1; 2692*e4b17023SJohn Marino } 2693*e4b17023SJohn Marino else if (__comp(__val, *__middle)) 2694*e4b17023SJohn Marino __len = __half; 2695*e4b17023SJohn Marino else 2696*e4b17023SJohn Marino { 2697*e4b17023SJohn Marino _ForwardIterator __left = std::lower_bound(__first, __middle, 2698*e4b17023SJohn Marino __val, __comp); 2699*e4b17023SJohn Marino std::advance(__first, __len); 2700*e4b17023SJohn Marino _ForwardIterator __right = std::upper_bound(++__middle, __first, 2701*e4b17023SJohn Marino __val, __comp); 2702*e4b17023SJohn Marino return pair<_ForwardIterator, _ForwardIterator>(__left, __right); 2703*e4b17023SJohn Marino } 2704*e4b17023SJohn Marino } 2705*e4b17023SJohn Marino return pair<_ForwardIterator, _ForwardIterator>(__first, __first); 2706*e4b17023SJohn Marino } 2707*e4b17023SJohn Marino 2708*e4b17023SJohn Marino /** 2709*e4b17023SJohn Marino * @brief Determines whether an element exists in a range. 2710*e4b17023SJohn Marino * @ingroup binary_search_algorithms 2711*e4b17023SJohn Marino * @param __first An iterator. 2712*e4b17023SJohn Marino * @param __last Another iterator. 2713*e4b17023SJohn Marino * @param __val The search term. 2714*e4b17023SJohn Marino * @return True if @p __val (or its equivalent) is in [@p 2715*e4b17023SJohn Marino * __first,@p __last ]. 2716*e4b17023SJohn Marino * 2717*e4b17023SJohn Marino * Note that this does not actually return an iterator to @p __val. For 2718*e4b17023SJohn Marino * that, use std::find or a container's specialized find member functions. 2719*e4b17023SJohn Marino */ 2720*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp> 2721*e4b17023SJohn Marino bool 2722*e4b17023SJohn Marino binary_search(_ForwardIterator __first, _ForwardIterator __last, 2723*e4b17023SJohn Marino const _Tp& __val) 2724*e4b17023SJohn Marino { 2725*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type 2726*e4b17023SJohn Marino _ValueType; 2727*e4b17023SJohn Marino 2728*e4b17023SJohn Marino // concept requirements 2729*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2730*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) 2731*e4b17023SJohn Marino __glibcxx_requires_partitioned_lower(__first, __last, __val); 2732*e4b17023SJohn Marino __glibcxx_requires_partitioned_upper(__first, __last, __val); 2733*e4b17023SJohn Marino 2734*e4b17023SJohn Marino _ForwardIterator __i = std::lower_bound(__first, __last, __val); 2735*e4b17023SJohn Marino return __i != __last && !(__val < *__i); 2736*e4b17023SJohn Marino } 2737*e4b17023SJohn Marino 2738*e4b17023SJohn Marino /** 2739*e4b17023SJohn Marino * @brief Determines whether an element exists in a range. 2740*e4b17023SJohn Marino * @ingroup binary_search_algorithms 2741*e4b17023SJohn Marino * @param __first An iterator. 2742*e4b17023SJohn Marino * @param __last Another iterator. 2743*e4b17023SJohn Marino * @param __val The search term. 2744*e4b17023SJohn Marino * @param __comp A functor to use for comparisons. 2745*e4b17023SJohn Marino * @return True if @p __val (or its equivalent) is in @p [__first,__last]. 2746*e4b17023SJohn Marino * 2747*e4b17023SJohn Marino * Note that this does not actually return an iterator to @p __val. For 2748*e4b17023SJohn Marino * that, use std::find or a container's specialized find member functions. 2749*e4b17023SJohn Marino * 2750*e4b17023SJohn Marino * The comparison function should have the same effects on ordering as 2751*e4b17023SJohn Marino * the function used for the initial sort. 2752*e4b17023SJohn Marino */ 2753*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp, typename _Compare> 2754*e4b17023SJohn Marino bool 2755*e4b17023SJohn Marino binary_search(_ForwardIterator __first, _ForwardIterator __last, 2756*e4b17023SJohn Marino const _Tp& __val, _Compare __comp) 2757*e4b17023SJohn Marino { 2758*e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type 2759*e4b17023SJohn Marino _ValueType; 2760*e4b17023SJohn Marino 2761*e4b17023SJohn Marino // concept requirements 2762*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2763*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2764*e4b17023SJohn Marino _Tp, _ValueType>) 2765*e4b17023SJohn Marino __glibcxx_requires_partitioned_lower_pred(__first, __last, 2766*e4b17023SJohn Marino __val, __comp); 2767*e4b17023SJohn Marino __glibcxx_requires_partitioned_upper_pred(__first, __last, 2768*e4b17023SJohn Marino __val, __comp); 2769*e4b17023SJohn Marino 2770*e4b17023SJohn Marino _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp); 2771*e4b17023SJohn Marino return __i != __last && !bool(__comp(__val, *__i)); 2772*e4b17023SJohn Marino } 2773*e4b17023SJohn Marino 2774*e4b17023SJohn Marino // merge 2775*e4b17023SJohn Marino 2776*e4b17023SJohn Marino /// This is a helper function for the __merge_adaptive routines. 2777*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 2778*e4b17023SJohn Marino typename _OutputIterator> 2779*e4b17023SJohn Marino void 2780*e4b17023SJohn Marino __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1, 2781*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 2782*e4b17023SJohn Marino _OutputIterator __result) 2783*e4b17023SJohn Marino { 2784*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 2785*e4b17023SJohn Marino { 2786*e4b17023SJohn Marino if (*__first2 < *__first1) 2787*e4b17023SJohn Marino { 2788*e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first2); 2789*e4b17023SJohn Marino ++__first2; 2790*e4b17023SJohn Marino } 2791*e4b17023SJohn Marino else 2792*e4b17023SJohn Marino { 2793*e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first1); 2794*e4b17023SJohn Marino ++__first1; 2795*e4b17023SJohn Marino } 2796*e4b17023SJohn Marino ++__result; 2797*e4b17023SJohn Marino } 2798*e4b17023SJohn Marino if (__first1 != __last1) 2799*e4b17023SJohn Marino _GLIBCXX_MOVE3(__first1, __last1, __result); 2800*e4b17023SJohn Marino } 2801*e4b17023SJohn Marino 2802*e4b17023SJohn Marino /// This is a helper function for the __merge_adaptive routines. 2803*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 2804*e4b17023SJohn Marino typename _OutputIterator, typename _Compare> 2805*e4b17023SJohn Marino void 2806*e4b17023SJohn Marino __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1, 2807*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 2808*e4b17023SJohn Marino _OutputIterator __result, _Compare __comp) 2809*e4b17023SJohn Marino { 2810*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 2811*e4b17023SJohn Marino { 2812*e4b17023SJohn Marino if (__comp(*__first2, *__first1)) 2813*e4b17023SJohn Marino { 2814*e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first2); 2815*e4b17023SJohn Marino ++__first2; 2816*e4b17023SJohn Marino } 2817*e4b17023SJohn Marino else 2818*e4b17023SJohn Marino { 2819*e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first1); 2820*e4b17023SJohn Marino ++__first1; 2821*e4b17023SJohn Marino } 2822*e4b17023SJohn Marino ++__result; 2823*e4b17023SJohn Marino } 2824*e4b17023SJohn Marino if (__first1 != __last1) 2825*e4b17023SJohn Marino _GLIBCXX_MOVE3(__first1, __last1, __result); 2826*e4b17023SJohn Marino } 2827*e4b17023SJohn Marino 2828*e4b17023SJohn Marino /// This is a helper function for the __merge_adaptive routines. 2829*e4b17023SJohn Marino template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, 2830*e4b17023SJohn Marino typename _BidirectionalIterator3> 2831*e4b17023SJohn Marino void 2832*e4b17023SJohn Marino __move_merge_adaptive_backward(_BidirectionalIterator1 __first1, 2833*e4b17023SJohn Marino _BidirectionalIterator1 __last1, 2834*e4b17023SJohn Marino _BidirectionalIterator2 __first2, 2835*e4b17023SJohn Marino _BidirectionalIterator2 __last2, 2836*e4b17023SJohn Marino _BidirectionalIterator3 __result) 2837*e4b17023SJohn Marino { 2838*e4b17023SJohn Marino if (__first1 == __last1) 2839*e4b17023SJohn Marino { 2840*e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first2, __last2, __result); 2841*e4b17023SJohn Marino return; 2842*e4b17023SJohn Marino } 2843*e4b17023SJohn Marino else if (__first2 == __last2) 2844*e4b17023SJohn Marino return; 2845*e4b17023SJohn Marino 2846*e4b17023SJohn Marino --__last1; 2847*e4b17023SJohn Marino --__last2; 2848*e4b17023SJohn Marino while (true) 2849*e4b17023SJohn Marino { 2850*e4b17023SJohn Marino if (*__last2 < *__last1) 2851*e4b17023SJohn Marino { 2852*e4b17023SJohn Marino *--__result = _GLIBCXX_MOVE(*__last1); 2853*e4b17023SJohn Marino if (__first1 == __last1) 2854*e4b17023SJohn Marino { 2855*e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first2, ++__last2, __result); 2856*e4b17023SJohn Marino return; 2857*e4b17023SJohn Marino } 2858*e4b17023SJohn Marino --__last1; 2859*e4b17023SJohn Marino } 2860*e4b17023SJohn Marino else 2861*e4b17023SJohn Marino { 2862*e4b17023SJohn Marino *--__result = _GLIBCXX_MOVE(*__last2); 2863*e4b17023SJohn Marino if (__first2 == __last2) 2864*e4b17023SJohn Marino return; 2865*e4b17023SJohn Marino --__last2; 2866*e4b17023SJohn Marino } 2867*e4b17023SJohn Marino } 2868*e4b17023SJohn Marino } 2869*e4b17023SJohn Marino 2870*e4b17023SJohn Marino /// This is a helper function for the __merge_adaptive routines. 2871*e4b17023SJohn Marino template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, 2872*e4b17023SJohn Marino typename _BidirectionalIterator3, typename _Compare> 2873*e4b17023SJohn Marino void 2874*e4b17023SJohn Marino __move_merge_adaptive_backward(_BidirectionalIterator1 __first1, 2875*e4b17023SJohn Marino _BidirectionalIterator1 __last1, 2876*e4b17023SJohn Marino _BidirectionalIterator2 __first2, 2877*e4b17023SJohn Marino _BidirectionalIterator2 __last2, 2878*e4b17023SJohn Marino _BidirectionalIterator3 __result, 2879*e4b17023SJohn Marino _Compare __comp) 2880*e4b17023SJohn Marino { 2881*e4b17023SJohn Marino if (__first1 == __last1) 2882*e4b17023SJohn Marino { 2883*e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first2, __last2, __result); 2884*e4b17023SJohn Marino return; 2885*e4b17023SJohn Marino } 2886*e4b17023SJohn Marino else if (__first2 == __last2) 2887*e4b17023SJohn Marino return; 2888*e4b17023SJohn Marino 2889*e4b17023SJohn Marino --__last1; 2890*e4b17023SJohn Marino --__last2; 2891*e4b17023SJohn Marino while (true) 2892*e4b17023SJohn Marino { 2893*e4b17023SJohn Marino if (__comp(*__last2, *__last1)) 2894*e4b17023SJohn Marino { 2895*e4b17023SJohn Marino *--__result = _GLIBCXX_MOVE(*__last1); 2896*e4b17023SJohn Marino if (__first1 == __last1) 2897*e4b17023SJohn Marino { 2898*e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first2, ++__last2, __result); 2899*e4b17023SJohn Marino return; 2900*e4b17023SJohn Marino } 2901*e4b17023SJohn Marino --__last1; 2902*e4b17023SJohn Marino } 2903*e4b17023SJohn Marino else 2904*e4b17023SJohn Marino { 2905*e4b17023SJohn Marino *--__result = _GLIBCXX_MOVE(*__last2); 2906*e4b17023SJohn Marino if (__first2 == __last2) 2907*e4b17023SJohn Marino return; 2908*e4b17023SJohn Marino --__last2; 2909*e4b17023SJohn Marino } 2910*e4b17023SJohn Marino } 2911*e4b17023SJohn Marino } 2912*e4b17023SJohn Marino 2913*e4b17023SJohn Marino /// This is a helper function for the merge routines. 2914*e4b17023SJohn Marino template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, 2915*e4b17023SJohn Marino typename _Distance> 2916*e4b17023SJohn Marino _BidirectionalIterator1 2917*e4b17023SJohn Marino __rotate_adaptive(_BidirectionalIterator1 __first, 2918*e4b17023SJohn Marino _BidirectionalIterator1 __middle, 2919*e4b17023SJohn Marino _BidirectionalIterator1 __last, 2920*e4b17023SJohn Marino _Distance __len1, _Distance __len2, 2921*e4b17023SJohn Marino _BidirectionalIterator2 __buffer, 2922*e4b17023SJohn Marino _Distance __buffer_size) 2923*e4b17023SJohn Marino { 2924*e4b17023SJohn Marino _BidirectionalIterator2 __buffer_end; 2925*e4b17023SJohn Marino if (__len1 > __len2 && __len2 <= __buffer_size) 2926*e4b17023SJohn Marino { 2927*e4b17023SJohn Marino if (__len2) 2928*e4b17023SJohn Marino { 2929*e4b17023SJohn Marino __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer); 2930*e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first, __middle, __last); 2931*e4b17023SJohn Marino return _GLIBCXX_MOVE3(__buffer, __buffer_end, __first); 2932*e4b17023SJohn Marino } 2933*e4b17023SJohn Marino else 2934*e4b17023SJohn Marino return __first; 2935*e4b17023SJohn Marino } 2936*e4b17023SJohn Marino else if (__len1 <= __buffer_size) 2937*e4b17023SJohn Marino { 2938*e4b17023SJohn Marino if (__len1) 2939*e4b17023SJohn Marino { 2940*e4b17023SJohn Marino __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer); 2941*e4b17023SJohn Marino _GLIBCXX_MOVE3(__middle, __last, __first); 2942*e4b17023SJohn Marino return _GLIBCXX_MOVE_BACKWARD3(__buffer, __buffer_end, __last); 2943*e4b17023SJohn Marino } 2944*e4b17023SJohn Marino else 2945*e4b17023SJohn Marino return __last; 2946*e4b17023SJohn Marino } 2947*e4b17023SJohn Marino else 2948*e4b17023SJohn Marino { 2949*e4b17023SJohn Marino std::rotate(__first, __middle, __last); 2950*e4b17023SJohn Marino std::advance(__first, std::distance(__middle, __last)); 2951*e4b17023SJohn Marino return __first; 2952*e4b17023SJohn Marino } 2953*e4b17023SJohn Marino } 2954*e4b17023SJohn Marino 2955*e4b17023SJohn Marino /// This is a helper function for the merge routines. 2956*e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Distance, 2957*e4b17023SJohn Marino typename _Pointer> 2958*e4b17023SJohn Marino void 2959*e4b17023SJohn Marino __merge_adaptive(_BidirectionalIterator __first, 2960*e4b17023SJohn Marino _BidirectionalIterator __middle, 2961*e4b17023SJohn Marino _BidirectionalIterator __last, 2962*e4b17023SJohn Marino _Distance __len1, _Distance __len2, 2963*e4b17023SJohn Marino _Pointer __buffer, _Distance __buffer_size) 2964*e4b17023SJohn Marino { 2965*e4b17023SJohn Marino if (__len1 <= __len2 && __len1 <= __buffer_size) 2966*e4b17023SJohn Marino { 2967*e4b17023SJohn Marino _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer); 2968*e4b17023SJohn Marino std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last, 2969*e4b17023SJohn Marino __first); 2970*e4b17023SJohn Marino } 2971*e4b17023SJohn Marino else if (__len2 <= __buffer_size) 2972*e4b17023SJohn Marino { 2973*e4b17023SJohn Marino _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer); 2974*e4b17023SJohn Marino std::__move_merge_adaptive_backward(__first, __middle, __buffer, 2975*e4b17023SJohn Marino __buffer_end, __last); 2976*e4b17023SJohn Marino } 2977*e4b17023SJohn Marino else 2978*e4b17023SJohn Marino { 2979*e4b17023SJohn Marino _BidirectionalIterator __first_cut = __first; 2980*e4b17023SJohn Marino _BidirectionalIterator __second_cut = __middle; 2981*e4b17023SJohn Marino _Distance __len11 = 0; 2982*e4b17023SJohn Marino _Distance __len22 = 0; 2983*e4b17023SJohn Marino if (__len1 > __len2) 2984*e4b17023SJohn Marino { 2985*e4b17023SJohn Marino __len11 = __len1 / 2; 2986*e4b17023SJohn Marino std::advance(__first_cut, __len11); 2987*e4b17023SJohn Marino __second_cut = std::lower_bound(__middle, __last, 2988*e4b17023SJohn Marino *__first_cut); 2989*e4b17023SJohn Marino __len22 = std::distance(__middle, __second_cut); 2990*e4b17023SJohn Marino } 2991*e4b17023SJohn Marino else 2992*e4b17023SJohn Marino { 2993*e4b17023SJohn Marino __len22 = __len2 / 2; 2994*e4b17023SJohn Marino std::advance(__second_cut, __len22); 2995*e4b17023SJohn Marino __first_cut = std::upper_bound(__first, __middle, 2996*e4b17023SJohn Marino *__second_cut); 2997*e4b17023SJohn Marino __len11 = std::distance(__first, __first_cut); 2998*e4b17023SJohn Marino } 2999*e4b17023SJohn Marino _BidirectionalIterator __new_middle = 3000*e4b17023SJohn Marino std::__rotate_adaptive(__first_cut, __middle, __second_cut, 3001*e4b17023SJohn Marino __len1 - __len11, __len22, __buffer, 3002*e4b17023SJohn Marino __buffer_size); 3003*e4b17023SJohn Marino std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, 3004*e4b17023SJohn Marino __len22, __buffer, __buffer_size); 3005*e4b17023SJohn Marino std::__merge_adaptive(__new_middle, __second_cut, __last, 3006*e4b17023SJohn Marino __len1 - __len11, 3007*e4b17023SJohn Marino __len2 - __len22, __buffer, __buffer_size); 3008*e4b17023SJohn Marino } 3009*e4b17023SJohn Marino } 3010*e4b17023SJohn Marino 3011*e4b17023SJohn Marino /// This is a helper function for the merge routines. 3012*e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Distance, 3013*e4b17023SJohn Marino typename _Pointer, typename _Compare> 3014*e4b17023SJohn Marino void 3015*e4b17023SJohn Marino __merge_adaptive(_BidirectionalIterator __first, 3016*e4b17023SJohn Marino _BidirectionalIterator __middle, 3017*e4b17023SJohn Marino _BidirectionalIterator __last, 3018*e4b17023SJohn Marino _Distance __len1, _Distance __len2, 3019*e4b17023SJohn Marino _Pointer __buffer, _Distance __buffer_size, 3020*e4b17023SJohn Marino _Compare __comp) 3021*e4b17023SJohn Marino { 3022*e4b17023SJohn Marino if (__len1 <= __len2 && __len1 <= __buffer_size) 3023*e4b17023SJohn Marino { 3024*e4b17023SJohn Marino _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer); 3025*e4b17023SJohn Marino std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last, 3026*e4b17023SJohn Marino __first, __comp); 3027*e4b17023SJohn Marino } 3028*e4b17023SJohn Marino else if (__len2 <= __buffer_size) 3029*e4b17023SJohn Marino { 3030*e4b17023SJohn Marino _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer); 3031*e4b17023SJohn Marino std::__move_merge_adaptive_backward(__first, __middle, __buffer, 3032*e4b17023SJohn Marino __buffer_end, __last, __comp); 3033*e4b17023SJohn Marino } 3034*e4b17023SJohn Marino else 3035*e4b17023SJohn Marino { 3036*e4b17023SJohn Marino _BidirectionalIterator __first_cut = __first; 3037*e4b17023SJohn Marino _BidirectionalIterator __second_cut = __middle; 3038*e4b17023SJohn Marino _Distance __len11 = 0; 3039*e4b17023SJohn Marino _Distance __len22 = 0; 3040*e4b17023SJohn Marino if (__len1 > __len2) 3041*e4b17023SJohn Marino { 3042*e4b17023SJohn Marino __len11 = __len1 / 2; 3043*e4b17023SJohn Marino std::advance(__first_cut, __len11); 3044*e4b17023SJohn Marino __second_cut = std::lower_bound(__middle, __last, *__first_cut, 3045*e4b17023SJohn Marino __comp); 3046*e4b17023SJohn Marino __len22 = std::distance(__middle, __second_cut); 3047*e4b17023SJohn Marino } 3048*e4b17023SJohn Marino else 3049*e4b17023SJohn Marino { 3050*e4b17023SJohn Marino __len22 = __len2 / 2; 3051*e4b17023SJohn Marino std::advance(__second_cut, __len22); 3052*e4b17023SJohn Marino __first_cut = std::upper_bound(__first, __middle, *__second_cut, 3053*e4b17023SJohn Marino __comp); 3054*e4b17023SJohn Marino __len11 = std::distance(__first, __first_cut); 3055*e4b17023SJohn Marino } 3056*e4b17023SJohn Marino _BidirectionalIterator __new_middle = 3057*e4b17023SJohn Marino std::__rotate_adaptive(__first_cut, __middle, __second_cut, 3058*e4b17023SJohn Marino __len1 - __len11, __len22, __buffer, 3059*e4b17023SJohn Marino __buffer_size); 3060*e4b17023SJohn Marino std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, 3061*e4b17023SJohn Marino __len22, __buffer, __buffer_size, __comp); 3062*e4b17023SJohn Marino std::__merge_adaptive(__new_middle, __second_cut, __last, 3063*e4b17023SJohn Marino __len1 - __len11, 3064*e4b17023SJohn Marino __len2 - __len22, __buffer, 3065*e4b17023SJohn Marino __buffer_size, __comp); 3066*e4b17023SJohn Marino } 3067*e4b17023SJohn Marino } 3068*e4b17023SJohn Marino 3069*e4b17023SJohn Marino /// This is a helper function for the merge routines. 3070*e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Distance> 3071*e4b17023SJohn Marino void 3072*e4b17023SJohn Marino __merge_without_buffer(_BidirectionalIterator __first, 3073*e4b17023SJohn Marino _BidirectionalIterator __middle, 3074*e4b17023SJohn Marino _BidirectionalIterator __last, 3075*e4b17023SJohn Marino _Distance __len1, _Distance __len2) 3076*e4b17023SJohn Marino { 3077*e4b17023SJohn Marino if (__len1 == 0 || __len2 == 0) 3078*e4b17023SJohn Marino return; 3079*e4b17023SJohn Marino if (__len1 + __len2 == 2) 3080*e4b17023SJohn Marino { 3081*e4b17023SJohn Marino if (*__middle < *__first) 3082*e4b17023SJohn Marino std::iter_swap(__first, __middle); 3083*e4b17023SJohn Marino return; 3084*e4b17023SJohn Marino } 3085*e4b17023SJohn Marino _BidirectionalIterator __first_cut = __first; 3086*e4b17023SJohn Marino _BidirectionalIterator __second_cut = __middle; 3087*e4b17023SJohn Marino _Distance __len11 = 0; 3088*e4b17023SJohn Marino _Distance __len22 = 0; 3089*e4b17023SJohn Marino if (__len1 > __len2) 3090*e4b17023SJohn Marino { 3091*e4b17023SJohn Marino __len11 = __len1 / 2; 3092*e4b17023SJohn Marino std::advance(__first_cut, __len11); 3093*e4b17023SJohn Marino __second_cut = std::lower_bound(__middle, __last, *__first_cut); 3094*e4b17023SJohn Marino __len22 = std::distance(__middle, __second_cut); 3095*e4b17023SJohn Marino } 3096*e4b17023SJohn Marino else 3097*e4b17023SJohn Marino { 3098*e4b17023SJohn Marino __len22 = __len2 / 2; 3099*e4b17023SJohn Marino std::advance(__second_cut, __len22); 3100*e4b17023SJohn Marino __first_cut = std::upper_bound(__first, __middle, *__second_cut); 3101*e4b17023SJohn Marino __len11 = std::distance(__first, __first_cut); 3102*e4b17023SJohn Marino } 3103*e4b17023SJohn Marino std::rotate(__first_cut, __middle, __second_cut); 3104*e4b17023SJohn Marino _BidirectionalIterator __new_middle = __first_cut; 3105*e4b17023SJohn Marino std::advance(__new_middle, std::distance(__middle, __second_cut)); 3106*e4b17023SJohn Marino std::__merge_without_buffer(__first, __first_cut, __new_middle, 3107*e4b17023SJohn Marino __len11, __len22); 3108*e4b17023SJohn Marino std::__merge_without_buffer(__new_middle, __second_cut, __last, 3109*e4b17023SJohn Marino __len1 - __len11, __len2 - __len22); 3110*e4b17023SJohn Marino } 3111*e4b17023SJohn Marino 3112*e4b17023SJohn Marino /// This is a helper function for the merge routines. 3113*e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Distance, 3114*e4b17023SJohn Marino typename _Compare> 3115*e4b17023SJohn Marino void 3116*e4b17023SJohn Marino __merge_without_buffer(_BidirectionalIterator __first, 3117*e4b17023SJohn Marino _BidirectionalIterator __middle, 3118*e4b17023SJohn Marino _BidirectionalIterator __last, 3119*e4b17023SJohn Marino _Distance __len1, _Distance __len2, 3120*e4b17023SJohn Marino _Compare __comp) 3121*e4b17023SJohn Marino { 3122*e4b17023SJohn Marino if (__len1 == 0 || __len2 == 0) 3123*e4b17023SJohn Marino return; 3124*e4b17023SJohn Marino if (__len1 + __len2 == 2) 3125*e4b17023SJohn Marino { 3126*e4b17023SJohn Marino if (__comp(*__middle, *__first)) 3127*e4b17023SJohn Marino std::iter_swap(__first, __middle); 3128*e4b17023SJohn Marino return; 3129*e4b17023SJohn Marino } 3130*e4b17023SJohn Marino _BidirectionalIterator __first_cut = __first; 3131*e4b17023SJohn Marino _BidirectionalIterator __second_cut = __middle; 3132*e4b17023SJohn Marino _Distance __len11 = 0; 3133*e4b17023SJohn Marino _Distance __len22 = 0; 3134*e4b17023SJohn Marino if (__len1 > __len2) 3135*e4b17023SJohn Marino { 3136*e4b17023SJohn Marino __len11 = __len1 / 2; 3137*e4b17023SJohn Marino std::advance(__first_cut, __len11); 3138*e4b17023SJohn Marino __second_cut = std::lower_bound(__middle, __last, *__first_cut, 3139*e4b17023SJohn Marino __comp); 3140*e4b17023SJohn Marino __len22 = std::distance(__middle, __second_cut); 3141*e4b17023SJohn Marino } 3142*e4b17023SJohn Marino else 3143*e4b17023SJohn Marino { 3144*e4b17023SJohn Marino __len22 = __len2 / 2; 3145*e4b17023SJohn Marino std::advance(__second_cut, __len22); 3146*e4b17023SJohn Marino __first_cut = std::upper_bound(__first, __middle, *__second_cut, 3147*e4b17023SJohn Marino __comp); 3148*e4b17023SJohn Marino __len11 = std::distance(__first, __first_cut); 3149*e4b17023SJohn Marino } 3150*e4b17023SJohn Marino std::rotate(__first_cut, __middle, __second_cut); 3151*e4b17023SJohn Marino _BidirectionalIterator __new_middle = __first_cut; 3152*e4b17023SJohn Marino std::advance(__new_middle, std::distance(__middle, __second_cut)); 3153*e4b17023SJohn Marino std::__merge_without_buffer(__first, __first_cut, __new_middle, 3154*e4b17023SJohn Marino __len11, __len22, __comp); 3155*e4b17023SJohn Marino std::__merge_without_buffer(__new_middle, __second_cut, __last, 3156*e4b17023SJohn Marino __len1 - __len11, __len2 - __len22, __comp); 3157*e4b17023SJohn Marino } 3158*e4b17023SJohn Marino 3159*e4b17023SJohn Marino /** 3160*e4b17023SJohn Marino * @brief Merges two sorted ranges in place. 3161*e4b17023SJohn Marino * @ingroup sorting_algorithms 3162*e4b17023SJohn Marino * @param __first An iterator. 3163*e4b17023SJohn Marino * @param __middle Another iterator. 3164*e4b17023SJohn Marino * @param __last Another iterator. 3165*e4b17023SJohn Marino * @return Nothing. 3166*e4b17023SJohn Marino * 3167*e4b17023SJohn Marino * Merges two sorted and consecutive ranges, [__first,__middle) and 3168*e4b17023SJohn Marino * [__middle,__last), and puts the result in [__first,__last). The 3169*e4b17023SJohn Marino * output will be sorted. The sort is @e stable, that is, for 3170*e4b17023SJohn Marino * equivalent elements in the two ranges, elements from the first 3171*e4b17023SJohn Marino * range will always come before elements from the second. 3172*e4b17023SJohn Marino * 3173*e4b17023SJohn Marino * If enough additional memory is available, this takes (__last-__first)-1 3174*e4b17023SJohn Marino * comparisons. Otherwise an NlogN algorithm is used, where N is 3175*e4b17023SJohn Marino * distance(__first,__last). 3176*e4b17023SJohn Marino */ 3177*e4b17023SJohn Marino template<typename _BidirectionalIterator> 3178*e4b17023SJohn Marino void 3179*e4b17023SJohn Marino inplace_merge(_BidirectionalIterator __first, 3180*e4b17023SJohn Marino _BidirectionalIterator __middle, 3181*e4b17023SJohn Marino _BidirectionalIterator __last) 3182*e4b17023SJohn Marino { 3183*e4b17023SJohn Marino typedef typename iterator_traits<_BidirectionalIterator>::value_type 3184*e4b17023SJohn Marino _ValueType; 3185*e4b17023SJohn Marino typedef typename iterator_traits<_BidirectionalIterator>::difference_type 3186*e4b17023SJohn Marino _DistanceType; 3187*e4b17023SJohn Marino 3188*e4b17023SJohn Marino // concept requirements 3189*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< 3190*e4b17023SJohn Marino _BidirectionalIterator>) 3191*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 3192*e4b17023SJohn Marino __glibcxx_requires_sorted(__first, __middle); 3193*e4b17023SJohn Marino __glibcxx_requires_sorted(__middle, __last); 3194*e4b17023SJohn Marino 3195*e4b17023SJohn Marino if (__first == __middle || __middle == __last) 3196*e4b17023SJohn Marino return; 3197*e4b17023SJohn Marino 3198*e4b17023SJohn Marino _DistanceType __len1 = std::distance(__first, __middle); 3199*e4b17023SJohn Marino _DistanceType __len2 = std::distance(__middle, __last); 3200*e4b17023SJohn Marino 3201*e4b17023SJohn Marino _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, 3202*e4b17023SJohn Marino __last); 3203*e4b17023SJohn Marino if (__buf.begin() == 0) 3204*e4b17023SJohn Marino std::__merge_without_buffer(__first, __middle, __last, __len1, __len2); 3205*e4b17023SJohn Marino else 3206*e4b17023SJohn Marino std::__merge_adaptive(__first, __middle, __last, __len1, __len2, 3207*e4b17023SJohn Marino __buf.begin(), _DistanceType(__buf.size())); 3208*e4b17023SJohn Marino } 3209*e4b17023SJohn Marino 3210*e4b17023SJohn Marino /** 3211*e4b17023SJohn Marino * @brief Merges two sorted ranges in place. 3212*e4b17023SJohn Marino * @ingroup sorting_algorithms 3213*e4b17023SJohn Marino * @param __first An iterator. 3214*e4b17023SJohn Marino * @param __middle Another iterator. 3215*e4b17023SJohn Marino * @param __last Another iterator. 3216*e4b17023SJohn Marino * @param __comp A functor to use for comparisons. 3217*e4b17023SJohn Marino * @return Nothing. 3218*e4b17023SJohn Marino * 3219*e4b17023SJohn Marino * Merges two sorted and consecutive ranges, [__first,__middle) and 3220*e4b17023SJohn Marino * [middle,last), and puts the result in [__first,__last). The output will 3221*e4b17023SJohn Marino * be sorted. The sort is @e stable, that is, for equivalent 3222*e4b17023SJohn Marino * elements in the two ranges, elements from the first range will always 3223*e4b17023SJohn Marino * come before elements from the second. 3224*e4b17023SJohn Marino * 3225*e4b17023SJohn Marino * If enough additional memory is available, this takes (__last-__first)-1 3226*e4b17023SJohn Marino * comparisons. Otherwise an NlogN algorithm is used, where N is 3227*e4b17023SJohn Marino * distance(__first,__last). 3228*e4b17023SJohn Marino * 3229*e4b17023SJohn Marino * The comparison function should have the same effects on ordering as 3230*e4b17023SJohn Marino * the function used for the initial sort. 3231*e4b17023SJohn Marino */ 3232*e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Compare> 3233*e4b17023SJohn Marino void 3234*e4b17023SJohn Marino inplace_merge(_BidirectionalIterator __first, 3235*e4b17023SJohn Marino _BidirectionalIterator __middle, 3236*e4b17023SJohn Marino _BidirectionalIterator __last, 3237*e4b17023SJohn Marino _Compare __comp) 3238*e4b17023SJohn Marino { 3239*e4b17023SJohn Marino typedef typename iterator_traits<_BidirectionalIterator>::value_type 3240*e4b17023SJohn Marino _ValueType; 3241*e4b17023SJohn Marino typedef typename iterator_traits<_BidirectionalIterator>::difference_type 3242*e4b17023SJohn Marino _DistanceType; 3243*e4b17023SJohn Marino 3244*e4b17023SJohn Marino // concept requirements 3245*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< 3246*e4b17023SJohn Marino _BidirectionalIterator>) 3247*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 3248*e4b17023SJohn Marino _ValueType, _ValueType>) 3249*e4b17023SJohn Marino __glibcxx_requires_sorted_pred(__first, __middle, __comp); 3250*e4b17023SJohn Marino __glibcxx_requires_sorted_pred(__middle, __last, __comp); 3251*e4b17023SJohn Marino 3252*e4b17023SJohn Marino if (__first == __middle || __middle == __last) 3253*e4b17023SJohn Marino return; 3254*e4b17023SJohn Marino 3255*e4b17023SJohn Marino const _DistanceType __len1 = std::distance(__first, __middle); 3256*e4b17023SJohn Marino const _DistanceType __len2 = std::distance(__middle, __last); 3257*e4b17023SJohn Marino 3258*e4b17023SJohn Marino _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, 3259*e4b17023SJohn Marino __last); 3260*e4b17023SJohn Marino if (__buf.begin() == 0) 3261*e4b17023SJohn Marino std::__merge_without_buffer(__first, __middle, __last, __len1, 3262*e4b17023SJohn Marino __len2, __comp); 3263*e4b17023SJohn Marino else 3264*e4b17023SJohn Marino std::__merge_adaptive(__first, __middle, __last, __len1, __len2, 3265*e4b17023SJohn Marino __buf.begin(), _DistanceType(__buf.size()), 3266*e4b17023SJohn Marino __comp); 3267*e4b17023SJohn Marino } 3268*e4b17023SJohn Marino 3269*e4b17023SJohn Marino 3270*e4b17023SJohn Marino /// This is a helper function for the __merge_sort_loop routines. 3271*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 3272*e4b17023SJohn Marino typename _OutputIterator> 3273*e4b17023SJohn Marino _OutputIterator 3274*e4b17023SJohn Marino __move_merge(_InputIterator1 __first1, _InputIterator1 __last1, 3275*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 3276*e4b17023SJohn Marino _OutputIterator __result) 3277*e4b17023SJohn Marino { 3278*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 3279*e4b17023SJohn Marino { 3280*e4b17023SJohn Marino if (*__first2 < *__first1) 3281*e4b17023SJohn Marino { 3282*e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first2); 3283*e4b17023SJohn Marino ++__first2; 3284*e4b17023SJohn Marino } 3285*e4b17023SJohn Marino else 3286*e4b17023SJohn Marino { 3287*e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first1); 3288*e4b17023SJohn Marino ++__first1; 3289*e4b17023SJohn Marino } 3290*e4b17023SJohn Marino ++__result; 3291*e4b17023SJohn Marino } 3292*e4b17023SJohn Marino return _GLIBCXX_MOVE3(__first2, __last2, 3293*e4b17023SJohn Marino _GLIBCXX_MOVE3(__first1, __last1, 3294*e4b17023SJohn Marino __result)); 3295*e4b17023SJohn Marino } 3296*e4b17023SJohn Marino 3297*e4b17023SJohn Marino /// This is a helper function for the __merge_sort_loop routines. 3298*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 3299*e4b17023SJohn Marino typename _OutputIterator, typename _Compare> 3300*e4b17023SJohn Marino _OutputIterator 3301*e4b17023SJohn Marino __move_merge(_InputIterator1 __first1, _InputIterator1 __last1, 3302*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 3303*e4b17023SJohn Marino _OutputIterator __result, _Compare __comp) 3304*e4b17023SJohn Marino { 3305*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 3306*e4b17023SJohn Marino { 3307*e4b17023SJohn Marino if (__comp(*__first2, *__first1)) 3308*e4b17023SJohn Marino { 3309*e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first2); 3310*e4b17023SJohn Marino ++__first2; 3311*e4b17023SJohn Marino } 3312*e4b17023SJohn Marino else 3313*e4b17023SJohn Marino { 3314*e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first1); 3315*e4b17023SJohn Marino ++__first1; 3316*e4b17023SJohn Marino } 3317*e4b17023SJohn Marino ++__result; 3318*e4b17023SJohn Marino } 3319*e4b17023SJohn Marino return _GLIBCXX_MOVE3(__first2, __last2, 3320*e4b17023SJohn Marino _GLIBCXX_MOVE3(__first1, __last1, 3321*e4b17023SJohn Marino __result)); 3322*e4b17023SJohn Marino } 3323*e4b17023SJohn Marino 3324*e4b17023SJohn Marino template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, 3325*e4b17023SJohn Marino typename _Distance> 3326*e4b17023SJohn Marino void 3327*e4b17023SJohn Marino __merge_sort_loop(_RandomAccessIterator1 __first, 3328*e4b17023SJohn Marino _RandomAccessIterator1 __last, 3329*e4b17023SJohn Marino _RandomAccessIterator2 __result, 3330*e4b17023SJohn Marino _Distance __step_size) 3331*e4b17023SJohn Marino { 3332*e4b17023SJohn Marino const _Distance __two_step = 2 * __step_size; 3333*e4b17023SJohn Marino 3334*e4b17023SJohn Marino while (__last - __first >= __two_step) 3335*e4b17023SJohn Marino { 3336*e4b17023SJohn Marino __result = std::__move_merge(__first, __first + __step_size, 3337*e4b17023SJohn Marino __first + __step_size, 3338*e4b17023SJohn Marino __first + __two_step, __result); 3339*e4b17023SJohn Marino __first += __two_step; 3340*e4b17023SJohn Marino } 3341*e4b17023SJohn Marino 3342*e4b17023SJohn Marino __step_size = std::min(_Distance(__last - __first), __step_size); 3343*e4b17023SJohn Marino std::__move_merge(__first, __first + __step_size, 3344*e4b17023SJohn Marino __first + __step_size, __last, __result); 3345*e4b17023SJohn Marino } 3346*e4b17023SJohn Marino 3347*e4b17023SJohn Marino template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, 3348*e4b17023SJohn Marino typename _Distance, typename _Compare> 3349*e4b17023SJohn Marino void 3350*e4b17023SJohn Marino __merge_sort_loop(_RandomAccessIterator1 __first, 3351*e4b17023SJohn Marino _RandomAccessIterator1 __last, 3352*e4b17023SJohn Marino _RandomAccessIterator2 __result, _Distance __step_size, 3353*e4b17023SJohn Marino _Compare __comp) 3354*e4b17023SJohn Marino { 3355*e4b17023SJohn Marino const _Distance __two_step = 2 * __step_size; 3356*e4b17023SJohn Marino 3357*e4b17023SJohn Marino while (__last - __first >= __two_step) 3358*e4b17023SJohn Marino { 3359*e4b17023SJohn Marino __result = std::__move_merge(__first, __first + __step_size, 3360*e4b17023SJohn Marino __first + __step_size, 3361*e4b17023SJohn Marino __first + __two_step, 3362*e4b17023SJohn Marino __result, __comp); 3363*e4b17023SJohn Marino __first += __two_step; 3364*e4b17023SJohn Marino } 3365*e4b17023SJohn Marino __step_size = std::min(_Distance(__last - __first), __step_size); 3366*e4b17023SJohn Marino 3367*e4b17023SJohn Marino std::__move_merge(__first,__first + __step_size, 3368*e4b17023SJohn Marino __first + __step_size, __last, __result, __comp); 3369*e4b17023SJohn Marino } 3370*e4b17023SJohn Marino 3371*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Distance> 3372*e4b17023SJohn Marino void 3373*e4b17023SJohn Marino __chunk_insertion_sort(_RandomAccessIterator __first, 3374*e4b17023SJohn Marino _RandomAccessIterator __last, 3375*e4b17023SJohn Marino _Distance __chunk_size) 3376*e4b17023SJohn Marino { 3377*e4b17023SJohn Marino while (__last - __first >= __chunk_size) 3378*e4b17023SJohn Marino { 3379*e4b17023SJohn Marino std::__insertion_sort(__first, __first + __chunk_size); 3380*e4b17023SJohn Marino __first += __chunk_size; 3381*e4b17023SJohn Marino } 3382*e4b17023SJohn Marino std::__insertion_sort(__first, __last); 3383*e4b17023SJohn Marino } 3384*e4b17023SJohn Marino 3385*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Distance, 3386*e4b17023SJohn Marino typename _Compare> 3387*e4b17023SJohn Marino void 3388*e4b17023SJohn Marino __chunk_insertion_sort(_RandomAccessIterator __first, 3389*e4b17023SJohn Marino _RandomAccessIterator __last, 3390*e4b17023SJohn Marino _Distance __chunk_size, _Compare __comp) 3391*e4b17023SJohn Marino { 3392*e4b17023SJohn Marino while (__last - __first >= __chunk_size) 3393*e4b17023SJohn Marino { 3394*e4b17023SJohn Marino std::__insertion_sort(__first, __first + __chunk_size, __comp); 3395*e4b17023SJohn Marino __first += __chunk_size; 3396*e4b17023SJohn Marino } 3397*e4b17023SJohn Marino std::__insertion_sort(__first, __last, __comp); 3398*e4b17023SJohn Marino } 3399*e4b17023SJohn Marino 3400*e4b17023SJohn Marino enum { _S_chunk_size = 7 }; 3401*e4b17023SJohn Marino 3402*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Pointer> 3403*e4b17023SJohn Marino void 3404*e4b17023SJohn Marino __merge_sort_with_buffer(_RandomAccessIterator __first, 3405*e4b17023SJohn Marino _RandomAccessIterator __last, 3406*e4b17023SJohn Marino _Pointer __buffer) 3407*e4b17023SJohn Marino { 3408*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type 3409*e4b17023SJohn Marino _Distance; 3410*e4b17023SJohn Marino 3411*e4b17023SJohn Marino const _Distance __len = __last - __first; 3412*e4b17023SJohn Marino const _Pointer __buffer_last = __buffer + __len; 3413*e4b17023SJohn Marino 3414*e4b17023SJohn Marino _Distance __step_size = _S_chunk_size; 3415*e4b17023SJohn Marino std::__chunk_insertion_sort(__first, __last, __step_size); 3416*e4b17023SJohn Marino 3417*e4b17023SJohn Marino while (__step_size < __len) 3418*e4b17023SJohn Marino { 3419*e4b17023SJohn Marino std::__merge_sort_loop(__first, __last, __buffer, __step_size); 3420*e4b17023SJohn Marino __step_size *= 2; 3421*e4b17023SJohn Marino std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size); 3422*e4b17023SJohn Marino __step_size *= 2; 3423*e4b17023SJohn Marino } 3424*e4b17023SJohn Marino } 3425*e4b17023SJohn Marino 3426*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Pointer, typename _Compare> 3427*e4b17023SJohn Marino void 3428*e4b17023SJohn Marino __merge_sort_with_buffer(_RandomAccessIterator __first, 3429*e4b17023SJohn Marino _RandomAccessIterator __last, 3430*e4b17023SJohn Marino _Pointer __buffer, _Compare __comp) 3431*e4b17023SJohn Marino { 3432*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type 3433*e4b17023SJohn Marino _Distance; 3434*e4b17023SJohn Marino 3435*e4b17023SJohn Marino const _Distance __len = __last - __first; 3436*e4b17023SJohn Marino const _Pointer __buffer_last = __buffer + __len; 3437*e4b17023SJohn Marino 3438*e4b17023SJohn Marino _Distance __step_size = _S_chunk_size; 3439*e4b17023SJohn Marino std::__chunk_insertion_sort(__first, __last, __step_size, __comp); 3440*e4b17023SJohn Marino 3441*e4b17023SJohn Marino while (__step_size < __len) 3442*e4b17023SJohn Marino { 3443*e4b17023SJohn Marino std::__merge_sort_loop(__first, __last, __buffer, 3444*e4b17023SJohn Marino __step_size, __comp); 3445*e4b17023SJohn Marino __step_size *= 2; 3446*e4b17023SJohn Marino std::__merge_sort_loop(__buffer, __buffer_last, __first, 3447*e4b17023SJohn Marino __step_size, __comp); 3448*e4b17023SJohn Marino __step_size *= 2; 3449*e4b17023SJohn Marino } 3450*e4b17023SJohn Marino } 3451*e4b17023SJohn Marino 3452*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Pointer, 3453*e4b17023SJohn Marino typename _Distance> 3454*e4b17023SJohn Marino void 3455*e4b17023SJohn Marino __stable_sort_adaptive(_RandomAccessIterator __first, 3456*e4b17023SJohn Marino _RandomAccessIterator __last, 3457*e4b17023SJohn Marino _Pointer __buffer, _Distance __buffer_size) 3458*e4b17023SJohn Marino { 3459*e4b17023SJohn Marino const _Distance __len = (__last - __first + 1) / 2; 3460*e4b17023SJohn Marino const _RandomAccessIterator __middle = __first + __len; 3461*e4b17023SJohn Marino if (__len > __buffer_size) 3462*e4b17023SJohn Marino { 3463*e4b17023SJohn Marino std::__stable_sort_adaptive(__first, __middle, 3464*e4b17023SJohn Marino __buffer, __buffer_size); 3465*e4b17023SJohn Marino std::__stable_sort_adaptive(__middle, __last, 3466*e4b17023SJohn Marino __buffer, __buffer_size); 3467*e4b17023SJohn Marino } 3468*e4b17023SJohn Marino else 3469*e4b17023SJohn Marino { 3470*e4b17023SJohn Marino std::__merge_sort_with_buffer(__first, __middle, __buffer); 3471*e4b17023SJohn Marino std::__merge_sort_with_buffer(__middle, __last, __buffer); 3472*e4b17023SJohn Marino } 3473*e4b17023SJohn Marino std::__merge_adaptive(__first, __middle, __last, 3474*e4b17023SJohn Marino _Distance(__middle - __first), 3475*e4b17023SJohn Marino _Distance(__last - __middle), 3476*e4b17023SJohn Marino __buffer, __buffer_size); 3477*e4b17023SJohn Marino } 3478*e4b17023SJohn Marino 3479*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Pointer, 3480*e4b17023SJohn Marino typename _Distance, typename _Compare> 3481*e4b17023SJohn Marino void 3482*e4b17023SJohn Marino __stable_sort_adaptive(_RandomAccessIterator __first, 3483*e4b17023SJohn Marino _RandomAccessIterator __last, 3484*e4b17023SJohn Marino _Pointer __buffer, _Distance __buffer_size, 3485*e4b17023SJohn Marino _Compare __comp) 3486*e4b17023SJohn Marino { 3487*e4b17023SJohn Marino const _Distance __len = (__last - __first + 1) / 2; 3488*e4b17023SJohn Marino const _RandomAccessIterator __middle = __first + __len; 3489*e4b17023SJohn Marino if (__len > __buffer_size) 3490*e4b17023SJohn Marino { 3491*e4b17023SJohn Marino std::__stable_sort_adaptive(__first, __middle, __buffer, 3492*e4b17023SJohn Marino __buffer_size, __comp); 3493*e4b17023SJohn Marino std::__stable_sort_adaptive(__middle, __last, __buffer, 3494*e4b17023SJohn Marino __buffer_size, __comp); 3495*e4b17023SJohn Marino } 3496*e4b17023SJohn Marino else 3497*e4b17023SJohn Marino { 3498*e4b17023SJohn Marino std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp); 3499*e4b17023SJohn Marino std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp); 3500*e4b17023SJohn Marino } 3501*e4b17023SJohn Marino std::__merge_adaptive(__first, __middle, __last, 3502*e4b17023SJohn Marino _Distance(__middle - __first), 3503*e4b17023SJohn Marino _Distance(__last - __middle), 3504*e4b17023SJohn Marino __buffer, __buffer_size, 3505*e4b17023SJohn Marino __comp); 3506*e4b17023SJohn Marino } 3507*e4b17023SJohn Marino 3508*e4b17023SJohn Marino /// This is a helper function for the stable sorting routines. 3509*e4b17023SJohn Marino template<typename _RandomAccessIterator> 3510*e4b17023SJohn Marino void 3511*e4b17023SJohn Marino __inplace_stable_sort(_RandomAccessIterator __first, 3512*e4b17023SJohn Marino _RandomAccessIterator __last) 3513*e4b17023SJohn Marino { 3514*e4b17023SJohn Marino if (__last - __first < 15) 3515*e4b17023SJohn Marino { 3516*e4b17023SJohn Marino std::__insertion_sort(__first, __last); 3517*e4b17023SJohn Marino return; 3518*e4b17023SJohn Marino } 3519*e4b17023SJohn Marino _RandomAccessIterator __middle = __first + (__last - __first) / 2; 3520*e4b17023SJohn Marino std::__inplace_stable_sort(__first, __middle); 3521*e4b17023SJohn Marino std::__inplace_stable_sort(__middle, __last); 3522*e4b17023SJohn Marino std::__merge_without_buffer(__first, __middle, __last, 3523*e4b17023SJohn Marino __middle - __first, 3524*e4b17023SJohn Marino __last - __middle); 3525*e4b17023SJohn Marino } 3526*e4b17023SJohn Marino 3527*e4b17023SJohn Marino /// This is a helper function for the stable sorting routines. 3528*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare> 3529*e4b17023SJohn Marino void 3530*e4b17023SJohn Marino __inplace_stable_sort(_RandomAccessIterator __first, 3531*e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp) 3532*e4b17023SJohn Marino { 3533*e4b17023SJohn Marino if (__last - __first < 15) 3534*e4b17023SJohn Marino { 3535*e4b17023SJohn Marino std::__insertion_sort(__first, __last, __comp); 3536*e4b17023SJohn Marino return; 3537*e4b17023SJohn Marino } 3538*e4b17023SJohn Marino _RandomAccessIterator __middle = __first + (__last - __first) / 2; 3539*e4b17023SJohn Marino std::__inplace_stable_sort(__first, __middle, __comp); 3540*e4b17023SJohn Marino std::__inplace_stable_sort(__middle, __last, __comp); 3541*e4b17023SJohn Marino std::__merge_without_buffer(__first, __middle, __last, 3542*e4b17023SJohn Marino __middle - __first, 3543*e4b17023SJohn Marino __last - __middle, 3544*e4b17023SJohn Marino __comp); 3545*e4b17023SJohn Marino } 3546*e4b17023SJohn Marino 3547*e4b17023SJohn Marino // stable_sort 3548*e4b17023SJohn Marino 3549*e4b17023SJohn Marino // Set algorithms: includes, set_union, set_intersection, set_difference, 3550*e4b17023SJohn Marino // set_symmetric_difference. All of these algorithms have the precondition 3551*e4b17023SJohn Marino // that their input ranges are sorted and the postcondition that their output 3552*e4b17023SJohn Marino // ranges are sorted. 3553*e4b17023SJohn Marino 3554*e4b17023SJohn Marino /** 3555*e4b17023SJohn Marino * @brief Determines whether all elements of a sequence exists in a range. 3556*e4b17023SJohn Marino * @param __first1 Start of search range. 3557*e4b17023SJohn Marino * @param __last1 End of search range. 3558*e4b17023SJohn Marino * @param __first2 Start of sequence 3559*e4b17023SJohn Marino * @param __last2 End of sequence. 3560*e4b17023SJohn Marino * @return True if each element in [__first2,__last2) is contained in order 3561*e4b17023SJohn Marino * within [__first1,__last1). False otherwise. 3562*e4b17023SJohn Marino * @ingroup set_algorithms 3563*e4b17023SJohn Marino * 3564*e4b17023SJohn Marino * This operation expects both [__first1,__last1) and 3565*e4b17023SJohn Marino * [__first2,__last2) to be sorted. Searches for the presence of 3566*e4b17023SJohn Marino * each element in [__first2,__last2) within [__first1,__last1). 3567*e4b17023SJohn Marino * The iterators over each range only move forward, so this is a 3568*e4b17023SJohn Marino * linear algorithm. If an element in [__first2,__last2) is not 3569*e4b17023SJohn Marino * found before the search iterator reaches @p __last2, false is 3570*e4b17023SJohn Marino * returned. 3571*e4b17023SJohn Marino */ 3572*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2> 3573*e4b17023SJohn Marino bool 3574*e4b17023SJohn Marino includes(_InputIterator1 __first1, _InputIterator1 __last1, 3575*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2) 3576*e4b17023SJohn Marino { 3577*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 3578*e4b17023SJohn Marino _ValueType1; 3579*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 3580*e4b17023SJohn Marino _ValueType2; 3581*e4b17023SJohn Marino 3582*e4b17023SJohn Marino // concept requirements 3583*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 3584*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 3585*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) 3586*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 3587*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2); 3588*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1); 3589*e4b17023SJohn Marino 3590*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 3591*e4b17023SJohn Marino if (*__first2 < *__first1) 3592*e4b17023SJohn Marino return false; 3593*e4b17023SJohn Marino else if(*__first1 < *__first2) 3594*e4b17023SJohn Marino ++__first1; 3595*e4b17023SJohn Marino else 3596*e4b17023SJohn Marino ++__first1, ++__first2; 3597*e4b17023SJohn Marino 3598*e4b17023SJohn Marino return __first2 == __last2; 3599*e4b17023SJohn Marino } 3600*e4b17023SJohn Marino 3601*e4b17023SJohn Marino /** 3602*e4b17023SJohn Marino * @brief Determines whether all elements of a sequence exists in a range 3603*e4b17023SJohn Marino * using comparison. 3604*e4b17023SJohn Marino * @ingroup set_algorithms 3605*e4b17023SJohn Marino * @param __first1 Start of search range. 3606*e4b17023SJohn Marino * @param __last1 End of search range. 3607*e4b17023SJohn Marino * @param __first2 Start of sequence 3608*e4b17023SJohn Marino * @param __last2 End of sequence. 3609*e4b17023SJohn Marino * @param __comp Comparison function to use. 3610*e4b17023SJohn Marino * @return True if each element in [__first2,__last2) is contained 3611*e4b17023SJohn Marino * in order within [__first1,__last1) according to comp. False 3612*e4b17023SJohn Marino * otherwise. @ingroup set_algorithms 3613*e4b17023SJohn Marino * 3614*e4b17023SJohn Marino * This operation expects both [__first1,__last1) and 3615*e4b17023SJohn Marino * [__first2,__last2) to be sorted. Searches for the presence of 3616*e4b17023SJohn Marino * each element in [__first2,__last2) within [__first1,__last1), 3617*e4b17023SJohn Marino * using comp to decide. The iterators over each range only move 3618*e4b17023SJohn Marino * forward, so this is a linear algorithm. If an element in 3619*e4b17023SJohn Marino * [__first2,__last2) is not found before the search iterator 3620*e4b17023SJohn Marino * reaches @p __last2, false is returned. 3621*e4b17023SJohn Marino */ 3622*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 3623*e4b17023SJohn Marino typename _Compare> 3624*e4b17023SJohn Marino bool 3625*e4b17023SJohn Marino includes(_InputIterator1 __first1, _InputIterator1 __last1, 3626*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 3627*e4b17023SJohn Marino _Compare __comp) 3628*e4b17023SJohn Marino { 3629*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 3630*e4b17023SJohn Marino _ValueType1; 3631*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 3632*e4b17023SJohn Marino _ValueType2; 3633*e4b17023SJohn Marino 3634*e4b17023SJohn Marino // concept requirements 3635*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 3636*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 3637*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 3638*e4b17023SJohn Marino _ValueType1, _ValueType2>) 3639*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 3640*e4b17023SJohn Marino _ValueType2, _ValueType1>) 3641*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 3642*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 3643*e4b17023SJohn Marino 3644*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 3645*e4b17023SJohn Marino if (__comp(*__first2, *__first1)) 3646*e4b17023SJohn Marino return false; 3647*e4b17023SJohn Marino else if(__comp(*__first1, *__first2)) 3648*e4b17023SJohn Marino ++__first1; 3649*e4b17023SJohn Marino else 3650*e4b17023SJohn Marino ++__first1, ++__first2; 3651*e4b17023SJohn Marino 3652*e4b17023SJohn Marino return __first2 == __last2; 3653*e4b17023SJohn Marino } 3654*e4b17023SJohn Marino 3655*e4b17023SJohn Marino // nth_element 3656*e4b17023SJohn Marino // merge 3657*e4b17023SJohn Marino // set_difference 3658*e4b17023SJohn Marino // set_intersection 3659*e4b17023SJohn Marino // set_union 3660*e4b17023SJohn Marino // stable_sort 3661*e4b17023SJohn Marino // set_symmetric_difference 3662*e4b17023SJohn Marino // min_element 3663*e4b17023SJohn Marino // max_element 3664*e4b17023SJohn Marino 3665*e4b17023SJohn Marino /** 3666*e4b17023SJohn Marino * @brief Permute range into the next @e dictionary ordering. 3667*e4b17023SJohn Marino * @ingroup sorting_algorithms 3668*e4b17023SJohn Marino * @param __first Start of range. 3669*e4b17023SJohn Marino * @param __last End of range. 3670*e4b17023SJohn Marino * @return False if wrapped to first permutation, true otherwise. 3671*e4b17023SJohn Marino * 3672*e4b17023SJohn Marino * Treats all permutations of the range as a set of @e dictionary sorted 3673*e4b17023SJohn Marino * sequences. Permutes the current sequence into the next one of this set. 3674*e4b17023SJohn Marino * Returns true if there are more sequences to generate. If the sequence 3675*e4b17023SJohn Marino * is the largest of the set, the smallest is generated and false returned. 3676*e4b17023SJohn Marino */ 3677*e4b17023SJohn Marino template<typename _BidirectionalIterator> 3678*e4b17023SJohn Marino bool 3679*e4b17023SJohn Marino next_permutation(_BidirectionalIterator __first, 3680*e4b17023SJohn Marino _BidirectionalIterator __last) 3681*e4b17023SJohn Marino { 3682*e4b17023SJohn Marino // concept requirements 3683*e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept< 3684*e4b17023SJohn Marino _BidirectionalIterator>) 3685*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept< 3686*e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type>) 3687*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 3688*e4b17023SJohn Marino 3689*e4b17023SJohn Marino if (__first == __last) 3690*e4b17023SJohn Marino return false; 3691*e4b17023SJohn Marino _BidirectionalIterator __i = __first; 3692*e4b17023SJohn Marino ++__i; 3693*e4b17023SJohn Marino if (__i == __last) 3694*e4b17023SJohn Marino return false; 3695*e4b17023SJohn Marino __i = __last; 3696*e4b17023SJohn Marino --__i; 3697*e4b17023SJohn Marino 3698*e4b17023SJohn Marino for(;;) 3699*e4b17023SJohn Marino { 3700*e4b17023SJohn Marino _BidirectionalIterator __ii = __i; 3701*e4b17023SJohn Marino --__i; 3702*e4b17023SJohn Marino if (*__i < *__ii) 3703*e4b17023SJohn Marino { 3704*e4b17023SJohn Marino _BidirectionalIterator __j = __last; 3705*e4b17023SJohn Marino while (!(*__i < *--__j)) 3706*e4b17023SJohn Marino {} 3707*e4b17023SJohn Marino std::iter_swap(__i, __j); 3708*e4b17023SJohn Marino std::reverse(__ii, __last); 3709*e4b17023SJohn Marino return true; 3710*e4b17023SJohn Marino } 3711*e4b17023SJohn Marino if (__i == __first) 3712*e4b17023SJohn Marino { 3713*e4b17023SJohn Marino std::reverse(__first, __last); 3714*e4b17023SJohn Marino return false; 3715*e4b17023SJohn Marino } 3716*e4b17023SJohn Marino } 3717*e4b17023SJohn Marino } 3718*e4b17023SJohn Marino 3719*e4b17023SJohn Marino /** 3720*e4b17023SJohn Marino * @brief Permute range into the next @e dictionary ordering using 3721*e4b17023SJohn Marino * comparison functor. 3722*e4b17023SJohn Marino * @ingroup sorting_algorithms 3723*e4b17023SJohn Marino * @param __first Start of range. 3724*e4b17023SJohn Marino * @param __last End of range. 3725*e4b17023SJohn Marino * @param __comp A comparison functor. 3726*e4b17023SJohn Marino * @return False if wrapped to first permutation, true otherwise. 3727*e4b17023SJohn Marino * 3728*e4b17023SJohn Marino * Treats all permutations of the range [__first,__last) as a set of 3729*e4b17023SJohn Marino * @e dictionary sorted sequences ordered by @p __comp. Permutes the current 3730*e4b17023SJohn Marino * sequence into the next one of this set. Returns true if there are more 3731*e4b17023SJohn Marino * sequences to generate. If the sequence is the largest of the set, the 3732*e4b17023SJohn Marino * smallest is generated and false returned. 3733*e4b17023SJohn Marino */ 3734*e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Compare> 3735*e4b17023SJohn Marino bool 3736*e4b17023SJohn Marino next_permutation(_BidirectionalIterator __first, 3737*e4b17023SJohn Marino _BidirectionalIterator __last, _Compare __comp) 3738*e4b17023SJohn Marino { 3739*e4b17023SJohn Marino // concept requirements 3740*e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept< 3741*e4b17023SJohn Marino _BidirectionalIterator>) 3742*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 3743*e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type, 3744*e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type>) 3745*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 3746*e4b17023SJohn Marino 3747*e4b17023SJohn Marino if (__first == __last) 3748*e4b17023SJohn Marino return false; 3749*e4b17023SJohn Marino _BidirectionalIterator __i = __first; 3750*e4b17023SJohn Marino ++__i; 3751*e4b17023SJohn Marino if (__i == __last) 3752*e4b17023SJohn Marino return false; 3753*e4b17023SJohn Marino __i = __last; 3754*e4b17023SJohn Marino --__i; 3755*e4b17023SJohn Marino 3756*e4b17023SJohn Marino for(;;) 3757*e4b17023SJohn Marino { 3758*e4b17023SJohn Marino _BidirectionalIterator __ii = __i; 3759*e4b17023SJohn Marino --__i; 3760*e4b17023SJohn Marino if (__comp(*__i, *__ii)) 3761*e4b17023SJohn Marino { 3762*e4b17023SJohn Marino _BidirectionalIterator __j = __last; 3763*e4b17023SJohn Marino while (!bool(__comp(*__i, *--__j))) 3764*e4b17023SJohn Marino {} 3765*e4b17023SJohn Marino std::iter_swap(__i, __j); 3766*e4b17023SJohn Marino std::reverse(__ii, __last); 3767*e4b17023SJohn Marino return true; 3768*e4b17023SJohn Marino } 3769*e4b17023SJohn Marino if (__i == __first) 3770*e4b17023SJohn Marino { 3771*e4b17023SJohn Marino std::reverse(__first, __last); 3772*e4b17023SJohn Marino return false; 3773*e4b17023SJohn Marino } 3774*e4b17023SJohn Marino } 3775*e4b17023SJohn Marino } 3776*e4b17023SJohn Marino 3777*e4b17023SJohn Marino /** 3778*e4b17023SJohn Marino * @brief Permute range into the previous @e dictionary ordering. 3779*e4b17023SJohn Marino * @ingroup sorting_algorithms 3780*e4b17023SJohn Marino * @param __first Start of range. 3781*e4b17023SJohn Marino * @param __last End of range. 3782*e4b17023SJohn Marino * @return False if wrapped to last permutation, true otherwise. 3783*e4b17023SJohn Marino * 3784*e4b17023SJohn Marino * Treats all permutations of the range as a set of @e dictionary sorted 3785*e4b17023SJohn Marino * sequences. Permutes the current sequence into the previous one of this 3786*e4b17023SJohn Marino * set. Returns true if there are more sequences to generate. If the 3787*e4b17023SJohn Marino * sequence is the smallest of the set, the largest is generated and false 3788*e4b17023SJohn Marino * returned. 3789*e4b17023SJohn Marino */ 3790*e4b17023SJohn Marino template<typename _BidirectionalIterator> 3791*e4b17023SJohn Marino bool 3792*e4b17023SJohn Marino prev_permutation(_BidirectionalIterator __first, 3793*e4b17023SJohn Marino _BidirectionalIterator __last) 3794*e4b17023SJohn Marino { 3795*e4b17023SJohn Marino // concept requirements 3796*e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept< 3797*e4b17023SJohn Marino _BidirectionalIterator>) 3798*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept< 3799*e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type>) 3800*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 3801*e4b17023SJohn Marino 3802*e4b17023SJohn Marino if (__first == __last) 3803*e4b17023SJohn Marino return false; 3804*e4b17023SJohn Marino _BidirectionalIterator __i = __first; 3805*e4b17023SJohn Marino ++__i; 3806*e4b17023SJohn Marino if (__i == __last) 3807*e4b17023SJohn Marino return false; 3808*e4b17023SJohn Marino __i = __last; 3809*e4b17023SJohn Marino --__i; 3810*e4b17023SJohn Marino 3811*e4b17023SJohn Marino for(;;) 3812*e4b17023SJohn Marino { 3813*e4b17023SJohn Marino _BidirectionalIterator __ii = __i; 3814*e4b17023SJohn Marino --__i; 3815*e4b17023SJohn Marino if (*__ii < *__i) 3816*e4b17023SJohn Marino { 3817*e4b17023SJohn Marino _BidirectionalIterator __j = __last; 3818*e4b17023SJohn Marino while (!(*--__j < *__i)) 3819*e4b17023SJohn Marino {} 3820*e4b17023SJohn Marino std::iter_swap(__i, __j); 3821*e4b17023SJohn Marino std::reverse(__ii, __last); 3822*e4b17023SJohn Marino return true; 3823*e4b17023SJohn Marino } 3824*e4b17023SJohn Marino if (__i == __first) 3825*e4b17023SJohn Marino { 3826*e4b17023SJohn Marino std::reverse(__first, __last); 3827*e4b17023SJohn Marino return false; 3828*e4b17023SJohn Marino } 3829*e4b17023SJohn Marino } 3830*e4b17023SJohn Marino } 3831*e4b17023SJohn Marino 3832*e4b17023SJohn Marino /** 3833*e4b17023SJohn Marino * @brief Permute range into the previous @e dictionary ordering using 3834*e4b17023SJohn Marino * comparison functor. 3835*e4b17023SJohn Marino * @ingroup sorting_algorithms 3836*e4b17023SJohn Marino * @param __first Start of range. 3837*e4b17023SJohn Marino * @param __last End of range. 3838*e4b17023SJohn Marino * @param __comp A comparison functor. 3839*e4b17023SJohn Marino * @return False if wrapped to last permutation, true otherwise. 3840*e4b17023SJohn Marino * 3841*e4b17023SJohn Marino * Treats all permutations of the range [__first,__last) as a set of 3842*e4b17023SJohn Marino * @e dictionary sorted sequences ordered by @p __comp. Permutes the current 3843*e4b17023SJohn Marino * sequence into the previous one of this set. Returns true if there are 3844*e4b17023SJohn Marino * more sequences to generate. If the sequence is the smallest of the set, 3845*e4b17023SJohn Marino * the largest is generated and false returned. 3846*e4b17023SJohn Marino */ 3847*e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Compare> 3848*e4b17023SJohn Marino bool 3849*e4b17023SJohn Marino prev_permutation(_BidirectionalIterator __first, 3850*e4b17023SJohn Marino _BidirectionalIterator __last, _Compare __comp) 3851*e4b17023SJohn Marino { 3852*e4b17023SJohn Marino // concept requirements 3853*e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept< 3854*e4b17023SJohn Marino _BidirectionalIterator>) 3855*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 3856*e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type, 3857*e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type>) 3858*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 3859*e4b17023SJohn Marino 3860*e4b17023SJohn Marino if (__first == __last) 3861*e4b17023SJohn Marino return false; 3862*e4b17023SJohn Marino _BidirectionalIterator __i = __first; 3863*e4b17023SJohn Marino ++__i; 3864*e4b17023SJohn Marino if (__i == __last) 3865*e4b17023SJohn Marino return false; 3866*e4b17023SJohn Marino __i = __last; 3867*e4b17023SJohn Marino --__i; 3868*e4b17023SJohn Marino 3869*e4b17023SJohn Marino for(;;) 3870*e4b17023SJohn Marino { 3871*e4b17023SJohn Marino _BidirectionalIterator __ii = __i; 3872*e4b17023SJohn Marino --__i; 3873*e4b17023SJohn Marino if (__comp(*__ii, *__i)) 3874*e4b17023SJohn Marino { 3875*e4b17023SJohn Marino _BidirectionalIterator __j = __last; 3876*e4b17023SJohn Marino while (!bool(__comp(*--__j, *__i))) 3877*e4b17023SJohn Marino {} 3878*e4b17023SJohn Marino std::iter_swap(__i, __j); 3879*e4b17023SJohn Marino std::reverse(__ii, __last); 3880*e4b17023SJohn Marino return true; 3881*e4b17023SJohn Marino } 3882*e4b17023SJohn Marino if (__i == __first) 3883*e4b17023SJohn Marino { 3884*e4b17023SJohn Marino std::reverse(__first, __last); 3885*e4b17023SJohn Marino return false; 3886*e4b17023SJohn Marino } 3887*e4b17023SJohn Marino } 3888*e4b17023SJohn Marino } 3889*e4b17023SJohn Marino 3890*e4b17023SJohn Marino // replace 3891*e4b17023SJohn Marino // replace_if 3892*e4b17023SJohn Marino 3893*e4b17023SJohn Marino /** 3894*e4b17023SJohn Marino * @brief Copy a sequence, replacing each element of one value with another 3895*e4b17023SJohn Marino * value. 3896*e4b17023SJohn Marino * @param __first An input iterator. 3897*e4b17023SJohn Marino * @param __last An input iterator. 3898*e4b17023SJohn Marino * @param __result An output iterator. 3899*e4b17023SJohn Marino * @param __old_value The value to be replaced. 3900*e4b17023SJohn Marino * @param __new_value The replacement value. 3901*e4b17023SJohn Marino * @return The end of the output sequence, @p result+(last-first). 3902*e4b17023SJohn Marino * 3903*e4b17023SJohn Marino * Copies each element in the input range @p [__first,__last) to the 3904*e4b17023SJohn Marino * output range @p [__result,__result+(__last-__first)) replacing elements 3905*e4b17023SJohn Marino * equal to @p __old_value with @p __new_value. 3906*e4b17023SJohn Marino */ 3907*e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator, typename _Tp> 3908*e4b17023SJohn Marino _OutputIterator 3909*e4b17023SJohn Marino replace_copy(_InputIterator __first, _InputIterator __last, 3910*e4b17023SJohn Marino _OutputIterator __result, 3911*e4b17023SJohn Marino const _Tp& __old_value, const _Tp& __new_value) 3912*e4b17023SJohn Marino { 3913*e4b17023SJohn Marino // concept requirements 3914*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 3915*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 3916*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 3917*e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept< 3918*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type, _Tp>) 3919*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 3920*e4b17023SJohn Marino 3921*e4b17023SJohn Marino for (; __first != __last; ++__first, ++__result) 3922*e4b17023SJohn Marino if (*__first == __old_value) 3923*e4b17023SJohn Marino *__result = __new_value; 3924*e4b17023SJohn Marino else 3925*e4b17023SJohn Marino *__result = *__first; 3926*e4b17023SJohn Marino return __result; 3927*e4b17023SJohn Marino } 3928*e4b17023SJohn Marino 3929*e4b17023SJohn Marino /** 3930*e4b17023SJohn Marino * @brief Copy a sequence, replacing each value for which a predicate 3931*e4b17023SJohn Marino * returns true with another value. 3932*e4b17023SJohn Marino * @ingroup mutating_algorithms 3933*e4b17023SJohn Marino * @param __first An input iterator. 3934*e4b17023SJohn Marino * @param __last An input iterator. 3935*e4b17023SJohn Marino * @param __result An output iterator. 3936*e4b17023SJohn Marino * @param __pred A predicate. 3937*e4b17023SJohn Marino * @param __new_value The replacement value. 3938*e4b17023SJohn Marino * @return The end of the output sequence, @p __result+(__last-__first). 3939*e4b17023SJohn Marino * 3940*e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) to the range 3941*e4b17023SJohn Marino * @p [__result,__result+(__last-__first)) replacing elements for which 3942*e4b17023SJohn Marino * @p __pred returns true with @p __new_value. 3943*e4b17023SJohn Marino */ 3944*e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator, 3945*e4b17023SJohn Marino typename _Predicate, typename _Tp> 3946*e4b17023SJohn Marino _OutputIterator 3947*e4b17023SJohn Marino replace_copy_if(_InputIterator __first, _InputIterator __last, 3948*e4b17023SJohn Marino _OutputIterator __result, 3949*e4b17023SJohn Marino _Predicate __pred, const _Tp& __new_value) 3950*e4b17023SJohn Marino { 3951*e4b17023SJohn Marino // concept requirements 3952*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 3953*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 3954*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 3955*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 3956*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 3957*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 3958*e4b17023SJohn Marino 3959*e4b17023SJohn Marino for (; __first != __last; ++__first, ++__result) 3960*e4b17023SJohn Marino if (__pred(*__first)) 3961*e4b17023SJohn Marino *__result = __new_value; 3962*e4b17023SJohn Marino else 3963*e4b17023SJohn Marino *__result = *__first; 3964*e4b17023SJohn Marino return __result; 3965*e4b17023SJohn Marino } 3966*e4b17023SJohn Marino 3967*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 3968*e4b17023SJohn Marino /** 3969*e4b17023SJohn Marino * @brief Determines whether the elements of a sequence are sorted. 3970*e4b17023SJohn Marino * @ingroup sorting_algorithms 3971*e4b17023SJohn Marino * @param __first An iterator. 3972*e4b17023SJohn Marino * @param __last Another iterator. 3973*e4b17023SJohn Marino * @return True if the elements are sorted, false otherwise. 3974*e4b17023SJohn Marino */ 3975*e4b17023SJohn Marino template<typename _ForwardIterator> 3976*e4b17023SJohn Marino inline bool 3977*e4b17023SJohn Marino is_sorted(_ForwardIterator __first, _ForwardIterator __last) 3978*e4b17023SJohn Marino { return std::is_sorted_until(__first, __last) == __last; } 3979*e4b17023SJohn Marino 3980*e4b17023SJohn Marino /** 3981*e4b17023SJohn Marino * @brief Determines whether the elements of a sequence are sorted 3982*e4b17023SJohn Marino * according to a comparison functor. 3983*e4b17023SJohn Marino * @ingroup sorting_algorithms 3984*e4b17023SJohn Marino * @param __first An iterator. 3985*e4b17023SJohn Marino * @param __last Another iterator. 3986*e4b17023SJohn Marino * @param __comp A comparison functor. 3987*e4b17023SJohn Marino * @return True if the elements are sorted, false otherwise. 3988*e4b17023SJohn Marino */ 3989*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Compare> 3990*e4b17023SJohn Marino inline bool 3991*e4b17023SJohn Marino is_sorted(_ForwardIterator __first, _ForwardIterator __last, 3992*e4b17023SJohn Marino _Compare __comp) 3993*e4b17023SJohn Marino { return std::is_sorted_until(__first, __last, __comp) == __last; } 3994*e4b17023SJohn Marino 3995*e4b17023SJohn Marino /** 3996*e4b17023SJohn Marino * @brief Determines the end of a sorted sequence. 3997*e4b17023SJohn Marino * @ingroup sorting_algorithms 3998*e4b17023SJohn Marino * @param __first An iterator. 3999*e4b17023SJohn Marino * @param __last Another iterator. 4000*e4b17023SJohn Marino * @return An iterator pointing to the last iterator i in [__first, __last) 4001*e4b17023SJohn Marino * for which the range [__first, i) is sorted. 4002*e4b17023SJohn Marino */ 4003*e4b17023SJohn Marino template<typename _ForwardIterator> 4004*e4b17023SJohn Marino _ForwardIterator 4005*e4b17023SJohn Marino is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) 4006*e4b17023SJohn Marino { 4007*e4b17023SJohn Marino // concept requirements 4008*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4009*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept< 4010*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 4011*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4012*e4b17023SJohn Marino 4013*e4b17023SJohn Marino if (__first == __last) 4014*e4b17023SJohn Marino return __last; 4015*e4b17023SJohn Marino 4016*e4b17023SJohn Marino _ForwardIterator __next = __first; 4017*e4b17023SJohn Marino for (++__next; __next != __last; __first = __next, ++__next) 4018*e4b17023SJohn Marino if (*__next < *__first) 4019*e4b17023SJohn Marino return __next; 4020*e4b17023SJohn Marino return __next; 4021*e4b17023SJohn Marino } 4022*e4b17023SJohn Marino 4023*e4b17023SJohn Marino /** 4024*e4b17023SJohn Marino * @brief Determines the end of a sorted sequence using comparison functor. 4025*e4b17023SJohn Marino * @ingroup sorting_algorithms 4026*e4b17023SJohn Marino * @param __first An iterator. 4027*e4b17023SJohn Marino * @param __last Another iterator. 4028*e4b17023SJohn Marino * @param __comp A comparison functor. 4029*e4b17023SJohn Marino * @return An iterator pointing to the last iterator i in [__first, __last) 4030*e4b17023SJohn Marino * for which the range [__first, i) is sorted. 4031*e4b17023SJohn Marino */ 4032*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Compare> 4033*e4b17023SJohn Marino _ForwardIterator 4034*e4b17023SJohn Marino is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, 4035*e4b17023SJohn Marino _Compare __comp) 4036*e4b17023SJohn Marino { 4037*e4b17023SJohn Marino // concept requirements 4038*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4039*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 4040*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, 4041*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 4042*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4043*e4b17023SJohn Marino 4044*e4b17023SJohn Marino if (__first == __last) 4045*e4b17023SJohn Marino return __last; 4046*e4b17023SJohn Marino 4047*e4b17023SJohn Marino _ForwardIterator __next = __first; 4048*e4b17023SJohn Marino for (++__next; __next != __last; __first = __next, ++__next) 4049*e4b17023SJohn Marino if (__comp(*__next, *__first)) 4050*e4b17023SJohn Marino return __next; 4051*e4b17023SJohn Marino return __next; 4052*e4b17023SJohn Marino } 4053*e4b17023SJohn Marino 4054*e4b17023SJohn Marino /** 4055*e4b17023SJohn Marino * @brief Determines min and max at once as an ordered pair. 4056*e4b17023SJohn Marino * @ingroup sorting_algorithms 4057*e4b17023SJohn Marino * @param __a A thing of arbitrary type. 4058*e4b17023SJohn Marino * @param __b Another thing of arbitrary type. 4059*e4b17023SJohn Marino * @return A pair(__b, __a) if __b is smaller than __a, pair(__a, 4060*e4b17023SJohn Marino * __b) otherwise. 4061*e4b17023SJohn Marino */ 4062*e4b17023SJohn Marino template<typename _Tp> 4063*e4b17023SJohn Marino inline pair<const _Tp&, const _Tp&> 4064*e4b17023SJohn Marino minmax(const _Tp& __a, const _Tp& __b) 4065*e4b17023SJohn Marino { 4066*e4b17023SJohn Marino // concept requirements 4067*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) 4068*e4b17023SJohn Marino 4069*e4b17023SJohn Marino return __b < __a ? pair<const _Tp&, const _Tp&>(__b, __a) 4070*e4b17023SJohn Marino : pair<const _Tp&, const _Tp&>(__a, __b); 4071*e4b17023SJohn Marino } 4072*e4b17023SJohn Marino 4073*e4b17023SJohn Marino /** 4074*e4b17023SJohn Marino * @brief Determines min and max at once as an ordered pair. 4075*e4b17023SJohn Marino * @ingroup sorting_algorithms 4076*e4b17023SJohn Marino * @param __a A thing of arbitrary type. 4077*e4b17023SJohn Marino * @param __b Another thing of arbitrary type. 4078*e4b17023SJohn Marino * @param __comp A @link comparison_functors comparison functor @endlink. 4079*e4b17023SJohn Marino * @return A pair(__b, __a) if __b is smaller than __a, pair(__a, 4080*e4b17023SJohn Marino * __b) otherwise. 4081*e4b17023SJohn Marino */ 4082*e4b17023SJohn Marino template<typename _Tp, typename _Compare> 4083*e4b17023SJohn Marino inline pair<const _Tp&, const _Tp&> 4084*e4b17023SJohn Marino minmax(const _Tp& __a, const _Tp& __b, _Compare __comp) 4085*e4b17023SJohn Marino { 4086*e4b17023SJohn Marino return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) 4087*e4b17023SJohn Marino : pair<const _Tp&, const _Tp&>(__a, __b); 4088*e4b17023SJohn Marino } 4089*e4b17023SJohn Marino 4090*e4b17023SJohn Marino /** 4091*e4b17023SJohn Marino * @brief Return a pair of iterators pointing to the minimum and maximum 4092*e4b17023SJohn Marino * elements in a range. 4093*e4b17023SJohn Marino * @ingroup sorting_algorithms 4094*e4b17023SJohn Marino * @param __first Start of range. 4095*e4b17023SJohn Marino * @param __last End of range. 4096*e4b17023SJohn Marino * @return make_pair(m, M), where m is the first iterator i in 4097*e4b17023SJohn Marino * [__first, __last) such that no other element in the range is 4098*e4b17023SJohn Marino * smaller, and where M is the last iterator i in [__first, __last) 4099*e4b17023SJohn Marino * such that no other element in the range is larger. 4100*e4b17023SJohn Marino */ 4101*e4b17023SJohn Marino template<typename _ForwardIterator> 4102*e4b17023SJohn Marino pair<_ForwardIterator, _ForwardIterator> 4103*e4b17023SJohn Marino minmax_element(_ForwardIterator __first, _ForwardIterator __last) 4104*e4b17023SJohn Marino { 4105*e4b17023SJohn Marino // concept requirements 4106*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4107*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept< 4108*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 4109*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4110*e4b17023SJohn Marino 4111*e4b17023SJohn Marino _ForwardIterator __next = __first; 4112*e4b17023SJohn Marino if (__first == __last 4113*e4b17023SJohn Marino || ++__next == __last) 4114*e4b17023SJohn Marino return std::make_pair(__first, __first); 4115*e4b17023SJohn Marino 4116*e4b17023SJohn Marino _ForwardIterator __min, __max; 4117*e4b17023SJohn Marino if (*__next < *__first) 4118*e4b17023SJohn Marino { 4119*e4b17023SJohn Marino __min = __next; 4120*e4b17023SJohn Marino __max = __first; 4121*e4b17023SJohn Marino } 4122*e4b17023SJohn Marino else 4123*e4b17023SJohn Marino { 4124*e4b17023SJohn Marino __min = __first; 4125*e4b17023SJohn Marino __max = __next; 4126*e4b17023SJohn Marino } 4127*e4b17023SJohn Marino 4128*e4b17023SJohn Marino __first = __next; 4129*e4b17023SJohn Marino ++__first; 4130*e4b17023SJohn Marino 4131*e4b17023SJohn Marino while (__first != __last) 4132*e4b17023SJohn Marino { 4133*e4b17023SJohn Marino __next = __first; 4134*e4b17023SJohn Marino if (++__next == __last) 4135*e4b17023SJohn Marino { 4136*e4b17023SJohn Marino if (*__first < *__min) 4137*e4b17023SJohn Marino __min = __first; 4138*e4b17023SJohn Marino else if (!(*__first < *__max)) 4139*e4b17023SJohn Marino __max = __first; 4140*e4b17023SJohn Marino break; 4141*e4b17023SJohn Marino } 4142*e4b17023SJohn Marino 4143*e4b17023SJohn Marino if (*__next < *__first) 4144*e4b17023SJohn Marino { 4145*e4b17023SJohn Marino if (*__next < *__min) 4146*e4b17023SJohn Marino __min = __next; 4147*e4b17023SJohn Marino if (!(*__first < *__max)) 4148*e4b17023SJohn Marino __max = __first; 4149*e4b17023SJohn Marino } 4150*e4b17023SJohn Marino else 4151*e4b17023SJohn Marino { 4152*e4b17023SJohn Marino if (*__first < *__min) 4153*e4b17023SJohn Marino __min = __first; 4154*e4b17023SJohn Marino if (!(*__next < *__max)) 4155*e4b17023SJohn Marino __max = __next; 4156*e4b17023SJohn Marino } 4157*e4b17023SJohn Marino 4158*e4b17023SJohn Marino __first = __next; 4159*e4b17023SJohn Marino ++__first; 4160*e4b17023SJohn Marino } 4161*e4b17023SJohn Marino 4162*e4b17023SJohn Marino return std::make_pair(__min, __max); 4163*e4b17023SJohn Marino } 4164*e4b17023SJohn Marino 4165*e4b17023SJohn Marino /** 4166*e4b17023SJohn Marino * @brief Return a pair of iterators pointing to the minimum and maximum 4167*e4b17023SJohn Marino * elements in a range. 4168*e4b17023SJohn Marino * @ingroup sorting_algorithms 4169*e4b17023SJohn Marino * @param __first Start of range. 4170*e4b17023SJohn Marino * @param __last End of range. 4171*e4b17023SJohn Marino * @param __comp Comparison functor. 4172*e4b17023SJohn Marino * @return make_pair(m, M), where m is the first iterator i in 4173*e4b17023SJohn Marino * [__first, __last) such that no other element in the range is 4174*e4b17023SJohn Marino * smaller, and where M is the last iterator i in [__first, __last) 4175*e4b17023SJohn Marino * such that no other element in the range is larger. 4176*e4b17023SJohn Marino */ 4177*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Compare> 4178*e4b17023SJohn Marino pair<_ForwardIterator, _ForwardIterator> 4179*e4b17023SJohn Marino minmax_element(_ForwardIterator __first, _ForwardIterator __last, 4180*e4b17023SJohn Marino _Compare __comp) 4181*e4b17023SJohn Marino { 4182*e4b17023SJohn Marino // concept requirements 4183*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4184*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 4185*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, 4186*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 4187*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4188*e4b17023SJohn Marino 4189*e4b17023SJohn Marino _ForwardIterator __next = __first; 4190*e4b17023SJohn Marino if (__first == __last 4191*e4b17023SJohn Marino || ++__next == __last) 4192*e4b17023SJohn Marino return std::make_pair(__first, __first); 4193*e4b17023SJohn Marino 4194*e4b17023SJohn Marino _ForwardIterator __min, __max; 4195*e4b17023SJohn Marino if (__comp(*__next, *__first)) 4196*e4b17023SJohn Marino { 4197*e4b17023SJohn Marino __min = __next; 4198*e4b17023SJohn Marino __max = __first; 4199*e4b17023SJohn Marino } 4200*e4b17023SJohn Marino else 4201*e4b17023SJohn Marino { 4202*e4b17023SJohn Marino __min = __first; 4203*e4b17023SJohn Marino __max = __next; 4204*e4b17023SJohn Marino } 4205*e4b17023SJohn Marino 4206*e4b17023SJohn Marino __first = __next; 4207*e4b17023SJohn Marino ++__first; 4208*e4b17023SJohn Marino 4209*e4b17023SJohn Marino while (__first != __last) 4210*e4b17023SJohn Marino { 4211*e4b17023SJohn Marino __next = __first; 4212*e4b17023SJohn Marino if (++__next == __last) 4213*e4b17023SJohn Marino { 4214*e4b17023SJohn Marino if (__comp(*__first, *__min)) 4215*e4b17023SJohn Marino __min = __first; 4216*e4b17023SJohn Marino else if (!__comp(*__first, *__max)) 4217*e4b17023SJohn Marino __max = __first; 4218*e4b17023SJohn Marino break; 4219*e4b17023SJohn Marino } 4220*e4b17023SJohn Marino 4221*e4b17023SJohn Marino if (__comp(*__next, *__first)) 4222*e4b17023SJohn Marino { 4223*e4b17023SJohn Marino if (__comp(*__next, *__min)) 4224*e4b17023SJohn Marino __min = __next; 4225*e4b17023SJohn Marino if (!__comp(*__first, *__max)) 4226*e4b17023SJohn Marino __max = __first; 4227*e4b17023SJohn Marino } 4228*e4b17023SJohn Marino else 4229*e4b17023SJohn Marino { 4230*e4b17023SJohn Marino if (__comp(*__first, *__min)) 4231*e4b17023SJohn Marino __min = __first; 4232*e4b17023SJohn Marino if (!__comp(*__next, *__max)) 4233*e4b17023SJohn Marino __max = __next; 4234*e4b17023SJohn Marino } 4235*e4b17023SJohn Marino 4236*e4b17023SJohn Marino __first = __next; 4237*e4b17023SJohn Marino ++__first; 4238*e4b17023SJohn Marino } 4239*e4b17023SJohn Marino 4240*e4b17023SJohn Marino return std::make_pair(__min, __max); 4241*e4b17023SJohn Marino } 4242*e4b17023SJohn Marino 4243*e4b17023SJohn Marino // N2722 + DR 915. 4244*e4b17023SJohn Marino template<typename _Tp> 4245*e4b17023SJohn Marino inline _Tp 4246*e4b17023SJohn Marino min(initializer_list<_Tp> __l) 4247*e4b17023SJohn Marino { return *std::min_element(__l.begin(), __l.end()); } 4248*e4b17023SJohn Marino 4249*e4b17023SJohn Marino template<typename _Tp, typename _Compare> 4250*e4b17023SJohn Marino inline _Tp 4251*e4b17023SJohn Marino min(initializer_list<_Tp> __l, _Compare __comp) 4252*e4b17023SJohn Marino { return *std::min_element(__l.begin(), __l.end(), __comp); } 4253*e4b17023SJohn Marino 4254*e4b17023SJohn Marino template<typename _Tp> 4255*e4b17023SJohn Marino inline _Tp 4256*e4b17023SJohn Marino max(initializer_list<_Tp> __l) 4257*e4b17023SJohn Marino { return *std::max_element(__l.begin(), __l.end()); } 4258*e4b17023SJohn Marino 4259*e4b17023SJohn Marino template<typename _Tp, typename _Compare> 4260*e4b17023SJohn Marino inline _Tp 4261*e4b17023SJohn Marino max(initializer_list<_Tp> __l, _Compare __comp) 4262*e4b17023SJohn Marino { return *std::max_element(__l.begin(), __l.end(), __comp); } 4263*e4b17023SJohn Marino 4264*e4b17023SJohn Marino template<typename _Tp> 4265*e4b17023SJohn Marino inline pair<_Tp, _Tp> 4266*e4b17023SJohn Marino minmax(initializer_list<_Tp> __l) 4267*e4b17023SJohn Marino { 4268*e4b17023SJohn Marino pair<const _Tp*, const _Tp*> __p = 4269*e4b17023SJohn Marino std::minmax_element(__l.begin(), __l.end()); 4270*e4b17023SJohn Marino return std::make_pair(*__p.first, *__p.second); 4271*e4b17023SJohn Marino } 4272*e4b17023SJohn Marino 4273*e4b17023SJohn Marino template<typename _Tp, typename _Compare> 4274*e4b17023SJohn Marino inline pair<_Tp, _Tp> 4275*e4b17023SJohn Marino minmax(initializer_list<_Tp> __l, _Compare __comp) 4276*e4b17023SJohn Marino { 4277*e4b17023SJohn Marino pair<const _Tp*, const _Tp*> __p = 4278*e4b17023SJohn Marino std::minmax_element(__l.begin(), __l.end(), __comp); 4279*e4b17023SJohn Marino return std::make_pair(*__p.first, *__p.second); 4280*e4b17023SJohn Marino } 4281*e4b17023SJohn Marino 4282*e4b17023SJohn Marino /** 4283*e4b17023SJohn Marino * @brief Checks whether a permutaion of the second sequence is equal 4284*e4b17023SJohn Marino * to the first sequence. 4285*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4286*e4b17023SJohn Marino * @param __first1 Start of first range. 4287*e4b17023SJohn Marino * @param __last1 End of first range. 4288*e4b17023SJohn Marino * @param __first2 Start of second range. 4289*e4b17023SJohn Marino * @return true if there exists a permutation of the elements in the range 4290*e4b17023SJohn Marino * [__first2, __first2 + (__last1 - __first1)), beginning with 4291*e4b17023SJohn Marino * ForwardIterator2 begin, such that equal(__first1, __last1, begin) 4292*e4b17023SJohn Marino * returns true; otherwise, returns false. 4293*e4b17023SJohn Marino */ 4294*e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2> 4295*e4b17023SJohn Marino bool 4296*e4b17023SJohn Marino is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 4297*e4b17023SJohn Marino _ForwardIterator2 __first2) 4298*e4b17023SJohn Marino { 4299*e4b17023SJohn Marino // Efficiently compare identical prefixes: O(N) if sequences 4300*e4b17023SJohn Marino // have the same elements in the same order. 4301*e4b17023SJohn Marino for (; __first1 != __last1; ++__first1, ++__first2) 4302*e4b17023SJohn Marino if (!(*__first1 == *__first2)) 4303*e4b17023SJohn Marino break; 4304*e4b17023SJohn Marino 4305*e4b17023SJohn Marino if (__first1 == __last1) 4306*e4b17023SJohn Marino return true; 4307*e4b17023SJohn Marino 4308*e4b17023SJohn Marino // Establish __last2 assuming equal ranges by iterating over the 4309*e4b17023SJohn Marino // rest of the list. 4310*e4b17023SJohn Marino _ForwardIterator2 __last2 = __first2; 4311*e4b17023SJohn Marino std::advance(__last2, std::distance(__first1, __last1)); 4312*e4b17023SJohn Marino for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan) 4313*e4b17023SJohn Marino { 4314*e4b17023SJohn Marino if (__scan != _GLIBCXX_STD_A::find(__first1, __scan, *__scan)) 4315*e4b17023SJohn Marino continue; // We've seen this one before. 4316*e4b17023SJohn Marino 4317*e4b17023SJohn Marino auto __matches = std::count(__first2, __last2, *__scan); 4318*e4b17023SJohn Marino if (0 == __matches 4319*e4b17023SJohn Marino || std::count(__scan, __last1, *__scan) != __matches) 4320*e4b17023SJohn Marino return false; 4321*e4b17023SJohn Marino } 4322*e4b17023SJohn Marino return true; 4323*e4b17023SJohn Marino } 4324*e4b17023SJohn Marino 4325*e4b17023SJohn Marino /** 4326*e4b17023SJohn Marino * @brief Checks whether a permutation of the second sequence is equal 4327*e4b17023SJohn Marino * to the first sequence. 4328*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4329*e4b17023SJohn Marino * @param __first1 Start of first range. 4330*e4b17023SJohn Marino * @param __last1 End of first range. 4331*e4b17023SJohn Marino * @param __first2 Start of second range. 4332*e4b17023SJohn Marino * @param __pred A binary predicate. 4333*e4b17023SJohn Marino * @return true if there exists a permutation of the elements in 4334*e4b17023SJohn Marino * the range [__first2, __first2 + (__last1 - __first1)), 4335*e4b17023SJohn Marino * beginning with ForwardIterator2 begin, such that 4336*e4b17023SJohn Marino * equal(__first1, __last1, __begin, __pred) returns true; 4337*e4b17023SJohn Marino * otherwise, returns false. 4338*e4b17023SJohn Marino */ 4339*e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2, 4340*e4b17023SJohn Marino typename _BinaryPredicate> 4341*e4b17023SJohn Marino bool 4342*e4b17023SJohn Marino is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 4343*e4b17023SJohn Marino _ForwardIterator2 __first2, _BinaryPredicate __pred) 4344*e4b17023SJohn Marino { 4345*e4b17023SJohn Marino // Efficiently compare identical prefixes: O(N) if sequences 4346*e4b17023SJohn Marino // have the same elements in the same order. 4347*e4b17023SJohn Marino for (; __first1 != __last1; ++__first1, ++__first2) 4348*e4b17023SJohn Marino if (!bool(__pred(*__first1, *__first2))) 4349*e4b17023SJohn Marino break; 4350*e4b17023SJohn Marino 4351*e4b17023SJohn Marino if (__first1 == __last1) 4352*e4b17023SJohn Marino return true; 4353*e4b17023SJohn Marino 4354*e4b17023SJohn Marino // Establish __last2 assuming equal ranges by iterating over the 4355*e4b17023SJohn Marino // rest of the list. 4356*e4b17023SJohn Marino _ForwardIterator2 __last2 = __first2; 4357*e4b17023SJohn Marino std::advance(__last2, std::distance(__first1, __last1)); 4358*e4b17023SJohn Marino for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan) 4359*e4b17023SJohn Marino { 4360*e4b17023SJohn Marino using std::placeholders::_1; 4361*e4b17023SJohn Marino 4362*e4b17023SJohn Marino if (__scan != _GLIBCXX_STD_A::find_if(__first1, __scan, 4363*e4b17023SJohn Marino std::bind(__pred, _1, *__scan))) 4364*e4b17023SJohn Marino continue; // We've seen this one before. 4365*e4b17023SJohn Marino 4366*e4b17023SJohn Marino auto __matches = std::count_if(__first2, __last2, 4367*e4b17023SJohn Marino std::bind(__pred, _1, *__scan)); 4368*e4b17023SJohn Marino if (0 == __matches 4369*e4b17023SJohn Marino || std::count_if(__scan, __last1, 4370*e4b17023SJohn Marino std::bind(__pred, _1, *__scan)) != __matches) 4371*e4b17023SJohn Marino return false; 4372*e4b17023SJohn Marino } 4373*e4b17023SJohn Marino return true; 4374*e4b17023SJohn Marino } 4375*e4b17023SJohn Marino 4376*e4b17023SJohn Marino #ifdef _GLIBCXX_USE_C99_STDINT_TR1 4377*e4b17023SJohn Marino /** 4378*e4b17023SJohn Marino * @brief Shuffle the elements of a sequence using a uniform random 4379*e4b17023SJohn Marino * number generator. 4380*e4b17023SJohn Marino * @ingroup mutating_algorithms 4381*e4b17023SJohn Marino * @param __first A forward iterator. 4382*e4b17023SJohn Marino * @param __last A forward iterator. 4383*e4b17023SJohn Marino * @param __g A UniformRandomNumberGenerator (26.5.1.3). 4384*e4b17023SJohn Marino * @return Nothing. 4385*e4b17023SJohn Marino * 4386*e4b17023SJohn Marino * Reorders the elements in the range @p [__first,__last) using @p __g to 4387*e4b17023SJohn Marino * provide random numbers. 4388*e4b17023SJohn Marino */ 4389*e4b17023SJohn Marino template<typename _RandomAccessIterator, 4390*e4b17023SJohn Marino typename _UniformRandomNumberGenerator> 4391*e4b17023SJohn Marino void 4392*e4b17023SJohn Marino shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, 4393*e4b17023SJohn Marino _UniformRandomNumberGenerator&& __g) 4394*e4b17023SJohn Marino { 4395*e4b17023SJohn Marino // concept requirements 4396*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 4397*e4b17023SJohn Marino _RandomAccessIterator>) 4398*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4399*e4b17023SJohn Marino 4400*e4b17023SJohn Marino if (__first == __last) 4401*e4b17023SJohn Marino return; 4402*e4b17023SJohn Marino 4403*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type 4404*e4b17023SJohn Marino _DistanceType; 4405*e4b17023SJohn Marino 4406*e4b17023SJohn Marino typedef typename std::make_unsigned<_DistanceType>::type __ud_type; 4407*e4b17023SJohn Marino typedef typename std::uniform_int_distribution<__ud_type> __distr_type; 4408*e4b17023SJohn Marino typedef typename __distr_type::param_type __p_type; 4409*e4b17023SJohn Marino __distr_type __d; 4410*e4b17023SJohn Marino 4411*e4b17023SJohn Marino for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) 4412*e4b17023SJohn Marino std::iter_swap(__i, __first + __d(__g, __p_type(0, __i - __first))); 4413*e4b17023SJohn Marino } 4414*e4b17023SJohn Marino #endif 4415*e4b17023SJohn Marino 4416*e4b17023SJohn Marino #endif // __GXX_EXPERIMENTAL_CXX0X__ 4417*e4b17023SJohn Marino 4418*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION 4419*e4b17023SJohn Marino 4420*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_ALGO 4421*e4b17023SJohn Marino 4422*e4b17023SJohn Marino /** 4423*e4b17023SJohn Marino * @brief Apply a function to every element of a sequence. 4424*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4425*e4b17023SJohn Marino * @param __first An input iterator. 4426*e4b17023SJohn Marino * @param __last An input iterator. 4427*e4b17023SJohn Marino * @param __f A unary function object. 4428*e4b17023SJohn Marino * @return @p __f (std::move(@p __f) in C++0x). 4429*e4b17023SJohn Marino * 4430*e4b17023SJohn Marino * Applies the function object @p __f to each element in the range 4431*e4b17023SJohn Marino * @p [first,last). @p __f must not modify the order of the sequence. 4432*e4b17023SJohn Marino * If @p __f has a return value it is ignored. 4433*e4b17023SJohn Marino */ 4434*e4b17023SJohn Marino template<typename _InputIterator, typename _Function> 4435*e4b17023SJohn Marino _Function 4436*e4b17023SJohn Marino for_each(_InputIterator __first, _InputIterator __last, _Function __f) 4437*e4b17023SJohn Marino { 4438*e4b17023SJohn Marino // concept requirements 4439*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4440*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4441*e4b17023SJohn Marino for (; __first != __last; ++__first) 4442*e4b17023SJohn Marino __f(*__first); 4443*e4b17023SJohn Marino return _GLIBCXX_MOVE(__f); 4444*e4b17023SJohn Marino } 4445*e4b17023SJohn Marino 4446*e4b17023SJohn Marino /** 4447*e4b17023SJohn Marino * @brief Find the first occurrence of a value in a sequence. 4448*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4449*e4b17023SJohn Marino * @param __first An input iterator. 4450*e4b17023SJohn Marino * @param __last An input iterator. 4451*e4b17023SJohn Marino * @param __val The value to find. 4452*e4b17023SJohn Marino * @return The first iterator @c i in the range @p [__first,__last) 4453*e4b17023SJohn Marino * such that @c *i == @p __val, or @p __last if no such iterator exists. 4454*e4b17023SJohn Marino */ 4455*e4b17023SJohn Marino template<typename _InputIterator, typename _Tp> 4456*e4b17023SJohn Marino inline _InputIterator 4457*e4b17023SJohn Marino find(_InputIterator __first, _InputIterator __last, 4458*e4b17023SJohn Marino const _Tp& __val) 4459*e4b17023SJohn Marino { 4460*e4b17023SJohn Marino // concept requirements 4461*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4462*e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept< 4463*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type, _Tp>) 4464*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4465*e4b17023SJohn Marino return std::__find(__first, __last, __val, 4466*e4b17023SJohn Marino std::__iterator_category(__first)); 4467*e4b17023SJohn Marino } 4468*e4b17023SJohn Marino 4469*e4b17023SJohn Marino /** 4470*e4b17023SJohn Marino * @brief Find the first element in a sequence for which a 4471*e4b17023SJohn Marino * predicate is true. 4472*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4473*e4b17023SJohn Marino * @param __first An input iterator. 4474*e4b17023SJohn Marino * @param __last An input iterator. 4475*e4b17023SJohn Marino * @param __pred A predicate. 4476*e4b17023SJohn Marino * @return The first iterator @c i in the range @p [__first,__last) 4477*e4b17023SJohn Marino * such that @p __pred(*i) is true, or @p __last if no such iterator exists. 4478*e4b17023SJohn Marino */ 4479*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 4480*e4b17023SJohn Marino inline _InputIterator 4481*e4b17023SJohn Marino find_if(_InputIterator __first, _InputIterator __last, 4482*e4b17023SJohn Marino _Predicate __pred) 4483*e4b17023SJohn Marino { 4484*e4b17023SJohn Marino // concept requirements 4485*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4486*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 4487*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 4488*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4489*e4b17023SJohn Marino return std::__find_if(__first, __last, __pred, 4490*e4b17023SJohn Marino std::__iterator_category(__first)); 4491*e4b17023SJohn Marino } 4492*e4b17023SJohn Marino 4493*e4b17023SJohn Marino /** 4494*e4b17023SJohn Marino * @brief Find element from a set in a sequence. 4495*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4496*e4b17023SJohn Marino * @param __first1 Start of range to search. 4497*e4b17023SJohn Marino * @param __last1 End of range to search. 4498*e4b17023SJohn Marino * @param __first2 Start of match candidates. 4499*e4b17023SJohn Marino * @param __last2 End of match candidates. 4500*e4b17023SJohn Marino * @return The first iterator @c i in the range 4501*e4b17023SJohn Marino * @p [__first1,__last1) such that @c *i == @p *(i2) such that i2 is an 4502*e4b17023SJohn Marino * iterator in [__first2,__last2), or @p __last1 if no such iterator exists. 4503*e4b17023SJohn Marino * 4504*e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for an element that is 4505*e4b17023SJohn Marino * equal to some element in the range [__first2,__last2). If 4506*e4b17023SJohn Marino * found, returns an iterator in the range [__first1,__last1), 4507*e4b17023SJohn Marino * otherwise returns @p __last1. 4508*e4b17023SJohn Marino */ 4509*e4b17023SJohn Marino template<typename _InputIterator, typename _ForwardIterator> 4510*e4b17023SJohn Marino _InputIterator 4511*e4b17023SJohn Marino find_first_of(_InputIterator __first1, _InputIterator __last1, 4512*e4b17023SJohn Marino _ForwardIterator __first2, _ForwardIterator __last2) 4513*e4b17023SJohn Marino { 4514*e4b17023SJohn Marino // concept requirements 4515*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4516*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4517*e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept< 4518*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type, 4519*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 4520*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1); 4521*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2); 4522*e4b17023SJohn Marino 4523*e4b17023SJohn Marino for (; __first1 != __last1; ++__first1) 4524*e4b17023SJohn Marino for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) 4525*e4b17023SJohn Marino if (*__first1 == *__iter) 4526*e4b17023SJohn Marino return __first1; 4527*e4b17023SJohn Marino return __last1; 4528*e4b17023SJohn Marino } 4529*e4b17023SJohn Marino 4530*e4b17023SJohn Marino /** 4531*e4b17023SJohn Marino * @brief Find element from a set in a sequence using a predicate. 4532*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4533*e4b17023SJohn Marino * @param __first1 Start of range to search. 4534*e4b17023SJohn Marino * @param __last1 End of range to search. 4535*e4b17023SJohn Marino * @param __first2 Start of match candidates. 4536*e4b17023SJohn Marino * @param __last2 End of match candidates. 4537*e4b17023SJohn Marino * @param __comp Predicate to use. 4538*e4b17023SJohn Marino * @return The first iterator @c i in the range 4539*e4b17023SJohn Marino * @p [__first1,__last1) such that @c comp(*i, @p *(i2)) is true 4540*e4b17023SJohn Marino * and i2 is an iterator in [__first2,__last2), or @p __last1 if no 4541*e4b17023SJohn Marino * such iterator exists. 4542*e4b17023SJohn Marino * 4543*e4b17023SJohn Marino 4544*e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for an element that is 4545*e4b17023SJohn Marino * equal to some element in the range [__first2,__last2). If 4546*e4b17023SJohn Marino * found, returns an iterator in the range [__first1,__last1), 4547*e4b17023SJohn Marino * otherwise returns @p __last1. 4548*e4b17023SJohn Marino */ 4549*e4b17023SJohn Marino template<typename _InputIterator, typename _ForwardIterator, 4550*e4b17023SJohn Marino typename _BinaryPredicate> 4551*e4b17023SJohn Marino _InputIterator 4552*e4b17023SJohn Marino find_first_of(_InputIterator __first1, _InputIterator __last1, 4553*e4b17023SJohn Marino _ForwardIterator __first2, _ForwardIterator __last2, 4554*e4b17023SJohn Marino _BinaryPredicate __comp) 4555*e4b17023SJohn Marino { 4556*e4b17023SJohn Marino // concept requirements 4557*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4558*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4559*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 4560*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type, 4561*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 4562*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1); 4563*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2); 4564*e4b17023SJohn Marino 4565*e4b17023SJohn Marino for (; __first1 != __last1; ++__first1) 4566*e4b17023SJohn Marino for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) 4567*e4b17023SJohn Marino if (__comp(*__first1, *__iter)) 4568*e4b17023SJohn Marino return __first1; 4569*e4b17023SJohn Marino return __last1; 4570*e4b17023SJohn Marino } 4571*e4b17023SJohn Marino 4572*e4b17023SJohn Marino /** 4573*e4b17023SJohn Marino * @brief Find two adjacent values in a sequence that are equal. 4574*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4575*e4b17023SJohn Marino * @param __first A forward iterator. 4576*e4b17023SJohn Marino * @param __last A forward iterator. 4577*e4b17023SJohn Marino * @return The first iterator @c i such that @c i and @c i+1 are both 4578*e4b17023SJohn Marino * valid iterators in @p [__first,__last) and such that @c *i == @c *(i+1), 4579*e4b17023SJohn Marino * or @p __last if no such iterator exists. 4580*e4b17023SJohn Marino */ 4581*e4b17023SJohn Marino template<typename _ForwardIterator> 4582*e4b17023SJohn Marino _ForwardIterator 4583*e4b17023SJohn Marino adjacent_find(_ForwardIterator __first, _ForwardIterator __last) 4584*e4b17023SJohn Marino { 4585*e4b17023SJohn Marino // concept requirements 4586*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4587*e4b17023SJohn Marino __glibcxx_function_requires(_EqualityComparableConcept< 4588*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 4589*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4590*e4b17023SJohn Marino if (__first == __last) 4591*e4b17023SJohn Marino return __last; 4592*e4b17023SJohn Marino _ForwardIterator __next = __first; 4593*e4b17023SJohn Marino while(++__next != __last) 4594*e4b17023SJohn Marino { 4595*e4b17023SJohn Marino if (*__first == *__next) 4596*e4b17023SJohn Marino return __first; 4597*e4b17023SJohn Marino __first = __next; 4598*e4b17023SJohn Marino } 4599*e4b17023SJohn Marino return __last; 4600*e4b17023SJohn Marino } 4601*e4b17023SJohn Marino 4602*e4b17023SJohn Marino /** 4603*e4b17023SJohn Marino * @brief Find two adjacent values in a sequence using a predicate. 4604*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4605*e4b17023SJohn Marino * @param __first A forward iterator. 4606*e4b17023SJohn Marino * @param __last A forward iterator. 4607*e4b17023SJohn Marino * @param __binary_pred A binary predicate. 4608*e4b17023SJohn Marino * @return The first iterator @c i such that @c i and @c i+1 are both 4609*e4b17023SJohn Marino * valid iterators in @p [__first,__last) and such that 4610*e4b17023SJohn Marino * @p __binary_pred(*i,*(i+1)) is true, or @p __last if no such iterator 4611*e4b17023SJohn Marino * exists. 4612*e4b17023SJohn Marino */ 4613*e4b17023SJohn Marino template<typename _ForwardIterator, typename _BinaryPredicate> 4614*e4b17023SJohn Marino _ForwardIterator 4615*e4b17023SJohn Marino adjacent_find(_ForwardIterator __first, _ForwardIterator __last, 4616*e4b17023SJohn Marino _BinaryPredicate __binary_pred) 4617*e4b17023SJohn Marino { 4618*e4b17023SJohn Marino // concept requirements 4619*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4620*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 4621*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, 4622*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 4623*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4624*e4b17023SJohn Marino if (__first == __last) 4625*e4b17023SJohn Marino return __last; 4626*e4b17023SJohn Marino _ForwardIterator __next = __first; 4627*e4b17023SJohn Marino while(++__next != __last) 4628*e4b17023SJohn Marino { 4629*e4b17023SJohn Marino if (__binary_pred(*__first, *__next)) 4630*e4b17023SJohn Marino return __first; 4631*e4b17023SJohn Marino __first = __next; 4632*e4b17023SJohn Marino } 4633*e4b17023SJohn Marino return __last; 4634*e4b17023SJohn Marino } 4635*e4b17023SJohn Marino 4636*e4b17023SJohn Marino /** 4637*e4b17023SJohn Marino * @brief Count the number of copies of a value in a sequence. 4638*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4639*e4b17023SJohn Marino * @param __first An input iterator. 4640*e4b17023SJohn Marino * @param __last An input iterator. 4641*e4b17023SJohn Marino * @param __value The value to be counted. 4642*e4b17023SJohn Marino * @return The number of iterators @c i in the range @p [__first,__last) 4643*e4b17023SJohn Marino * for which @c *i == @p __value 4644*e4b17023SJohn Marino */ 4645*e4b17023SJohn Marino template<typename _InputIterator, typename _Tp> 4646*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::difference_type 4647*e4b17023SJohn Marino count(_InputIterator __first, _InputIterator __last, const _Tp& __value) 4648*e4b17023SJohn Marino { 4649*e4b17023SJohn Marino // concept requirements 4650*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4651*e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept< 4652*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type, _Tp>) 4653*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4654*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::difference_type __n = 0; 4655*e4b17023SJohn Marino for (; __first != __last; ++__first) 4656*e4b17023SJohn Marino if (*__first == __value) 4657*e4b17023SJohn Marino ++__n; 4658*e4b17023SJohn Marino return __n; 4659*e4b17023SJohn Marino } 4660*e4b17023SJohn Marino 4661*e4b17023SJohn Marino /** 4662*e4b17023SJohn Marino * @brief Count the elements of a sequence for which a predicate is true. 4663*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4664*e4b17023SJohn Marino * @param __first An input iterator. 4665*e4b17023SJohn Marino * @param __last An input iterator. 4666*e4b17023SJohn Marino * @param __pred A predicate. 4667*e4b17023SJohn Marino * @return The number of iterators @c i in the range @p [__first,__last) 4668*e4b17023SJohn Marino * for which @p __pred(*i) is true. 4669*e4b17023SJohn Marino */ 4670*e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate> 4671*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::difference_type 4672*e4b17023SJohn Marino count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) 4673*e4b17023SJohn Marino { 4674*e4b17023SJohn Marino // concept requirements 4675*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4676*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 4677*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 4678*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4679*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::difference_type __n = 0; 4680*e4b17023SJohn Marino for (; __first != __last; ++__first) 4681*e4b17023SJohn Marino if (__pred(*__first)) 4682*e4b17023SJohn Marino ++__n; 4683*e4b17023SJohn Marino return __n; 4684*e4b17023SJohn Marino } 4685*e4b17023SJohn Marino 4686*e4b17023SJohn Marino /** 4687*e4b17023SJohn Marino * @brief Search a sequence for a matching sub-sequence. 4688*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4689*e4b17023SJohn Marino * @param __first1 A forward iterator. 4690*e4b17023SJohn Marino * @param __last1 A forward iterator. 4691*e4b17023SJohn Marino * @param __first2 A forward iterator. 4692*e4b17023SJohn Marino * @param __last2 A forward iterator. 4693*e4b17023SJohn Marino * @return The first iterator @c i in the range @p 4694*e4b17023SJohn Marino * [__first1,__last1-(__last2-__first2)) such that @c *(i+N) == @p 4695*e4b17023SJohn Marino * *(__first2+N) for each @c N in the range @p 4696*e4b17023SJohn Marino * [0,__last2-__first2), or @p __last1 if no such iterator exists. 4697*e4b17023SJohn Marino * 4698*e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for a sub-sequence that 4699*e4b17023SJohn Marino * compares equal value-by-value with the sequence given by @p 4700*e4b17023SJohn Marino * [__first2,__last2) and returns an iterator to the first element 4701*e4b17023SJohn Marino * of the sub-sequence, or @p __last1 if the sub-sequence is not 4702*e4b17023SJohn Marino * found. 4703*e4b17023SJohn Marino * 4704*e4b17023SJohn Marino * Because the sub-sequence must lie completely within the range @p 4705*e4b17023SJohn Marino * [__first1,__last1) it must start at a position less than @p 4706*e4b17023SJohn Marino * __last1-(__last2-__first2) where @p __last2-__first2 is the 4707*e4b17023SJohn Marino * length of the sub-sequence. 4708*e4b17023SJohn Marino * 4709*e4b17023SJohn Marino * This means that the returned iterator @c i will be in the range 4710*e4b17023SJohn Marino * @p [__first1,__last1-(__last2-__first2)) 4711*e4b17023SJohn Marino */ 4712*e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2> 4713*e4b17023SJohn Marino _ForwardIterator1 4714*e4b17023SJohn Marino search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 4715*e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2) 4716*e4b17023SJohn Marino { 4717*e4b17023SJohn Marino // concept requirements 4718*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) 4719*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) 4720*e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept< 4721*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator1>::value_type, 4722*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator2>::value_type>) 4723*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1); 4724*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2); 4725*e4b17023SJohn Marino 4726*e4b17023SJohn Marino // Test for empty ranges 4727*e4b17023SJohn Marino if (__first1 == __last1 || __first2 == __last2) 4728*e4b17023SJohn Marino return __first1; 4729*e4b17023SJohn Marino 4730*e4b17023SJohn Marino // Test for a pattern of length 1. 4731*e4b17023SJohn Marino _ForwardIterator2 __p1(__first2); 4732*e4b17023SJohn Marino if (++__p1 == __last2) 4733*e4b17023SJohn Marino return _GLIBCXX_STD_A::find(__first1, __last1, *__first2); 4734*e4b17023SJohn Marino 4735*e4b17023SJohn Marino // General case. 4736*e4b17023SJohn Marino _ForwardIterator2 __p; 4737*e4b17023SJohn Marino _ForwardIterator1 __current = __first1; 4738*e4b17023SJohn Marino 4739*e4b17023SJohn Marino for (;;) 4740*e4b17023SJohn Marino { 4741*e4b17023SJohn Marino __first1 = _GLIBCXX_STD_A::find(__first1, __last1, *__first2); 4742*e4b17023SJohn Marino if (__first1 == __last1) 4743*e4b17023SJohn Marino return __last1; 4744*e4b17023SJohn Marino 4745*e4b17023SJohn Marino __p = __p1; 4746*e4b17023SJohn Marino __current = __first1; 4747*e4b17023SJohn Marino if (++__current == __last1) 4748*e4b17023SJohn Marino return __last1; 4749*e4b17023SJohn Marino 4750*e4b17023SJohn Marino while (*__current == *__p) 4751*e4b17023SJohn Marino { 4752*e4b17023SJohn Marino if (++__p == __last2) 4753*e4b17023SJohn Marino return __first1; 4754*e4b17023SJohn Marino if (++__current == __last1) 4755*e4b17023SJohn Marino return __last1; 4756*e4b17023SJohn Marino } 4757*e4b17023SJohn Marino ++__first1; 4758*e4b17023SJohn Marino } 4759*e4b17023SJohn Marino return __first1; 4760*e4b17023SJohn Marino } 4761*e4b17023SJohn Marino 4762*e4b17023SJohn Marino /** 4763*e4b17023SJohn Marino * @brief Search a sequence for a matching sub-sequence using a predicate. 4764*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4765*e4b17023SJohn Marino * @param __first1 A forward iterator. 4766*e4b17023SJohn Marino * @param __last1 A forward iterator. 4767*e4b17023SJohn Marino * @param __first2 A forward iterator. 4768*e4b17023SJohn Marino * @param __last2 A forward iterator. 4769*e4b17023SJohn Marino * @param __predicate A binary predicate. 4770*e4b17023SJohn Marino * @return The first iterator @c i in the range 4771*e4b17023SJohn Marino * @p [__first1,__last1-(__last2-__first2)) such that 4772*e4b17023SJohn Marino * @p __predicate(*(i+N),*(__first2+N)) is true for each @c N in the range 4773*e4b17023SJohn Marino * @p [0,__last2-__first2), or @p __last1 if no such iterator exists. 4774*e4b17023SJohn Marino * 4775*e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for a sub-sequence that 4776*e4b17023SJohn Marino * compares equal value-by-value with the sequence given by @p 4777*e4b17023SJohn Marino * [__first2,__last2), using @p __predicate to determine equality, 4778*e4b17023SJohn Marino * and returns an iterator to the first element of the 4779*e4b17023SJohn Marino * sub-sequence, or @p __last1 if no such iterator exists. 4780*e4b17023SJohn Marino * 4781*e4b17023SJohn Marino * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2) 4782*e4b17023SJohn Marino */ 4783*e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2, 4784*e4b17023SJohn Marino typename _BinaryPredicate> 4785*e4b17023SJohn Marino _ForwardIterator1 4786*e4b17023SJohn Marino search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 4787*e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2, 4788*e4b17023SJohn Marino _BinaryPredicate __predicate) 4789*e4b17023SJohn Marino { 4790*e4b17023SJohn Marino // concept requirements 4791*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) 4792*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) 4793*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 4794*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator1>::value_type, 4795*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator2>::value_type>) 4796*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1); 4797*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2); 4798*e4b17023SJohn Marino 4799*e4b17023SJohn Marino // Test for empty ranges 4800*e4b17023SJohn Marino if (__first1 == __last1 || __first2 == __last2) 4801*e4b17023SJohn Marino return __first1; 4802*e4b17023SJohn Marino 4803*e4b17023SJohn Marino // Test for a pattern of length 1. 4804*e4b17023SJohn Marino _ForwardIterator2 __p1(__first2); 4805*e4b17023SJohn Marino if (++__p1 == __last2) 4806*e4b17023SJohn Marino { 4807*e4b17023SJohn Marino while (__first1 != __last1 4808*e4b17023SJohn Marino && !bool(__predicate(*__first1, *__first2))) 4809*e4b17023SJohn Marino ++__first1; 4810*e4b17023SJohn Marino return __first1; 4811*e4b17023SJohn Marino } 4812*e4b17023SJohn Marino 4813*e4b17023SJohn Marino // General case. 4814*e4b17023SJohn Marino _ForwardIterator2 __p; 4815*e4b17023SJohn Marino _ForwardIterator1 __current = __first1; 4816*e4b17023SJohn Marino 4817*e4b17023SJohn Marino for (;;) 4818*e4b17023SJohn Marino { 4819*e4b17023SJohn Marino while (__first1 != __last1 4820*e4b17023SJohn Marino && !bool(__predicate(*__first1, *__first2))) 4821*e4b17023SJohn Marino ++__first1; 4822*e4b17023SJohn Marino if (__first1 == __last1) 4823*e4b17023SJohn Marino return __last1; 4824*e4b17023SJohn Marino 4825*e4b17023SJohn Marino __p = __p1; 4826*e4b17023SJohn Marino __current = __first1; 4827*e4b17023SJohn Marino if (++__current == __last1) 4828*e4b17023SJohn Marino return __last1; 4829*e4b17023SJohn Marino 4830*e4b17023SJohn Marino while (__predicate(*__current, *__p)) 4831*e4b17023SJohn Marino { 4832*e4b17023SJohn Marino if (++__p == __last2) 4833*e4b17023SJohn Marino return __first1; 4834*e4b17023SJohn Marino if (++__current == __last1) 4835*e4b17023SJohn Marino return __last1; 4836*e4b17023SJohn Marino } 4837*e4b17023SJohn Marino ++__first1; 4838*e4b17023SJohn Marino } 4839*e4b17023SJohn Marino return __first1; 4840*e4b17023SJohn Marino } 4841*e4b17023SJohn Marino 4842*e4b17023SJohn Marino 4843*e4b17023SJohn Marino /** 4844*e4b17023SJohn Marino * @brief Search a sequence for a number of consecutive values. 4845*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4846*e4b17023SJohn Marino * @param __first A forward iterator. 4847*e4b17023SJohn Marino * @param __last A forward iterator. 4848*e4b17023SJohn Marino * @param __count The number of consecutive values. 4849*e4b17023SJohn Marino * @param __val The value to find. 4850*e4b17023SJohn Marino * @return The first iterator @c i in the range @p 4851*e4b17023SJohn Marino * [__first,__last-__count) such that @c *(i+N) == @p __val for 4852*e4b17023SJohn Marino * each @c N in the range @p [0,__count), or @p __last if no such 4853*e4b17023SJohn Marino * iterator exists. 4854*e4b17023SJohn Marino * 4855*e4b17023SJohn Marino * Searches the range @p [__first,__last) for @p count consecutive elements 4856*e4b17023SJohn Marino * equal to @p __val. 4857*e4b17023SJohn Marino */ 4858*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Integer, typename _Tp> 4859*e4b17023SJohn Marino _ForwardIterator 4860*e4b17023SJohn Marino search_n(_ForwardIterator __first, _ForwardIterator __last, 4861*e4b17023SJohn Marino _Integer __count, const _Tp& __val) 4862*e4b17023SJohn Marino { 4863*e4b17023SJohn Marino // concept requirements 4864*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4865*e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept< 4866*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, _Tp>) 4867*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4868*e4b17023SJohn Marino 4869*e4b17023SJohn Marino if (__count <= 0) 4870*e4b17023SJohn Marino return __first; 4871*e4b17023SJohn Marino if (__count == 1) 4872*e4b17023SJohn Marino return _GLIBCXX_STD_A::find(__first, __last, __val); 4873*e4b17023SJohn Marino return std::__search_n(__first, __last, __count, __val, 4874*e4b17023SJohn Marino std::__iterator_category(__first)); 4875*e4b17023SJohn Marino } 4876*e4b17023SJohn Marino 4877*e4b17023SJohn Marino 4878*e4b17023SJohn Marino /** 4879*e4b17023SJohn Marino * @brief Search a sequence for a number of consecutive values using a 4880*e4b17023SJohn Marino * predicate. 4881*e4b17023SJohn Marino * @ingroup non_mutating_algorithms 4882*e4b17023SJohn Marino * @param __first A forward iterator. 4883*e4b17023SJohn Marino * @param __last A forward iterator. 4884*e4b17023SJohn Marino * @param __count The number of consecutive values. 4885*e4b17023SJohn Marino * @param __val The value to find. 4886*e4b17023SJohn Marino * @param __binary_pred A binary predicate. 4887*e4b17023SJohn Marino * @return The first iterator @c i in the range @p 4888*e4b17023SJohn Marino * [__first,__last-__count) such that @p 4889*e4b17023SJohn Marino * __binary_pred(*(i+N),__val) is true for each @c N in the range 4890*e4b17023SJohn Marino * @p [0,__count), or @p __last if no such iterator exists. 4891*e4b17023SJohn Marino * 4892*e4b17023SJohn Marino * Searches the range @p [__first,__last) for @p __count 4893*e4b17023SJohn Marino * consecutive elements for which the predicate returns true. 4894*e4b17023SJohn Marino */ 4895*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Integer, typename _Tp, 4896*e4b17023SJohn Marino typename _BinaryPredicate> 4897*e4b17023SJohn Marino _ForwardIterator 4898*e4b17023SJohn Marino search_n(_ForwardIterator __first, _ForwardIterator __last, 4899*e4b17023SJohn Marino _Integer __count, const _Tp& __val, 4900*e4b17023SJohn Marino _BinaryPredicate __binary_pred) 4901*e4b17023SJohn Marino { 4902*e4b17023SJohn Marino // concept requirements 4903*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4904*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 4905*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, _Tp>) 4906*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4907*e4b17023SJohn Marino 4908*e4b17023SJohn Marino if (__count <= 0) 4909*e4b17023SJohn Marino return __first; 4910*e4b17023SJohn Marino if (__count == 1) 4911*e4b17023SJohn Marino { 4912*e4b17023SJohn Marino while (__first != __last && !bool(__binary_pred(*__first, __val))) 4913*e4b17023SJohn Marino ++__first; 4914*e4b17023SJohn Marino return __first; 4915*e4b17023SJohn Marino } 4916*e4b17023SJohn Marino return std::__search_n(__first, __last, __count, __val, __binary_pred, 4917*e4b17023SJohn Marino std::__iterator_category(__first)); 4918*e4b17023SJohn Marino } 4919*e4b17023SJohn Marino 4920*e4b17023SJohn Marino 4921*e4b17023SJohn Marino /** 4922*e4b17023SJohn Marino * @brief Perform an operation on a sequence. 4923*e4b17023SJohn Marino * @ingroup mutating_algorithms 4924*e4b17023SJohn Marino * @param __first An input iterator. 4925*e4b17023SJohn Marino * @param __last An input iterator. 4926*e4b17023SJohn Marino * @param __result An output iterator. 4927*e4b17023SJohn Marino * @param __unary_op A unary operator. 4928*e4b17023SJohn Marino * @return An output iterator equal to @p __result+(__last-__first). 4929*e4b17023SJohn Marino * 4930*e4b17023SJohn Marino * Applies the operator to each element in the input range and assigns 4931*e4b17023SJohn Marino * the results to successive elements of the output sequence. 4932*e4b17023SJohn Marino * Evaluates @p *(__result+N)=unary_op(*(__first+N)) for each @c N in the 4933*e4b17023SJohn Marino * range @p [0,__last-__first). 4934*e4b17023SJohn Marino * 4935*e4b17023SJohn Marino * @p unary_op must not alter its argument. 4936*e4b17023SJohn Marino */ 4937*e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator, 4938*e4b17023SJohn Marino typename _UnaryOperation> 4939*e4b17023SJohn Marino _OutputIterator 4940*e4b17023SJohn Marino transform(_InputIterator __first, _InputIterator __last, 4941*e4b17023SJohn Marino _OutputIterator __result, _UnaryOperation __unary_op) 4942*e4b17023SJohn Marino { 4943*e4b17023SJohn Marino // concept requirements 4944*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4945*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 4946*e4b17023SJohn Marino // "the type returned by a _UnaryOperation" 4947*e4b17023SJohn Marino __typeof__(__unary_op(*__first))>) 4948*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 4949*e4b17023SJohn Marino 4950*e4b17023SJohn Marino for (; __first != __last; ++__first, ++__result) 4951*e4b17023SJohn Marino *__result = __unary_op(*__first); 4952*e4b17023SJohn Marino return __result; 4953*e4b17023SJohn Marino } 4954*e4b17023SJohn Marino 4955*e4b17023SJohn Marino /** 4956*e4b17023SJohn Marino * @brief Perform an operation on corresponding elements of two sequences. 4957*e4b17023SJohn Marino * @ingroup mutating_algorithms 4958*e4b17023SJohn Marino * @param __first1 An input iterator. 4959*e4b17023SJohn Marino * @param __last1 An input iterator. 4960*e4b17023SJohn Marino * @param __first2 An input iterator. 4961*e4b17023SJohn Marino * @param __result An output iterator. 4962*e4b17023SJohn Marino * @param __binary_op A binary operator. 4963*e4b17023SJohn Marino * @return An output iterator equal to @p result+(last-first). 4964*e4b17023SJohn Marino * 4965*e4b17023SJohn Marino * Applies the operator to the corresponding elements in the two 4966*e4b17023SJohn Marino * input ranges and assigns the results to successive elements of the 4967*e4b17023SJohn Marino * output sequence. 4968*e4b17023SJohn Marino * Evaluates @p 4969*e4b17023SJohn Marino * *(__result+N)=__binary_op(*(__first1+N),*(__first2+N)) for each 4970*e4b17023SJohn Marino * @c N in the range @p [0,__last1-__first1). 4971*e4b17023SJohn Marino * 4972*e4b17023SJohn Marino * @p binary_op must not alter either of its arguments. 4973*e4b17023SJohn Marino */ 4974*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 4975*e4b17023SJohn Marino typename _OutputIterator, typename _BinaryOperation> 4976*e4b17023SJohn Marino _OutputIterator 4977*e4b17023SJohn Marino transform(_InputIterator1 __first1, _InputIterator1 __last1, 4978*e4b17023SJohn Marino _InputIterator2 __first2, _OutputIterator __result, 4979*e4b17023SJohn Marino _BinaryOperation __binary_op) 4980*e4b17023SJohn Marino { 4981*e4b17023SJohn Marino // concept requirements 4982*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 4983*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 4984*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 4985*e4b17023SJohn Marino // "the type returned by a _BinaryOperation" 4986*e4b17023SJohn Marino __typeof__(__binary_op(*__first1,*__first2))>) 4987*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1); 4988*e4b17023SJohn Marino 4989*e4b17023SJohn Marino for (; __first1 != __last1; ++__first1, ++__first2, ++__result) 4990*e4b17023SJohn Marino *__result = __binary_op(*__first1, *__first2); 4991*e4b17023SJohn Marino return __result; 4992*e4b17023SJohn Marino } 4993*e4b17023SJohn Marino 4994*e4b17023SJohn Marino /** 4995*e4b17023SJohn Marino * @brief Replace each occurrence of one value in a sequence with another 4996*e4b17023SJohn Marino * value. 4997*e4b17023SJohn Marino * @ingroup mutating_algorithms 4998*e4b17023SJohn Marino * @param __first A forward iterator. 4999*e4b17023SJohn Marino * @param __last A forward iterator. 5000*e4b17023SJohn Marino * @param __old_value The value to be replaced. 5001*e4b17023SJohn Marino * @param __new_value The replacement value. 5002*e4b17023SJohn Marino * @return replace() returns no value. 5003*e4b17023SJohn Marino * 5004*e4b17023SJohn Marino * For each iterator @c i in the range @p [__first,__last) if @c *i == 5005*e4b17023SJohn Marino * @p __old_value then the assignment @c *i = @p __new_value is performed. 5006*e4b17023SJohn Marino */ 5007*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp> 5008*e4b17023SJohn Marino void 5009*e4b17023SJohn Marino replace(_ForwardIterator __first, _ForwardIterator __last, 5010*e4b17023SJohn Marino const _Tp& __old_value, const _Tp& __new_value) 5011*e4b17023SJohn Marino { 5012*e4b17023SJohn Marino // concept requirements 5013*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 5014*e4b17023SJohn Marino _ForwardIterator>) 5015*e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept< 5016*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, _Tp>) 5017*e4b17023SJohn Marino __glibcxx_function_requires(_ConvertibleConcept<_Tp, 5018*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 5019*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5020*e4b17023SJohn Marino 5021*e4b17023SJohn Marino for (; __first != __last; ++__first) 5022*e4b17023SJohn Marino if (*__first == __old_value) 5023*e4b17023SJohn Marino *__first = __new_value; 5024*e4b17023SJohn Marino } 5025*e4b17023SJohn Marino 5026*e4b17023SJohn Marino /** 5027*e4b17023SJohn Marino * @brief Replace each value in a sequence for which a predicate returns 5028*e4b17023SJohn Marino * true with another value. 5029*e4b17023SJohn Marino * @ingroup mutating_algorithms 5030*e4b17023SJohn Marino * @param __first A forward iterator. 5031*e4b17023SJohn Marino * @param __last A forward iterator. 5032*e4b17023SJohn Marino * @param __pred A predicate. 5033*e4b17023SJohn Marino * @param __new_value The replacement value. 5034*e4b17023SJohn Marino * @return replace_if() returns no value. 5035*e4b17023SJohn Marino * 5036*e4b17023SJohn Marino * For each iterator @c i in the range @p [__first,__last) if @p __pred(*i) 5037*e4b17023SJohn Marino * is true then the assignment @c *i = @p __new_value is performed. 5038*e4b17023SJohn Marino */ 5039*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate, typename _Tp> 5040*e4b17023SJohn Marino void 5041*e4b17023SJohn Marino replace_if(_ForwardIterator __first, _ForwardIterator __last, 5042*e4b17023SJohn Marino _Predicate __pred, const _Tp& __new_value) 5043*e4b17023SJohn Marino { 5044*e4b17023SJohn Marino // concept requirements 5045*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 5046*e4b17023SJohn Marino _ForwardIterator>) 5047*e4b17023SJohn Marino __glibcxx_function_requires(_ConvertibleConcept<_Tp, 5048*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 5049*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 5050*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 5051*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5052*e4b17023SJohn Marino 5053*e4b17023SJohn Marino for (; __first != __last; ++__first) 5054*e4b17023SJohn Marino if (__pred(*__first)) 5055*e4b17023SJohn Marino *__first = __new_value; 5056*e4b17023SJohn Marino } 5057*e4b17023SJohn Marino 5058*e4b17023SJohn Marino /** 5059*e4b17023SJohn Marino * @brief Assign the result of a function object to each value in a 5060*e4b17023SJohn Marino * sequence. 5061*e4b17023SJohn Marino * @ingroup mutating_algorithms 5062*e4b17023SJohn Marino * @param __first A forward iterator. 5063*e4b17023SJohn Marino * @param __last A forward iterator. 5064*e4b17023SJohn Marino * @param __gen A function object taking no arguments and returning 5065*e4b17023SJohn Marino * std::iterator_traits<_ForwardIterator>::value_type 5066*e4b17023SJohn Marino * @return generate() returns no value. 5067*e4b17023SJohn Marino * 5068*e4b17023SJohn Marino * Performs the assignment @c *i = @p __gen() for each @c i in the range 5069*e4b17023SJohn Marino * @p [__first,__last). 5070*e4b17023SJohn Marino */ 5071*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Generator> 5072*e4b17023SJohn Marino void 5073*e4b17023SJohn Marino generate(_ForwardIterator __first, _ForwardIterator __last, 5074*e4b17023SJohn Marino _Generator __gen) 5075*e4b17023SJohn Marino { 5076*e4b17023SJohn Marino // concept requirements 5077*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 5078*e4b17023SJohn Marino __glibcxx_function_requires(_GeneratorConcept<_Generator, 5079*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 5080*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5081*e4b17023SJohn Marino 5082*e4b17023SJohn Marino for (; __first != __last; ++__first) 5083*e4b17023SJohn Marino *__first = __gen(); 5084*e4b17023SJohn Marino } 5085*e4b17023SJohn Marino 5086*e4b17023SJohn Marino /** 5087*e4b17023SJohn Marino * @brief Assign the result of a function object to each value in a 5088*e4b17023SJohn Marino * sequence. 5089*e4b17023SJohn Marino * @ingroup mutating_algorithms 5090*e4b17023SJohn Marino * @param __first A forward iterator. 5091*e4b17023SJohn Marino * @param __n The length of the sequence. 5092*e4b17023SJohn Marino * @param __gen A function object taking no arguments and returning 5093*e4b17023SJohn Marino * std::iterator_traits<_ForwardIterator>::value_type 5094*e4b17023SJohn Marino * @return The end of the sequence, @p __first+__n 5095*e4b17023SJohn Marino * 5096*e4b17023SJohn Marino * Performs the assignment @c *i = @p __gen() for each @c i in the range 5097*e4b17023SJohn Marino * @p [__first,__first+__n). 5098*e4b17023SJohn Marino * 5099*e4b17023SJohn Marino * _GLIBCXX_RESOLVE_LIB_DEFECTS 5100*e4b17023SJohn Marino * DR 865. More algorithms that throw away information 5101*e4b17023SJohn Marino */ 5102*e4b17023SJohn Marino template<typename _OutputIterator, typename _Size, typename _Generator> 5103*e4b17023SJohn Marino _OutputIterator 5104*e4b17023SJohn Marino generate_n(_OutputIterator __first, _Size __n, _Generator __gen) 5105*e4b17023SJohn Marino { 5106*e4b17023SJohn Marino // concept requirements 5107*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5108*e4b17023SJohn Marino // "the type returned by a _Generator" 5109*e4b17023SJohn Marino __typeof__(__gen())>) 5110*e4b17023SJohn Marino 5111*e4b17023SJohn Marino for (__decltype(__n + 0) __niter = __n; 5112*e4b17023SJohn Marino __niter > 0; --__niter, ++__first) 5113*e4b17023SJohn Marino *__first = __gen(); 5114*e4b17023SJohn Marino return __first; 5115*e4b17023SJohn Marino } 5116*e4b17023SJohn Marino 5117*e4b17023SJohn Marino 5118*e4b17023SJohn Marino /** 5119*e4b17023SJohn Marino * @brief Copy a sequence, removing consecutive duplicate values. 5120*e4b17023SJohn Marino * @ingroup mutating_algorithms 5121*e4b17023SJohn Marino * @param __first An input iterator. 5122*e4b17023SJohn Marino * @param __last An input iterator. 5123*e4b17023SJohn Marino * @param __result An output iterator. 5124*e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence. 5125*e4b17023SJohn Marino * 5126*e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) to the range 5127*e4b17023SJohn Marino * beginning at @p __result, except that only the first element is copied 5128*e4b17023SJohn Marino * from groups of consecutive elements that compare equal. 5129*e4b17023SJohn Marino * unique_copy() is stable, so the relative order of elements that are 5130*e4b17023SJohn Marino * copied is unchanged. 5131*e4b17023SJohn Marino * 5132*e4b17023SJohn Marino * _GLIBCXX_RESOLVE_LIB_DEFECTS 5133*e4b17023SJohn Marino * DR 241. Does unique_copy() require CopyConstructible and Assignable? 5134*e4b17023SJohn Marino * 5135*e4b17023SJohn Marino * _GLIBCXX_RESOLVE_LIB_DEFECTS 5136*e4b17023SJohn Marino * DR 538. 241 again: Does unique_copy() require CopyConstructible and 5137*e4b17023SJohn Marino * Assignable? 5138*e4b17023SJohn Marino */ 5139*e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator> 5140*e4b17023SJohn Marino inline _OutputIterator 5141*e4b17023SJohn Marino unique_copy(_InputIterator __first, _InputIterator __last, 5142*e4b17023SJohn Marino _OutputIterator __result) 5143*e4b17023SJohn Marino { 5144*e4b17023SJohn Marino // concept requirements 5145*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 5146*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5147*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 5148*e4b17023SJohn Marino __glibcxx_function_requires(_EqualityComparableConcept< 5149*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 5150*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5151*e4b17023SJohn Marino 5152*e4b17023SJohn Marino if (__first == __last) 5153*e4b17023SJohn Marino return __result; 5154*e4b17023SJohn Marino return std::__unique_copy(__first, __last, __result, 5155*e4b17023SJohn Marino std::__iterator_category(__first), 5156*e4b17023SJohn Marino std::__iterator_category(__result)); 5157*e4b17023SJohn Marino } 5158*e4b17023SJohn Marino 5159*e4b17023SJohn Marino /** 5160*e4b17023SJohn Marino * @brief Copy a sequence, removing consecutive values using a predicate. 5161*e4b17023SJohn Marino * @ingroup mutating_algorithms 5162*e4b17023SJohn Marino * @param __first An input iterator. 5163*e4b17023SJohn Marino * @param __last An input iterator. 5164*e4b17023SJohn Marino * @param __result An output iterator. 5165*e4b17023SJohn Marino * @param __binary_pred A binary predicate. 5166*e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence. 5167*e4b17023SJohn Marino * 5168*e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) to the range 5169*e4b17023SJohn Marino * beginning at @p __result, except that only the first element is copied 5170*e4b17023SJohn Marino * from groups of consecutive elements for which @p __binary_pred returns 5171*e4b17023SJohn Marino * true. 5172*e4b17023SJohn Marino * unique_copy() is stable, so the relative order of elements that are 5173*e4b17023SJohn Marino * copied is unchanged. 5174*e4b17023SJohn Marino * 5175*e4b17023SJohn Marino * _GLIBCXX_RESOLVE_LIB_DEFECTS 5176*e4b17023SJohn Marino * DR 241. Does unique_copy() require CopyConstructible and Assignable? 5177*e4b17023SJohn Marino */ 5178*e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator, 5179*e4b17023SJohn Marino typename _BinaryPredicate> 5180*e4b17023SJohn Marino inline _OutputIterator 5181*e4b17023SJohn Marino unique_copy(_InputIterator __first, _InputIterator __last, 5182*e4b17023SJohn Marino _OutputIterator __result, 5183*e4b17023SJohn Marino _BinaryPredicate __binary_pred) 5184*e4b17023SJohn Marino { 5185*e4b17023SJohn Marino // concept requirements -- predicates checked later 5186*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 5187*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5188*e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>) 5189*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5190*e4b17023SJohn Marino 5191*e4b17023SJohn Marino if (__first == __last) 5192*e4b17023SJohn Marino return __result; 5193*e4b17023SJohn Marino return std::__unique_copy(__first, __last, __result, __binary_pred, 5194*e4b17023SJohn Marino std::__iterator_category(__first), 5195*e4b17023SJohn Marino std::__iterator_category(__result)); 5196*e4b17023SJohn Marino } 5197*e4b17023SJohn Marino 5198*e4b17023SJohn Marino 5199*e4b17023SJohn Marino /** 5200*e4b17023SJohn Marino * @brief Randomly shuffle the elements of a sequence. 5201*e4b17023SJohn Marino * @ingroup mutating_algorithms 5202*e4b17023SJohn Marino * @param __first A forward iterator. 5203*e4b17023SJohn Marino * @param __last A forward iterator. 5204*e4b17023SJohn Marino * @return Nothing. 5205*e4b17023SJohn Marino * 5206*e4b17023SJohn Marino * Reorder the elements in the range @p [__first,__last) using a random 5207*e4b17023SJohn Marino * distribution, so that every possible ordering of the sequence is 5208*e4b17023SJohn Marino * equally likely. 5209*e4b17023SJohn Marino */ 5210*e4b17023SJohn Marino template<typename _RandomAccessIterator> 5211*e4b17023SJohn Marino inline void 5212*e4b17023SJohn Marino random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) 5213*e4b17023SJohn Marino { 5214*e4b17023SJohn Marino // concept requirements 5215*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 5216*e4b17023SJohn Marino _RandomAccessIterator>) 5217*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5218*e4b17023SJohn Marino 5219*e4b17023SJohn Marino if (__first != __last) 5220*e4b17023SJohn Marino for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) 5221*e4b17023SJohn Marino std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1))); 5222*e4b17023SJohn Marino } 5223*e4b17023SJohn Marino 5224*e4b17023SJohn Marino /** 5225*e4b17023SJohn Marino * @brief Shuffle the elements of a sequence using a random number 5226*e4b17023SJohn Marino * generator. 5227*e4b17023SJohn Marino * @ingroup mutating_algorithms 5228*e4b17023SJohn Marino * @param __first A forward iterator. 5229*e4b17023SJohn Marino * @param __last A forward iterator. 5230*e4b17023SJohn Marino * @param __rand The RNG functor or function. 5231*e4b17023SJohn Marino * @return Nothing. 5232*e4b17023SJohn Marino * 5233*e4b17023SJohn Marino * Reorders the elements in the range @p [__first,__last) using @p __rand to 5234*e4b17023SJohn Marino * provide a random distribution. Calling @p __rand(N) for a positive 5235*e4b17023SJohn Marino * integer @p N should return a randomly chosen integer from the 5236*e4b17023SJohn Marino * range [0,N). 5237*e4b17023SJohn Marino */ 5238*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _RandomNumberGenerator> 5239*e4b17023SJohn Marino void 5240*e4b17023SJohn Marino random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, 5241*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 5242*e4b17023SJohn Marino _RandomNumberGenerator&& __rand) 5243*e4b17023SJohn Marino #else 5244*e4b17023SJohn Marino _RandomNumberGenerator& __rand) 5245*e4b17023SJohn Marino #endif 5246*e4b17023SJohn Marino { 5247*e4b17023SJohn Marino // concept requirements 5248*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 5249*e4b17023SJohn Marino _RandomAccessIterator>) 5250*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5251*e4b17023SJohn Marino 5252*e4b17023SJohn Marino if (__first == __last) 5253*e4b17023SJohn Marino return; 5254*e4b17023SJohn Marino for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) 5255*e4b17023SJohn Marino std::iter_swap(__i, __first + __rand((__i - __first) + 1)); 5256*e4b17023SJohn Marino } 5257*e4b17023SJohn Marino 5258*e4b17023SJohn Marino 5259*e4b17023SJohn Marino /** 5260*e4b17023SJohn Marino * @brief Move elements for which a predicate is true to the beginning 5261*e4b17023SJohn Marino * of a sequence. 5262*e4b17023SJohn Marino * @ingroup mutating_algorithms 5263*e4b17023SJohn Marino * @param __first A forward iterator. 5264*e4b17023SJohn Marino * @param __last A forward iterator. 5265*e4b17023SJohn Marino * @param __pred A predicate functor. 5266*e4b17023SJohn Marino * @return An iterator @p middle such that @p __pred(i) is true for each 5267*e4b17023SJohn Marino * iterator @p i in the range @p [__first,middle) and false for each @p i 5268*e4b17023SJohn Marino * in the range @p [middle,__last). 5269*e4b17023SJohn Marino * 5270*e4b17023SJohn Marino * @p __pred must not modify its operand. @p partition() does not preserve 5271*e4b17023SJohn Marino * the relative ordering of elements in each group, use 5272*e4b17023SJohn Marino * @p stable_partition() if this is needed. 5273*e4b17023SJohn Marino */ 5274*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate> 5275*e4b17023SJohn Marino inline _ForwardIterator 5276*e4b17023SJohn Marino partition(_ForwardIterator __first, _ForwardIterator __last, 5277*e4b17023SJohn Marino _Predicate __pred) 5278*e4b17023SJohn Marino { 5279*e4b17023SJohn Marino // concept requirements 5280*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 5281*e4b17023SJohn Marino _ForwardIterator>) 5282*e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 5283*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 5284*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5285*e4b17023SJohn Marino 5286*e4b17023SJohn Marino return std::__partition(__first, __last, __pred, 5287*e4b17023SJohn Marino std::__iterator_category(__first)); 5288*e4b17023SJohn Marino } 5289*e4b17023SJohn Marino 5290*e4b17023SJohn Marino 5291*e4b17023SJohn Marino 5292*e4b17023SJohn Marino /** 5293*e4b17023SJohn Marino * @brief Sort the smallest elements of a sequence. 5294*e4b17023SJohn Marino * @ingroup sorting_algorithms 5295*e4b17023SJohn Marino * @param __first An iterator. 5296*e4b17023SJohn Marino * @param __middle Another iterator. 5297*e4b17023SJohn Marino * @param __last Another iterator. 5298*e4b17023SJohn Marino * @return Nothing. 5299*e4b17023SJohn Marino * 5300*e4b17023SJohn Marino * Sorts the smallest @p (__middle-__first) elements in the range 5301*e4b17023SJohn Marino * @p [first,last) and moves them to the range @p [__first,__middle). The 5302*e4b17023SJohn Marino * order of the remaining elements in the range @p [__middle,__last) is 5303*e4b17023SJohn Marino * undefined. 5304*e4b17023SJohn Marino * After the sort if @e i and @e j are iterators in the range 5305*e4b17023SJohn Marino * @p [__first,__middle) such that i precedes j and @e k is an iterator in 5306*e4b17023SJohn Marino * the range @p [__middle,__last) then *j<*i and *k<*i are both false. 5307*e4b17023SJohn Marino */ 5308*e4b17023SJohn Marino template<typename _RandomAccessIterator> 5309*e4b17023SJohn Marino inline void 5310*e4b17023SJohn Marino partial_sort(_RandomAccessIterator __first, 5311*e4b17023SJohn Marino _RandomAccessIterator __middle, 5312*e4b17023SJohn Marino _RandomAccessIterator __last) 5313*e4b17023SJohn Marino { 5314*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 5315*e4b17023SJohn Marino _ValueType; 5316*e4b17023SJohn Marino 5317*e4b17023SJohn Marino // concept requirements 5318*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 5319*e4b17023SJohn Marino _RandomAccessIterator>) 5320*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 5321*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __middle); 5322*e4b17023SJohn Marino __glibcxx_requires_valid_range(__middle, __last); 5323*e4b17023SJohn Marino 5324*e4b17023SJohn Marino std::__heap_select(__first, __middle, __last); 5325*e4b17023SJohn Marino std::sort_heap(__first, __middle); 5326*e4b17023SJohn Marino } 5327*e4b17023SJohn Marino 5328*e4b17023SJohn Marino /** 5329*e4b17023SJohn Marino * @brief Sort the smallest elements of a sequence using a predicate 5330*e4b17023SJohn Marino * for comparison. 5331*e4b17023SJohn Marino * @ingroup sorting_algorithms 5332*e4b17023SJohn Marino * @param __first An iterator. 5333*e4b17023SJohn Marino * @param __middle Another iterator. 5334*e4b17023SJohn Marino * @param __last Another iterator. 5335*e4b17023SJohn Marino * @param __comp A comparison functor. 5336*e4b17023SJohn Marino * @return Nothing. 5337*e4b17023SJohn Marino * 5338*e4b17023SJohn Marino * Sorts the smallest @p (__middle-__first) elements in the range 5339*e4b17023SJohn Marino * @p [__first,__last) and moves them to the range @p [__first,__middle). The 5340*e4b17023SJohn Marino * order of the remaining elements in the range @p [__middle,__last) is 5341*e4b17023SJohn Marino * undefined. 5342*e4b17023SJohn Marino * After the sort if @e i and @e j are iterators in the range 5343*e4b17023SJohn Marino * @p [__first,__middle) such that i precedes j and @e k is an iterator in 5344*e4b17023SJohn Marino * the range @p [__middle,__last) then @p *__comp(j,*i) and @p __comp(*k,*i) 5345*e4b17023SJohn Marino * are both false. 5346*e4b17023SJohn Marino */ 5347*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare> 5348*e4b17023SJohn Marino inline void 5349*e4b17023SJohn Marino partial_sort(_RandomAccessIterator __first, 5350*e4b17023SJohn Marino _RandomAccessIterator __middle, 5351*e4b17023SJohn Marino _RandomAccessIterator __last, 5352*e4b17023SJohn Marino _Compare __comp) 5353*e4b17023SJohn Marino { 5354*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 5355*e4b17023SJohn Marino _ValueType; 5356*e4b17023SJohn Marino 5357*e4b17023SJohn Marino // concept requirements 5358*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 5359*e4b17023SJohn Marino _RandomAccessIterator>) 5360*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5361*e4b17023SJohn Marino _ValueType, _ValueType>) 5362*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __middle); 5363*e4b17023SJohn Marino __glibcxx_requires_valid_range(__middle, __last); 5364*e4b17023SJohn Marino 5365*e4b17023SJohn Marino std::__heap_select(__first, __middle, __last, __comp); 5366*e4b17023SJohn Marino std::sort_heap(__first, __middle, __comp); 5367*e4b17023SJohn Marino } 5368*e4b17023SJohn Marino 5369*e4b17023SJohn Marino /** 5370*e4b17023SJohn Marino * @brief Sort a sequence just enough to find a particular position. 5371*e4b17023SJohn Marino * @ingroup sorting_algorithms 5372*e4b17023SJohn Marino * @param __first An iterator. 5373*e4b17023SJohn Marino * @param __nth Another iterator. 5374*e4b17023SJohn Marino * @param __last Another iterator. 5375*e4b17023SJohn Marino * @return Nothing. 5376*e4b17023SJohn Marino * 5377*e4b17023SJohn Marino * Rearranges the elements in the range @p [__first,__last) so that @p *__nth 5378*e4b17023SJohn Marino * is the same element that would have been in that position had the 5379*e4b17023SJohn Marino * whole sequence been sorted. The elements either side of @p *__nth are 5380*e4b17023SJohn Marino * not completely sorted, but for any iterator @e i in the range 5381*e4b17023SJohn Marino * @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it 5382*e4b17023SJohn Marino * holds that *j < *i is false. 5383*e4b17023SJohn Marino */ 5384*e4b17023SJohn Marino template<typename _RandomAccessIterator> 5385*e4b17023SJohn Marino inline void 5386*e4b17023SJohn Marino nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, 5387*e4b17023SJohn Marino _RandomAccessIterator __last) 5388*e4b17023SJohn Marino { 5389*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 5390*e4b17023SJohn Marino _ValueType; 5391*e4b17023SJohn Marino 5392*e4b17023SJohn Marino // concept requirements 5393*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 5394*e4b17023SJohn Marino _RandomAccessIterator>) 5395*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 5396*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __nth); 5397*e4b17023SJohn Marino __glibcxx_requires_valid_range(__nth, __last); 5398*e4b17023SJohn Marino 5399*e4b17023SJohn Marino if (__first == __last || __nth == __last) 5400*e4b17023SJohn Marino return; 5401*e4b17023SJohn Marino 5402*e4b17023SJohn Marino std::__introselect(__first, __nth, __last, 5403*e4b17023SJohn Marino std::__lg(__last - __first) * 2); 5404*e4b17023SJohn Marino } 5405*e4b17023SJohn Marino 5406*e4b17023SJohn Marino /** 5407*e4b17023SJohn Marino * @brief Sort a sequence just enough to find a particular position 5408*e4b17023SJohn Marino * using a predicate for comparison. 5409*e4b17023SJohn Marino * @ingroup sorting_algorithms 5410*e4b17023SJohn Marino * @param __first An iterator. 5411*e4b17023SJohn Marino * @param __nth Another iterator. 5412*e4b17023SJohn Marino * @param __last Another iterator. 5413*e4b17023SJohn Marino * @param __comp A comparison functor. 5414*e4b17023SJohn Marino * @return Nothing. 5415*e4b17023SJohn Marino * 5416*e4b17023SJohn Marino * Rearranges the elements in the range @p [__first,__last) so that @p *__nth 5417*e4b17023SJohn Marino * is the same element that would have been in that position had the 5418*e4b17023SJohn Marino * whole sequence been sorted. The elements either side of @p *__nth are 5419*e4b17023SJohn Marino * not completely sorted, but for any iterator @e i in the range 5420*e4b17023SJohn Marino * @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it 5421*e4b17023SJohn Marino * holds that @p __comp(*j,*i) is false. 5422*e4b17023SJohn Marino */ 5423*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare> 5424*e4b17023SJohn Marino inline void 5425*e4b17023SJohn Marino nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, 5426*e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp) 5427*e4b17023SJohn Marino { 5428*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 5429*e4b17023SJohn Marino _ValueType; 5430*e4b17023SJohn Marino 5431*e4b17023SJohn Marino // concept requirements 5432*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 5433*e4b17023SJohn Marino _RandomAccessIterator>) 5434*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5435*e4b17023SJohn Marino _ValueType, _ValueType>) 5436*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __nth); 5437*e4b17023SJohn Marino __glibcxx_requires_valid_range(__nth, __last); 5438*e4b17023SJohn Marino 5439*e4b17023SJohn Marino if (__first == __last || __nth == __last) 5440*e4b17023SJohn Marino return; 5441*e4b17023SJohn Marino 5442*e4b17023SJohn Marino std::__introselect(__first, __nth, __last, 5443*e4b17023SJohn Marino std::__lg(__last - __first) * 2, __comp); 5444*e4b17023SJohn Marino } 5445*e4b17023SJohn Marino 5446*e4b17023SJohn Marino 5447*e4b17023SJohn Marino /** 5448*e4b17023SJohn Marino * @brief Sort the elements of a sequence. 5449*e4b17023SJohn Marino * @ingroup sorting_algorithms 5450*e4b17023SJohn Marino * @param __first An iterator. 5451*e4b17023SJohn Marino * @param __last Another iterator. 5452*e4b17023SJohn Marino * @return Nothing. 5453*e4b17023SJohn Marino * 5454*e4b17023SJohn Marino * Sorts the elements in the range @p [__first,__last) in ascending order, 5455*e4b17023SJohn Marino * such that for each iterator @e i in the range @p [__first,__last-1), 5456*e4b17023SJohn Marino * *(i+1)<*i is false. 5457*e4b17023SJohn Marino * 5458*e4b17023SJohn Marino * The relative ordering of equivalent elements is not preserved, use 5459*e4b17023SJohn Marino * @p stable_sort() if this is needed. 5460*e4b17023SJohn Marino */ 5461*e4b17023SJohn Marino template<typename _RandomAccessIterator> 5462*e4b17023SJohn Marino inline void 5463*e4b17023SJohn Marino sort(_RandomAccessIterator __first, _RandomAccessIterator __last) 5464*e4b17023SJohn Marino { 5465*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 5466*e4b17023SJohn Marino _ValueType; 5467*e4b17023SJohn Marino 5468*e4b17023SJohn Marino // concept requirements 5469*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 5470*e4b17023SJohn Marino _RandomAccessIterator>) 5471*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 5472*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5473*e4b17023SJohn Marino 5474*e4b17023SJohn Marino if (__first != __last) 5475*e4b17023SJohn Marino { 5476*e4b17023SJohn Marino std::__introsort_loop(__first, __last, 5477*e4b17023SJohn Marino std::__lg(__last - __first) * 2); 5478*e4b17023SJohn Marino std::__final_insertion_sort(__first, __last); 5479*e4b17023SJohn Marino } 5480*e4b17023SJohn Marino } 5481*e4b17023SJohn Marino 5482*e4b17023SJohn Marino /** 5483*e4b17023SJohn Marino * @brief Sort the elements of a sequence using a predicate for comparison. 5484*e4b17023SJohn Marino * @ingroup sorting_algorithms 5485*e4b17023SJohn Marino * @param __first An iterator. 5486*e4b17023SJohn Marino * @param __last Another iterator. 5487*e4b17023SJohn Marino * @param __comp A comparison functor. 5488*e4b17023SJohn Marino * @return Nothing. 5489*e4b17023SJohn Marino * 5490*e4b17023SJohn Marino * Sorts the elements in the range @p [__first,__last) in ascending order, 5491*e4b17023SJohn Marino * such that @p __comp(*(i+1),*i) is false for every iterator @e i in the 5492*e4b17023SJohn Marino * range @p [__first,__last-1). 5493*e4b17023SJohn Marino * 5494*e4b17023SJohn Marino * The relative ordering of equivalent elements is not preserved, use 5495*e4b17023SJohn Marino * @p stable_sort() if this is needed. 5496*e4b17023SJohn Marino */ 5497*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare> 5498*e4b17023SJohn Marino inline void 5499*e4b17023SJohn Marino sort(_RandomAccessIterator __first, _RandomAccessIterator __last, 5500*e4b17023SJohn Marino _Compare __comp) 5501*e4b17023SJohn Marino { 5502*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 5503*e4b17023SJohn Marino _ValueType; 5504*e4b17023SJohn Marino 5505*e4b17023SJohn Marino // concept requirements 5506*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 5507*e4b17023SJohn Marino _RandomAccessIterator>) 5508*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, 5509*e4b17023SJohn Marino _ValueType>) 5510*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5511*e4b17023SJohn Marino 5512*e4b17023SJohn Marino if (__first != __last) 5513*e4b17023SJohn Marino { 5514*e4b17023SJohn Marino std::__introsort_loop(__first, __last, 5515*e4b17023SJohn Marino std::__lg(__last - __first) * 2, __comp); 5516*e4b17023SJohn Marino std::__final_insertion_sort(__first, __last, __comp); 5517*e4b17023SJohn Marino } 5518*e4b17023SJohn Marino } 5519*e4b17023SJohn Marino 5520*e4b17023SJohn Marino /** 5521*e4b17023SJohn Marino * @brief Merges two sorted ranges. 5522*e4b17023SJohn Marino * @ingroup sorting_algorithms 5523*e4b17023SJohn Marino * @param __first1 An iterator. 5524*e4b17023SJohn Marino * @param __first2 Another iterator. 5525*e4b17023SJohn Marino * @param __last1 Another iterator. 5526*e4b17023SJohn Marino * @param __last2 Another iterator. 5527*e4b17023SJohn Marino * @param __result An iterator pointing to the end of the merged range. 5528*e4b17023SJohn Marino * @return An iterator pointing to the first element <em>not less 5529*e4b17023SJohn Marino * than</em> @e val. 5530*e4b17023SJohn Marino * 5531*e4b17023SJohn Marino * Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into 5532*e4b17023SJohn Marino * the sorted range @p [__result, __result + (__last1-__first1) + 5533*e4b17023SJohn Marino * (__last2-__first2)). Both input ranges must be sorted, and the 5534*e4b17023SJohn Marino * output range must not overlap with either of the input ranges. 5535*e4b17023SJohn Marino * The sort is @e stable, that is, for equivalent elements in the 5536*e4b17023SJohn Marino * two ranges, elements from the first range will always come 5537*e4b17023SJohn Marino * before elements from the second. 5538*e4b17023SJohn Marino */ 5539*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 5540*e4b17023SJohn Marino typename _OutputIterator> 5541*e4b17023SJohn Marino _OutputIterator 5542*e4b17023SJohn Marino merge(_InputIterator1 __first1, _InputIterator1 __last1, 5543*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 5544*e4b17023SJohn Marino _OutputIterator __result) 5545*e4b17023SJohn Marino { 5546*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 5547*e4b17023SJohn Marino _ValueType1; 5548*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 5549*e4b17023SJohn Marino _ValueType2; 5550*e4b17023SJohn Marino 5551*e4b17023SJohn Marino // concept requirements 5552*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5553*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5554*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5555*e4b17023SJohn Marino _ValueType1>) 5556*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5557*e4b17023SJohn Marino _ValueType2>) 5558*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 5559*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2); 5560*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1); 5561*e4b17023SJohn Marino 5562*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 5563*e4b17023SJohn Marino { 5564*e4b17023SJohn Marino if (*__first2 < *__first1) 5565*e4b17023SJohn Marino { 5566*e4b17023SJohn Marino *__result = *__first2; 5567*e4b17023SJohn Marino ++__first2; 5568*e4b17023SJohn Marino } 5569*e4b17023SJohn Marino else 5570*e4b17023SJohn Marino { 5571*e4b17023SJohn Marino *__result = *__first1; 5572*e4b17023SJohn Marino ++__first1; 5573*e4b17023SJohn Marino } 5574*e4b17023SJohn Marino ++__result; 5575*e4b17023SJohn Marino } 5576*e4b17023SJohn Marino return std::copy(__first2, __last2, std::copy(__first1, __last1, 5577*e4b17023SJohn Marino __result)); 5578*e4b17023SJohn Marino } 5579*e4b17023SJohn Marino 5580*e4b17023SJohn Marino /** 5581*e4b17023SJohn Marino * @brief Merges two sorted ranges. 5582*e4b17023SJohn Marino * @ingroup sorting_algorithms 5583*e4b17023SJohn Marino * @param __first1 An iterator. 5584*e4b17023SJohn Marino * @param __first2 Another iterator. 5585*e4b17023SJohn Marino * @param __last1 Another iterator. 5586*e4b17023SJohn Marino * @param __last2 Another iterator. 5587*e4b17023SJohn Marino * @param __result An iterator pointing to the end of the merged range. 5588*e4b17023SJohn Marino * @param __comp A functor to use for comparisons. 5589*e4b17023SJohn Marino * @return An iterator pointing to the first element "not less 5590*e4b17023SJohn Marino * than" @e val. 5591*e4b17023SJohn Marino * 5592*e4b17023SJohn Marino * Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into 5593*e4b17023SJohn Marino * the sorted range @p [__result, __result + (__last1-__first1) + 5594*e4b17023SJohn Marino * (__last2-__first2)). Both input ranges must be sorted, and the 5595*e4b17023SJohn Marino * output range must not overlap with either of the input ranges. 5596*e4b17023SJohn Marino * The sort is @e stable, that is, for equivalent elements in the 5597*e4b17023SJohn Marino * two ranges, elements from the first range will always come 5598*e4b17023SJohn Marino * before elements from the second. 5599*e4b17023SJohn Marino * 5600*e4b17023SJohn Marino * The comparison function should have the same effects on ordering as 5601*e4b17023SJohn Marino * the function used for the initial sort. 5602*e4b17023SJohn Marino */ 5603*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 5604*e4b17023SJohn Marino typename _OutputIterator, typename _Compare> 5605*e4b17023SJohn Marino _OutputIterator 5606*e4b17023SJohn Marino merge(_InputIterator1 __first1, _InputIterator1 __last1, 5607*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 5608*e4b17023SJohn Marino _OutputIterator __result, _Compare __comp) 5609*e4b17023SJohn Marino { 5610*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 5611*e4b17023SJohn Marino _ValueType1; 5612*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 5613*e4b17023SJohn Marino _ValueType2; 5614*e4b17023SJohn Marino 5615*e4b17023SJohn Marino // concept requirements 5616*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5617*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5618*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5619*e4b17023SJohn Marino _ValueType1>) 5620*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5621*e4b17023SJohn Marino _ValueType2>) 5622*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5623*e4b17023SJohn Marino _ValueType2, _ValueType1>) 5624*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 5625*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 5626*e4b17023SJohn Marino 5627*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 5628*e4b17023SJohn Marino { 5629*e4b17023SJohn Marino if (__comp(*__first2, *__first1)) 5630*e4b17023SJohn Marino { 5631*e4b17023SJohn Marino *__result = *__first2; 5632*e4b17023SJohn Marino ++__first2; 5633*e4b17023SJohn Marino } 5634*e4b17023SJohn Marino else 5635*e4b17023SJohn Marino { 5636*e4b17023SJohn Marino *__result = *__first1; 5637*e4b17023SJohn Marino ++__first1; 5638*e4b17023SJohn Marino } 5639*e4b17023SJohn Marino ++__result; 5640*e4b17023SJohn Marino } 5641*e4b17023SJohn Marino return std::copy(__first2, __last2, std::copy(__first1, __last1, 5642*e4b17023SJohn Marino __result)); 5643*e4b17023SJohn Marino } 5644*e4b17023SJohn Marino 5645*e4b17023SJohn Marino 5646*e4b17023SJohn Marino /** 5647*e4b17023SJohn Marino * @brief Sort the elements of a sequence, preserving the relative order 5648*e4b17023SJohn Marino * of equivalent elements. 5649*e4b17023SJohn Marino * @ingroup sorting_algorithms 5650*e4b17023SJohn Marino * @param __first An iterator. 5651*e4b17023SJohn Marino * @param __last Another iterator. 5652*e4b17023SJohn Marino * @return Nothing. 5653*e4b17023SJohn Marino * 5654*e4b17023SJohn Marino * Sorts the elements in the range @p [__first,__last) in ascending order, 5655*e4b17023SJohn Marino * such that for each iterator @p i in the range @p [__first,__last-1), 5656*e4b17023SJohn Marino * @p *(i+1)<*i is false. 5657*e4b17023SJohn Marino * 5658*e4b17023SJohn Marino * The relative ordering of equivalent elements is preserved, so any two 5659*e4b17023SJohn Marino * elements @p x and @p y in the range @p [__first,__last) such that 5660*e4b17023SJohn Marino * @p x<y is false and @p y<x is false will have the same relative 5661*e4b17023SJohn Marino * ordering after calling @p stable_sort(). 5662*e4b17023SJohn Marino */ 5663*e4b17023SJohn Marino template<typename _RandomAccessIterator> 5664*e4b17023SJohn Marino inline void 5665*e4b17023SJohn Marino stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) 5666*e4b17023SJohn Marino { 5667*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 5668*e4b17023SJohn Marino _ValueType; 5669*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type 5670*e4b17023SJohn Marino _DistanceType; 5671*e4b17023SJohn Marino 5672*e4b17023SJohn Marino // concept requirements 5673*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 5674*e4b17023SJohn Marino _RandomAccessIterator>) 5675*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 5676*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5677*e4b17023SJohn Marino 5678*e4b17023SJohn Marino _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first, 5679*e4b17023SJohn Marino __last); 5680*e4b17023SJohn Marino if (__buf.begin() == 0) 5681*e4b17023SJohn Marino std::__inplace_stable_sort(__first, __last); 5682*e4b17023SJohn Marino else 5683*e4b17023SJohn Marino std::__stable_sort_adaptive(__first, __last, __buf.begin(), 5684*e4b17023SJohn Marino _DistanceType(__buf.size())); 5685*e4b17023SJohn Marino } 5686*e4b17023SJohn Marino 5687*e4b17023SJohn Marino /** 5688*e4b17023SJohn Marino * @brief Sort the elements of a sequence using a predicate for comparison, 5689*e4b17023SJohn Marino * preserving the relative order of equivalent elements. 5690*e4b17023SJohn Marino * @ingroup sorting_algorithms 5691*e4b17023SJohn Marino * @param __first An iterator. 5692*e4b17023SJohn Marino * @param __last Another iterator. 5693*e4b17023SJohn Marino * @param __comp A comparison functor. 5694*e4b17023SJohn Marino * @return Nothing. 5695*e4b17023SJohn Marino * 5696*e4b17023SJohn Marino * Sorts the elements in the range @p [__first,__last) in ascending order, 5697*e4b17023SJohn Marino * such that for each iterator @p i in the range @p [__first,__last-1), 5698*e4b17023SJohn Marino * @p __comp(*(i+1),*i) is false. 5699*e4b17023SJohn Marino * 5700*e4b17023SJohn Marino * The relative ordering of equivalent elements is preserved, so any two 5701*e4b17023SJohn Marino * elements @p x and @p y in the range @p [__first,__last) such that 5702*e4b17023SJohn Marino * @p __comp(x,y) is false and @p __comp(y,x) is false will have the same 5703*e4b17023SJohn Marino * relative ordering after calling @p stable_sort(). 5704*e4b17023SJohn Marino */ 5705*e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare> 5706*e4b17023SJohn Marino inline void 5707*e4b17023SJohn Marino stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, 5708*e4b17023SJohn Marino _Compare __comp) 5709*e4b17023SJohn Marino { 5710*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type 5711*e4b17023SJohn Marino _ValueType; 5712*e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type 5713*e4b17023SJohn Marino _DistanceType; 5714*e4b17023SJohn Marino 5715*e4b17023SJohn Marino // concept requirements 5716*e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 5717*e4b17023SJohn Marino _RandomAccessIterator>) 5718*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5719*e4b17023SJohn Marino _ValueType, 5720*e4b17023SJohn Marino _ValueType>) 5721*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 5722*e4b17023SJohn Marino 5723*e4b17023SJohn Marino _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first, 5724*e4b17023SJohn Marino __last); 5725*e4b17023SJohn Marino if (__buf.begin() == 0) 5726*e4b17023SJohn Marino std::__inplace_stable_sort(__first, __last, __comp); 5727*e4b17023SJohn Marino else 5728*e4b17023SJohn Marino std::__stable_sort_adaptive(__first, __last, __buf.begin(), 5729*e4b17023SJohn Marino _DistanceType(__buf.size()), __comp); 5730*e4b17023SJohn Marino } 5731*e4b17023SJohn Marino 5732*e4b17023SJohn Marino 5733*e4b17023SJohn Marino /** 5734*e4b17023SJohn Marino * @brief Return the union of two sorted ranges. 5735*e4b17023SJohn Marino * @ingroup set_algorithms 5736*e4b17023SJohn Marino * @param __first1 Start of first range. 5737*e4b17023SJohn Marino * @param __last1 End of first range. 5738*e4b17023SJohn Marino * @param __first2 Start of second range. 5739*e4b17023SJohn Marino * @param __last2 End of second range. 5740*e4b17023SJohn Marino * @return End of the output range. 5741*e4b17023SJohn Marino * @ingroup set_algorithms 5742*e4b17023SJohn Marino * 5743*e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in 5744*e4b17023SJohn Marino * each range in order to the output range. Iterators increment for each 5745*e4b17023SJohn Marino * range. When the current element of one range is less than the other, 5746*e4b17023SJohn Marino * that element is copied and the iterator advanced. If an element is 5747*e4b17023SJohn Marino * contained in both ranges, the element from the first range is copied and 5748*e4b17023SJohn Marino * both ranges advance. The output range may not overlap either input 5749*e4b17023SJohn Marino * range. 5750*e4b17023SJohn Marino */ 5751*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 5752*e4b17023SJohn Marino typename _OutputIterator> 5753*e4b17023SJohn Marino _OutputIterator 5754*e4b17023SJohn Marino set_union(_InputIterator1 __first1, _InputIterator1 __last1, 5755*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 5756*e4b17023SJohn Marino _OutputIterator __result) 5757*e4b17023SJohn Marino { 5758*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 5759*e4b17023SJohn Marino _ValueType1; 5760*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 5761*e4b17023SJohn Marino _ValueType2; 5762*e4b17023SJohn Marino 5763*e4b17023SJohn Marino // concept requirements 5764*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5765*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5766*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5767*e4b17023SJohn Marino _ValueType1>) 5768*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5769*e4b17023SJohn Marino _ValueType2>) 5770*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) 5771*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 5772*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2); 5773*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1); 5774*e4b17023SJohn Marino 5775*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 5776*e4b17023SJohn Marino { 5777*e4b17023SJohn Marino if (*__first1 < *__first2) 5778*e4b17023SJohn Marino { 5779*e4b17023SJohn Marino *__result = *__first1; 5780*e4b17023SJohn Marino ++__first1; 5781*e4b17023SJohn Marino } 5782*e4b17023SJohn Marino else if (*__first2 < *__first1) 5783*e4b17023SJohn Marino { 5784*e4b17023SJohn Marino *__result = *__first2; 5785*e4b17023SJohn Marino ++__first2; 5786*e4b17023SJohn Marino } 5787*e4b17023SJohn Marino else 5788*e4b17023SJohn Marino { 5789*e4b17023SJohn Marino *__result = *__first1; 5790*e4b17023SJohn Marino ++__first1; 5791*e4b17023SJohn Marino ++__first2; 5792*e4b17023SJohn Marino } 5793*e4b17023SJohn Marino ++__result; 5794*e4b17023SJohn Marino } 5795*e4b17023SJohn Marino return std::copy(__first2, __last2, std::copy(__first1, __last1, 5796*e4b17023SJohn Marino __result)); 5797*e4b17023SJohn Marino } 5798*e4b17023SJohn Marino 5799*e4b17023SJohn Marino /** 5800*e4b17023SJohn Marino * @brief Return the union of two sorted ranges using a comparison functor. 5801*e4b17023SJohn Marino * @ingroup set_algorithms 5802*e4b17023SJohn Marino * @param __first1 Start of first range. 5803*e4b17023SJohn Marino * @param __last1 End of first range. 5804*e4b17023SJohn Marino * @param __first2 Start of second range. 5805*e4b17023SJohn Marino * @param __last2 End of second range. 5806*e4b17023SJohn Marino * @param __comp The comparison functor. 5807*e4b17023SJohn Marino * @return End of the output range. 5808*e4b17023SJohn Marino * @ingroup set_algorithms 5809*e4b17023SJohn Marino * 5810*e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in 5811*e4b17023SJohn Marino * each range in order to the output range. Iterators increment for each 5812*e4b17023SJohn Marino * range. When the current element of one range is less than the other 5813*e4b17023SJohn Marino * according to @p __comp, that element is copied and the iterator advanced. 5814*e4b17023SJohn Marino * If an equivalent element according to @p __comp is contained in both 5815*e4b17023SJohn Marino * ranges, the element from the first range is copied and both ranges 5816*e4b17023SJohn Marino * advance. The output range may not overlap either input range. 5817*e4b17023SJohn Marino */ 5818*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 5819*e4b17023SJohn Marino typename _OutputIterator, typename _Compare> 5820*e4b17023SJohn Marino _OutputIterator 5821*e4b17023SJohn Marino set_union(_InputIterator1 __first1, _InputIterator1 __last1, 5822*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 5823*e4b17023SJohn Marino _OutputIterator __result, _Compare __comp) 5824*e4b17023SJohn Marino { 5825*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 5826*e4b17023SJohn Marino _ValueType1; 5827*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 5828*e4b17023SJohn Marino _ValueType2; 5829*e4b17023SJohn Marino 5830*e4b17023SJohn Marino // concept requirements 5831*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5832*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5833*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5834*e4b17023SJohn Marino _ValueType1>) 5835*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5836*e4b17023SJohn Marino _ValueType2>) 5837*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5838*e4b17023SJohn Marino _ValueType1, _ValueType2>) 5839*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5840*e4b17023SJohn Marino _ValueType2, _ValueType1>) 5841*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 5842*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 5843*e4b17023SJohn Marino 5844*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 5845*e4b17023SJohn Marino { 5846*e4b17023SJohn Marino if (__comp(*__first1, *__first2)) 5847*e4b17023SJohn Marino { 5848*e4b17023SJohn Marino *__result = *__first1; 5849*e4b17023SJohn Marino ++__first1; 5850*e4b17023SJohn Marino } 5851*e4b17023SJohn Marino else if (__comp(*__first2, *__first1)) 5852*e4b17023SJohn Marino { 5853*e4b17023SJohn Marino *__result = *__first2; 5854*e4b17023SJohn Marino ++__first2; 5855*e4b17023SJohn Marino } 5856*e4b17023SJohn Marino else 5857*e4b17023SJohn Marino { 5858*e4b17023SJohn Marino *__result = *__first1; 5859*e4b17023SJohn Marino ++__first1; 5860*e4b17023SJohn Marino ++__first2; 5861*e4b17023SJohn Marino } 5862*e4b17023SJohn Marino ++__result; 5863*e4b17023SJohn Marino } 5864*e4b17023SJohn Marino return std::copy(__first2, __last2, std::copy(__first1, __last1, 5865*e4b17023SJohn Marino __result)); 5866*e4b17023SJohn Marino } 5867*e4b17023SJohn Marino 5868*e4b17023SJohn Marino /** 5869*e4b17023SJohn Marino * @brief Return the intersection of two sorted ranges. 5870*e4b17023SJohn Marino * @ingroup set_algorithms 5871*e4b17023SJohn Marino * @param __first1 Start of first range. 5872*e4b17023SJohn Marino * @param __last1 End of first range. 5873*e4b17023SJohn Marino * @param __first2 Start of second range. 5874*e4b17023SJohn Marino * @param __last2 End of second range. 5875*e4b17023SJohn Marino * @return End of the output range. 5876*e4b17023SJohn Marino * @ingroup set_algorithms 5877*e4b17023SJohn Marino * 5878*e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in 5879*e4b17023SJohn Marino * both ranges in order to the output range. Iterators increment for each 5880*e4b17023SJohn Marino * range. When the current element of one range is less than the other, 5881*e4b17023SJohn Marino * that iterator advances. If an element is contained in both ranges, the 5882*e4b17023SJohn Marino * element from the first range is copied and both ranges advance. The 5883*e4b17023SJohn Marino * output range may not overlap either input range. 5884*e4b17023SJohn Marino */ 5885*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 5886*e4b17023SJohn Marino typename _OutputIterator> 5887*e4b17023SJohn Marino _OutputIterator 5888*e4b17023SJohn Marino set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 5889*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 5890*e4b17023SJohn Marino _OutputIterator __result) 5891*e4b17023SJohn Marino { 5892*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 5893*e4b17023SJohn Marino _ValueType1; 5894*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 5895*e4b17023SJohn Marino _ValueType2; 5896*e4b17023SJohn Marino 5897*e4b17023SJohn Marino // concept requirements 5898*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5899*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5900*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5901*e4b17023SJohn Marino _ValueType1>) 5902*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) 5903*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 5904*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2); 5905*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1); 5906*e4b17023SJohn Marino 5907*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 5908*e4b17023SJohn Marino if (*__first1 < *__first2) 5909*e4b17023SJohn Marino ++__first1; 5910*e4b17023SJohn Marino else if (*__first2 < *__first1) 5911*e4b17023SJohn Marino ++__first2; 5912*e4b17023SJohn Marino else 5913*e4b17023SJohn Marino { 5914*e4b17023SJohn Marino *__result = *__first1; 5915*e4b17023SJohn Marino ++__first1; 5916*e4b17023SJohn Marino ++__first2; 5917*e4b17023SJohn Marino ++__result; 5918*e4b17023SJohn Marino } 5919*e4b17023SJohn Marino return __result; 5920*e4b17023SJohn Marino } 5921*e4b17023SJohn Marino 5922*e4b17023SJohn Marino /** 5923*e4b17023SJohn Marino * @brief Return the intersection of two sorted ranges using comparison 5924*e4b17023SJohn Marino * functor. 5925*e4b17023SJohn Marino * @ingroup set_algorithms 5926*e4b17023SJohn Marino * @param __first1 Start of first range. 5927*e4b17023SJohn Marino * @param __last1 End of first range. 5928*e4b17023SJohn Marino * @param __first2 Start of second range. 5929*e4b17023SJohn Marino * @param __last2 End of second range. 5930*e4b17023SJohn Marino * @param __comp The comparison functor. 5931*e4b17023SJohn Marino * @return End of the output range. 5932*e4b17023SJohn Marino * @ingroup set_algorithms 5933*e4b17023SJohn Marino * 5934*e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in 5935*e4b17023SJohn Marino * both ranges in order to the output range. Iterators increment for each 5936*e4b17023SJohn Marino * range. When the current element of one range is less than the other 5937*e4b17023SJohn Marino * according to @p __comp, that iterator advances. If an element is 5938*e4b17023SJohn Marino * contained in both ranges according to @p __comp, the element from the 5939*e4b17023SJohn Marino * first range is copied and both ranges advance. The output range may not 5940*e4b17023SJohn Marino * overlap either input range. 5941*e4b17023SJohn Marino */ 5942*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 5943*e4b17023SJohn Marino typename _OutputIterator, typename _Compare> 5944*e4b17023SJohn Marino _OutputIterator 5945*e4b17023SJohn Marino set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 5946*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 5947*e4b17023SJohn Marino _OutputIterator __result, _Compare __comp) 5948*e4b17023SJohn Marino { 5949*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 5950*e4b17023SJohn Marino _ValueType1; 5951*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 5952*e4b17023SJohn Marino _ValueType2; 5953*e4b17023SJohn Marino 5954*e4b17023SJohn Marino // concept requirements 5955*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5956*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5957*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5958*e4b17023SJohn Marino _ValueType1>) 5959*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5960*e4b17023SJohn Marino _ValueType1, _ValueType2>) 5961*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5962*e4b17023SJohn Marino _ValueType2, _ValueType1>) 5963*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 5964*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 5965*e4b17023SJohn Marino 5966*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 5967*e4b17023SJohn Marino if (__comp(*__first1, *__first2)) 5968*e4b17023SJohn Marino ++__first1; 5969*e4b17023SJohn Marino else if (__comp(*__first2, *__first1)) 5970*e4b17023SJohn Marino ++__first2; 5971*e4b17023SJohn Marino else 5972*e4b17023SJohn Marino { 5973*e4b17023SJohn Marino *__result = *__first1; 5974*e4b17023SJohn Marino ++__first1; 5975*e4b17023SJohn Marino ++__first2; 5976*e4b17023SJohn Marino ++__result; 5977*e4b17023SJohn Marino } 5978*e4b17023SJohn Marino return __result; 5979*e4b17023SJohn Marino } 5980*e4b17023SJohn Marino 5981*e4b17023SJohn Marino /** 5982*e4b17023SJohn Marino * @brief Return the difference of two sorted ranges. 5983*e4b17023SJohn Marino * @ingroup set_algorithms 5984*e4b17023SJohn Marino * @param __first1 Start of first range. 5985*e4b17023SJohn Marino * @param __last1 End of first range. 5986*e4b17023SJohn Marino * @param __first2 Start of second range. 5987*e4b17023SJohn Marino * @param __last2 End of second range. 5988*e4b17023SJohn Marino * @return End of the output range. 5989*e4b17023SJohn Marino * @ingroup set_algorithms 5990*e4b17023SJohn Marino * 5991*e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in 5992*e4b17023SJohn Marino * the first range but not the second in order to the output range. 5993*e4b17023SJohn Marino * Iterators increment for each range. When the current element of the 5994*e4b17023SJohn Marino * first range is less than the second, that element is copied and the 5995*e4b17023SJohn Marino * iterator advances. If the current element of the second range is less, 5996*e4b17023SJohn Marino * the iterator advances, but no element is copied. If an element is 5997*e4b17023SJohn Marino * contained in both ranges, no elements are copied and both ranges 5998*e4b17023SJohn Marino * advance. The output range may not overlap either input range. 5999*e4b17023SJohn Marino */ 6000*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 6001*e4b17023SJohn Marino typename _OutputIterator> 6002*e4b17023SJohn Marino _OutputIterator 6003*e4b17023SJohn Marino set_difference(_InputIterator1 __first1, _InputIterator1 __last1, 6004*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 6005*e4b17023SJohn Marino _OutputIterator __result) 6006*e4b17023SJohn Marino { 6007*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 6008*e4b17023SJohn Marino _ValueType1; 6009*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 6010*e4b17023SJohn Marino _ValueType2; 6011*e4b17023SJohn Marino 6012*e4b17023SJohn Marino // concept requirements 6013*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 6014*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 6015*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 6016*e4b17023SJohn Marino _ValueType1>) 6017*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) 6018*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 6019*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2); 6020*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1); 6021*e4b17023SJohn Marino 6022*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 6023*e4b17023SJohn Marino if (*__first1 < *__first2) 6024*e4b17023SJohn Marino { 6025*e4b17023SJohn Marino *__result = *__first1; 6026*e4b17023SJohn Marino ++__first1; 6027*e4b17023SJohn Marino ++__result; 6028*e4b17023SJohn Marino } 6029*e4b17023SJohn Marino else if (*__first2 < *__first1) 6030*e4b17023SJohn Marino ++__first2; 6031*e4b17023SJohn Marino else 6032*e4b17023SJohn Marino { 6033*e4b17023SJohn Marino ++__first1; 6034*e4b17023SJohn Marino ++__first2; 6035*e4b17023SJohn Marino } 6036*e4b17023SJohn Marino return std::copy(__first1, __last1, __result); 6037*e4b17023SJohn Marino } 6038*e4b17023SJohn Marino 6039*e4b17023SJohn Marino /** 6040*e4b17023SJohn Marino * @brief Return the difference of two sorted ranges using comparison 6041*e4b17023SJohn Marino * functor. 6042*e4b17023SJohn Marino * @ingroup set_algorithms 6043*e4b17023SJohn Marino * @param __first1 Start of first range. 6044*e4b17023SJohn Marino * @param __last1 End of first range. 6045*e4b17023SJohn Marino * @param __first2 Start of second range. 6046*e4b17023SJohn Marino * @param __last2 End of second range. 6047*e4b17023SJohn Marino * @param __comp The comparison functor. 6048*e4b17023SJohn Marino * @return End of the output range. 6049*e4b17023SJohn Marino * @ingroup set_algorithms 6050*e4b17023SJohn Marino * 6051*e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in 6052*e4b17023SJohn Marino * the first range but not the second in order to the output range. 6053*e4b17023SJohn Marino * Iterators increment for each range. When the current element of the 6054*e4b17023SJohn Marino * first range is less than the second according to @p __comp, that element 6055*e4b17023SJohn Marino * is copied and the iterator advances. If the current element of the 6056*e4b17023SJohn Marino * second range is less, no element is copied and the iterator advances. 6057*e4b17023SJohn Marino * If an element is contained in both ranges according to @p __comp, no 6058*e4b17023SJohn Marino * elements are copied and both ranges advance. The output range may not 6059*e4b17023SJohn Marino * overlap either input range. 6060*e4b17023SJohn Marino */ 6061*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 6062*e4b17023SJohn Marino typename _OutputIterator, typename _Compare> 6063*e4b17023SJohn Marino _OutputIterator 6064*e4b17023SJohn Marino set_difference(_InputIterator1 __first1, _InputIterator1 __last1, 6065*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 6066*e4b17023SJohn Marino _OutputIterator __result, _Compare __comp) 6067*e4b17023SJohn Marino { 6068*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 6069*e4b17023SJohn Marino _ValueType1; 6070*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 6071*e4b17023SJohn Marino _ValueType2; 6072*e4b17023SJohn Marino 6073*e4b17023SJohn Marino // concept requirements 6074*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 6075*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 6076*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 6077*e4b17023SJohn Marino _ValueType1>) 6078*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 6079*e4b17023SJohn Marino _ValueType1, _ValueType2>) 6080*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 6081*e4b17023SJohn Marino _ValueType2, _ValueType1>) 6082*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 6083*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 6084*e4b17023SJohn Marino 6085*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 6086*e4b17023SJohn Marino if (__comp(*__first1, *__first2)) 6087*e4b17023SJohn Marino { 6088*e4b17023SJohn Marino *__result = *__first1; 6089*e4b17023SJohn Marino ++__first1; 6090*e4b17023SJohn Marino ++__result; 6091*e4b17023SJohn Marino } 6092*e4b17023SJohn Marino else if (__comp(*__first2, *__first1)) 6093*e4b17023SJohn Marino ++__first2; 6094*e4b17023SJohn Marino else 6095*e4b17023SJohn Marino { 6096*e4b17023SJohn Marino ++__first1; 6097*e4b17023SJohn Marino ++__first2; 6098*e4b17023SJohn Marino } 6099*e4b17023SJohn Marino return std::copy(__first1, __last1, __result); 6100*e4b17023SJohn Marino } 6101*e4b17023SJohn Marino 6102*e4b17023SJohn Marino /** 6103*e4b17023SJohn Marino * @brief Return the symmetric difference of two sorted ranges. 6104*e4b17023SJohn Marino * @ingroup set_algorithms 6105*e4b17023SJohn Marino * @param __first1 Start of first range. 6106*e4b17023SJohn Marino * @param __last1 End of first range. 6107*e4b17023SJohn Marino * @param __first2 Start of second range. 6108*e4b17023SJohn Marino * @param __last2 End of second range. 6109*e4b17023SJohn Marino * @return End of the output range. 6110*e4b17023SJohn Marino * @ingroup set_algorithms 6111*e4b17023SJohn Marino * 6112*e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in 6113*e4b17023SJohn Marino * one range but not the other in order to the output range. Iterators 6114*e4b17023SJohn Marino * increment for each range. When the current element of one range is less 6115*e4b17023SJohn Marino * than the other, that element is copied and the iterator advances. If an 6116*e4b17023SJohn Marino * element is contained in both ranges, no elements are copied and both 6117*e4b17023SJohn Marino * ranges advance. The output range may not overlap either input range. 6118*e4b17023SJohn Marino */ 6119*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 6120*e4b17023SJohn Marino typename _OutputIterator> 6121*e4b17023SJohn Marino _OutputIterator 6122*e4b17023SJohn Marino set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 6123*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 6124*e4b17023SJohn Marino _OutputIterator __result) 6125*e4b17023SJohn Marino { 6126*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 6127*e4b17023SJohn Marino _ValueType1; 6128*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 6129*e4b17023SJohn Marino _ValueType2; 6130*e4b17023SJohn Marino 6131*e4b17023SJohn Marino // concept requirements 6132*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 6133*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 6134*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 6135*e4b17023SJohn Marino _ValueType1>) 6136*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 6137*e4b17023SJohn Marino _ValueType2>) 6138*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) 6139*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 6140*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2); 6141*e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1); 6142*e4b17023SJohn Marino 6143*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 6144*e4b17023SJohn Marino if (*__first1 < *__first2) 6145*e4b17023SJohn Marino { 6146*e4b17023SJohn Marino *__result = *__first1; 6147*e4b17023SJohn Marino ++__first1; 6148*e4b17023SJohn Marino ++__result; 6149*e4b17023SJohn Marino } 6150*e4b17023SJohn Marino else if (*__first2 < *__first1) 6151*e4b17023SJohn Marino { 6152*e4b17023SJohn Marino *__result = *__first2; 6153*e4b17023SJohn Marino ++__first2; 6154*e4b17023SJohn Marino ++__result; 6155*e4b17023SJohn Marino } 6156*e4b17023SJohn Marino else 6157*e4b17023SJohn Marino { 6158*e4b17023SJohn Marino ++__first1; 6159*e4b17023SJohn Marino ++__first2; 6160*e4b17023SJohn Marino } 6161*e4b17023SJohn Marino return std::copy(__first2, __last2, std::copy(__first1, 6162*e4b17023SJohn Marino __last1, __result)); 6163*e4b17023SJohn Marino } 6164*e4b17023SJohn Marino 6165*e4b17023SJohn Marino /** 6166*e4b17023SJohn Marino * @brief Return the symmetric difference of two sorted ranges using 6167*e4b17023SJohn Marino * comparison functor. 6168*e4b17023SJohn Marino * @ingroup set_algorithms 6169*e4b17023SJohn Marino * @param __first1 Start of first range. 6170*e4b17023SJohn Marino * @param __last1 End of first range. 6171*e4b17023SJohn Marino * @param __first2 Start of second range. 6172*e4b17023SJohn Marino * @param __last2 End of second range. 6173*e4b17023SJohn Marino * @param __comp The comparison functor. 6174*e4b17023SJohn Marino * @return End of the output range. 6175*e4b17023SJohn Marino * @ingroup set_algorithms 6176*e4b17023SJohn Marino * 6177*e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in 6178*e4b17023SJohn Marino * one range but not the other in order to the output range. Iterators 6179*e4b17023SJohn Marino * increment for each range. When the current element of one range is less 6180*e4b17023SJohn Marino * than the other according to @p comp, that element is copied and the 6181*e4b17023SJohn Marino * iterator advances. If an element is contained in both ranges according 6182*e4b17023SJohn Marino * to @p __comp, no elements are copied and both ranges advance. The output 6183*e4b17023SJohn Marino * range may not overlap either input range. 6184*e4b17023SJohn Marino */ 6185*e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2, 6186*e4b17023SJohn Marino typename _OutputIterator, typename _Compare> 6187*e4b17023SJohn Marino _OutputIterator 6188*e4b17023SJohn Marino set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 6189*e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2, 6190*e4b17023SJohn Marino _OutputIterator __result, 6191*e4b17023SJohn Marino _Compare __comp) 6192*e4b17023SJohn Marino { 6193*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type 6194*e4b17023SJohn Marino _ValueType1; 6195*e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type 6196*e4b17023SJohn Marino _ValueType2; 6197*e4b17023SJohn Marino 6198*e4b17023SJohn Marino // concept requirements 6199*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 6200*e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 6201*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 6202*e4b17023SJohn Marino _ValueType1>) 6203*e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 6204*e4b17023SJohn Marino _ValueType2>) 6205*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 6206*e4b17023SJohn Marino _ValueType1, _ValueType2>) 6207*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 6208*e4b17023SJohn Marino _ValueType2, _ValueType1>) 6209*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 6210*e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 6211*e4b17023SJohn Marino 6212*e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2) 6213*e4b17023SJohn Marino if (__comp(*__first1, *__first2)) 6214*e4b17023SJohn Marino { 6215*e4b17023SJohn Marino *__result = *__first1; 6216*e4b17023SJohn Marino ++__first1; 6217*e4b17023SJohn Marino ++__result; 6218*e4b17023SJohn Marino } 6219*e4b17023SJohn Marino else if (__comp(*__first2, *__first1)) 6220*e4b17023SJohn Marino { 6221*e4b17023SJohn Marino *__result = *__first2; 6222*e4b17023SJohn Marino ++__first2; 6223*e4b17023SJohn Marino ++__result; 6224*e4b17023SJohn Marino } 6225*e4b17023SJohn Marino else 6226*e4b17023SJohn Marino { 6227*e4b17023SJohn Marino ++__first1; 6228*e4b17023SJohn Marino ++__first2; 6229*e4b17023SJohn Marino } 6230*e4b17023SJohn Marino return std::copy(__first2, __last2, 6231*e4b17023SJohn Marino std::copy(__first1, __last1, __result)); 6232*e4b17023SJohn Marino } 6233*e4b17023SJohn Marino 6234*e4b17023SJohn Marino 6235*e4b17023SJohn Marino /** 6236*e4b17023SJohn Marino * @brief Return the minimum element in a range. 6237*e4b17023SJohn Marino * @ingroup sorting_algorithms 6238*e4b17023SJohn Marino * @param __first Start of range. 6239*e4b17023SJohn Marino * @param __last End of range. 6240*e4b17023SJohn Marino * @return Iterator referencing the first instance of the smallest value. 6241*e4b17023SJohn Marino */ 6242*e4b17023SJohn Marino template<typename _ForwardIterator> 6243*e4b17023SJohn Marino _ForwardIterator 6244*e4b17023SJohn Marino min_element(_ForwardIterator __first, _ForwardIterator __last) 6245*e4b17023SJohn Marino { 6246*e4b17023SJohn Marino // concept requirements 6247*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 6248*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept< 6249*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 6250*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 6251*e4b17023SJohn Marino 6252*e4b17023SJohn Marino if (__first == __last) 6253*e4b17023SJohn Marino return __first; 6254*e4b17023SJohn Marino _ForwardIterator __result = __first; 6255*e4b17023SJohn Marino while (++__first != __last) 6256*e4b17023SJohn Marino if (*__first < *__result) 6257*e4b17023SJohn Marino __result = __first; 6258*e4b17023SJohn Marino return __result; 6259*e4b17023SJohn Marino } 6260*e4b17023SJohn Marino 6261*e4b17023SJohn Marino /** 6262*e4b17023SJohn Marino * @brief Return the minimum element in a range using comparison functor. 6263*e4b17023SJohn Marino * @ingroup sorting_algorithms 6264*e4b17023SJohn Marino * @param __first Start of range. 6265*e4b17023SJohn Marino * @param __last End of range. 6266*e4b17023SJohn Marino * @param __comp Comparison functor. 6267*e4b17023SJohn Marino * @return Iterator referencing the first instance of the smallest value 6268*e4b17023SJohn Marino * according to __comp. 6269*e4b17023SJohn Marino */ 6270*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Compare> 6271*e4b17023SJohn Marino _ForwardIterator 6272*e4b17023SJohn Marino min_element(_ForwardIterator __first, _ForwardIterator __last, 6273*e4b17023SJohn Marino _Compare __comp) 6274*e4b17023SJohn Marino { 6275*e4b17023SJohn Marino // concept requirements 6276*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 6277*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 6278*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, 6279*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 6280*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 6281*e4b17023SJohn Marino 6282*e4b17023SJohn Marino if (__first == __last) 6283*e4b17023SJohn Marino return __first; 6284*e4b17023SJohn Marino _ForwardIterator __result = __first; 6285*e4b17023SJohn Marino while (++__first != __last) 6286*e4b17023SJohn Marino if (__comp(*__first, *__result)) 6287*e4b17023SJohn Marino __result = __first; 6288*e4b17023SJohn Marino return __result; 6289*e4b17023SJohn Marino } 6290*e4b17023SJohn Marino 6291*e4b17023SJohn Marino /** 6292*e4b17023SJohn Marino * @brief Return the maximum element in a range. 6293*e4b17023SJohn Marino * @ingroup sorting_algorithms 6294*e4b17023SJohn Marino * @param __first Start of range. 6295*e4b17023SJohn Marino * @param __last End of range. 6296*e4b17023SJohn Marino * @return Iterator referencing the first instance of the largest value. 6297*e4b17023SJohn Marino */ 6298*e4b17023SJohn Marino template<typename _ForwardIterator> 6299*e4b17023SJohn Marino _ForwardIterator 6300*e4b17023SJohn Marino max_element(_ForwardIterator __first, _ForwardIterator __last) 6301*e4b17023SJohn Marino { 6302*e4b17023SJohn Marino // concept requirements 6303*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 6304*e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept< 6305*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 6306*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 6307*e4b17023SJohn Marino 6308*e4b17023SJohn Marino if (__first == __last) 6309*e4b17023SJohn Marino return __first; 6310*e4b17023SJohn Marino _ForwardIterator __result = __first; 6311*e4b17023SJohn Marino while (++__first != __last) 6312*e4b17023SJohn Marino if (*__result < *__first) 6313*e4b17023SJohn Marino __result = __first; 6314*e4b17023SJohn Marino return __result; 6315*e4b17023SJohn Marino } 6316*e4b17023SJohn Marino 6317*e4b17023SJohn Marino /** 6318*e4b17023SJohn Marino * @brief Return the maximum element in a range using comparison functor. 6319*e4b17023SJohn Marino * @ingroup sorting_algorithms 6320*e4b17023SJohn Marino * @param __first Start of range. 6321*e4b17023SJohn Marino * @param __last End of range. 6322*e4b17023SJohn Marino * @param __comp Comparison functor. 6323*e4b17023SJohn Marino * @return Iterator referencing the first instance of the largest value 6324*e4b17023SJohn Marino * according to __comp. 6325*e4b17023SJohn Marino */ 6326*e4b17023SJohn Marino template<typename _ForwardIterator, typename _Compare> 6327*e4b17023SJohn Marino _ForwardIterator 6328*e4b17023SJohn Marino max_element(_ForwardIterator __first, _ForwardIterator __last, 6329*e4b17023SJohn Marino _Compare __comp) 6330*e4b17023SJohn Marino { 6331*e4b17023SJohn Marino // concept requirements 6332*e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 6333*e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 6334*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, 6335*e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>) 6336*e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last); 6337*e4b17023SJohn Marino 6338*e4b17023SJohn Marino if (__first == __last) return __first; 6339*e4b17023SJohn Marino _ForwardIterator __result = __first; 6340*e4b17023SJohn Marino while (++__first != __last) 6341*e4b17023SJohn Marino if (__comp(*__result, *__first)) 6342*e4b17023SJohn Marino __result = __first; 6343*e4b17023SJohn Marino return __result; 6344*e4b17023SJohn Marino } 6345*e4b17023SJohn Marino 6346*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_ALGO 6347*e4b17023SJohn Marino } // namespace std 6348*e4b17023SJohn Marino 6349*e4b17023SJohn Marino #endif /* _STL_ALGO_H */ 6350