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