1*0b57cec5SDimitry Andric// -*- C++ -*- 2*0b57cec5SDimitry Andric//===-------------------------- algorithm ---------------------------------===// 3*0b57cec5SDimitry Andric// 4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*0b57cec5SDimitry Andric// 8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 9*0b57cec5SDimitry Andric 10*0b57cec5SDimitry Andric#ifndef _LIBCPP_ALGORITHM 11*0b57cec5SDimitry Andric#define _LIBCPP_ALGORITHM 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric/* 14*0b57cec5SDimitry Andric algorithm synopsis 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric#include <initializer_list> 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andricnamespace std 19*0b57cec5SDimitry Andric{ 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 22*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 23*0b57cec5SDimitry Andric all_of(InputIterator first, InputIterator last, Predicate pred); 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 26*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 27*0b57cec5SDimitry Andric any_of(InputIterator first, InputIterator last, Predicate pred); 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 30*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 31*0b57cec5SDimitry Andric none_of(InputIterator first, InputIterator last, Predicate pred); 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andrictemplate <class InputIterator, class Function> 34*0b57cec5SDimitry Andric constexpr Function // constexpr in C++20 35*0b57cec5SDimitry Andric for_each(InputIterator first, InputIterator last, Function f); 36*0b57cec5SDimitry Andric 37*0b57cec5SDimitry Andrictemplate<class InputIterator, class Size, class Function> 38*0b57cec5SDimitry Andric constexpr InputIterator // constexpr in C++20 39*0b57cec5SDimitry Andric for_each_n(InputIterator first, Size n, Function f); // C++17 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andrictemplate <class InputIterator, class T> 42*0b57cec5SDimitry Andric constexpr InputIterator // constexpr in C++20 43*0b57cec5SDimitry Andric find(InputIterator first, InputIterator last, const T& value); 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 46*0b57cec5SDimitry Andric constexpr InputIterator // constexpr in C++20 47*0b57cec5SDimitry Andric find_if(InputIterator first, InputIterator last, Predicate pred); 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andrictemplate<class InputIterator, class Predicate> 50e8d8bef9SDimitry Andric constexpr InputIterator // constexpr in C++20 51*0b57cec5SDimitry Andric find_if_not(InputIterator first, InputIterator last, Predicate pred); 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2> 54e8d8bef9SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 55*0b57cec5SDimitry Andric find_end(ForwardIterator1 first1, ForwardIterator1 last1, 56*0b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2); 57*0b57cec5SDimitry Andric 58*0b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 59e8d8bef9SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 60*0b57cec5SDimitry Andric find_end(ForwardIterator1 first1, ForwardIterator1 last1, 61*0b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2> 64*0b57cec5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 65*0b57cec5SDimitry Andric find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, 66*0b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2); 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 69*0b57cec5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 70*0b57cec5SDimitry Andric find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, 71*0b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andrictemplate <class ForwardIterator> 74*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 75*0b57cec5SDimitry Andric adjacent_find(ForwardIterator first, ForwardIterator last); 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class BinaryPredicate> 78*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 79*0b57cec5SDimitry Andric adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andrictemplate <class InputIterator, class T> 82*0b57cec5SDimitry Andric constexpr typename iterator_traits<InputIterator>::difference_type // constexpr in C++20 83*0b57cec5SDimitry Andric count(InputIterator first, InputIterator last, const T& value); 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 86*0b57cec5SDimitry Andric constexpr typename iterator_traits<InputIterator>::difference_type // constexpr in C++20 87*0b57cec5SDimitry Andric count_if(InputIterator first, InputIterator last, Predicate pred); 88*0b57cec5SDimitry Andric 89*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 90*0b57cec5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 91*0b57cec5SDimitry Andric mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 94*0b57cec5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 95*0b57cec5SDimitry Andric mismatch(InputIterator1 first1, InputIterator1 last1, 96*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2); // **C++14** 97*0b57cec5SDimitry Andric 98*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 99*0b57cec5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 100*0b57cec5SDimitry Andric mismatch(InputIterator1 first1, InputIterator1 last1, 101*0b57cec5SDimitry Andric InputIterator2 first2, BinaryPredicate pred); 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 104*0b57cec5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 105*0b57cec5SDimitry Andric mismatch(InputIterator1 first1, InputIterator1 last1, 106*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, 107*0b57cec5SDimitry Andric BinaryPredicate pred); // **C++14** 108*0b57cec5SDimitry Andric 109*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 110*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 111*0b57cec5SDimitry Andric equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 114*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 115*0b57cec5SDimitry Andric equal(InputIterator1 first1, InputIterator1 last1, 116*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2); // **C++14** 117*0b57cec5SDimitry Andric 118*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 119*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 120*0b57cec5SDimitry Andric equal(InputIterator1 first1, InputIterator1 last1, 121*0b57cec5SDimitry Andric InputIterator2 first2, BinaryPredicate pred); 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 124*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 125*0b57cec5SDimitry Andric equal(InputIterator1 first1, InputIterator1 last1, 126*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, 127*0b57cec5SDimitry Andric BinaryPredicate pred); // **C++14** 128*0b57cec5SDimitry Andric 129*0b57cec5SDimitry Andrictemplate<class ForwardIterator1, class ForwardIterator2> 130*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 131*0b57cec5SDimitry Andric is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 132*0b57cec5SDimitry Andric ForwardIterator2 first2); 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andrictemplate<class ForwardIterator1, class ForwardIterator2> 135*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 136*0b57cec5SDimitry Andric is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 137*0b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2); // **C++14** 138*0b57cec5SDimitry Andric 139*0b57cec5SDimitry Andrictemplate<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 140*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 141*0b57cec5SDimitry Andric is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 142*0b57cec5SDimitry Andric ForwardIterator2 first2, BinaryPredicate pred); 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andrictemplate<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 145*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 146*0b57cec5SDimitry Andric is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 147*0b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2, 148*0b57cec5SDimitry Andric BinaryPredicate pred); // **C++14** 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2> 151*0b57cec5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 152*0b57cec5SDimitry Andric search(ForwardIterator1 first1, ForwardIterator1 last1, 153*0b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2); 154*0b57cec5SDimitry Andric 155*0b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 156*0b57cec5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 157*0b57cec5SDimitry Andric search(ForwardIterator1 first1, ForwardIterator1 last1, 158*0b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size, class T> 161*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 162*0b57cec5SDimitry Andric search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value); 163*0b57cec5SDimitry Andric 164*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size, class T, class BinaryPredicate> 165*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 166*0b57cec5SDimitry Andric search_n(ForwardIterator first, ForwardIterator last, 167*0b57cec5SDimitry Andric Size count, const T& value, BinaryPredicate pred); 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator> 170480093f4SDimitry Andric constexpr OutputIterator // constexpr in C++20 171*0b57cec5SDimitry Andric copy(InputIterator first, InputIterator last, OutputIterator result); 172*0b57cec5SDimitry Andric 173*0b57cec5SDimitry Andrictemplate<class InputIterator, class OutputIterator, class Predicate> 174480093f4SDimitry Andric constexpr OutputIterator // constexpr in C++20 175*0b57cec5SDimitry Andric copy_if(InputIterator first, InputIterator last, 176*0b57cec5SDimitry Andric OutputIterator result, Predicate pred); 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andrictemplate<class InputIterator, class Size, class OutputIterator> 179480093f4SDimitry Andric constexpr OutputIterator // constexpr in C++20 180*0b57cec5SDimitry Andric copy_n(InputIterator first, Size n, OutputIterator result); 181*0b57cec5SDimitry Andric 182*0b57cec5SDimitry Andrictemplate <class BidirectionalIterator1, class BidirectionalIterator2> 183480093f4SDimitry Andric constexpr BidirectionalIterator2 // constexpr in C++20 184*0b57cec5SDimitry Andric copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, 185*0b57cec5SDimitry Andric BidirectionalIterator2 result); 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2> 188e8d8bef9SDimitry Andric constexpr ForwardIterator2 // constexpr in C++20 189*0b57cec5SDimitry Andric swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); 190*0b57cec5SDimitry Andric 191*0b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2> 192e8d8bef9SDimitry Andric constexpr void // constexpr in C++20 193*0b57cec5SDimitry Andric iter_swap(ForwardIterator1 a, ForwardIterator2 b); 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class UnaryOperation> 196*0b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 197*0b57cec5SDimitry Andric transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op); 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation> 200*0b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 201*0b57cec5SDimitry Andric transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, 202*0b57cec5SDimitry Andric OutputIterator result, BinaryOperation binary_op); 203*0b57cec5SDimitry Andric 204*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 205*0b57cec5SDimitry Andric constexpr void // constexpr in C++20 206*0b57cec5SDimitry Andric replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); 207*0b57cec5SDimitry Andric 208*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class Predicate, class T> 209*0b57cec5SDimitry Andric constexpr void // constexpr in C++20 210*0b57cec5SDimitry Andric replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value); 211*0b57cec5SDimitry Andric 212*0b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class T> 213*0b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 214*0b57cec5SDimitry Andric replace_copy(InputIterator first, InputIterator last, OutputIterator result, 215*0b57cec5SDimitry Andric const T& old_value, const T& new_value); 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class Predicate, class T> 218*0b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 219*0b57cec5SDimitry Andric replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value); 220*0b57cec5SDimitry Andric 221*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 222*0b57cec5SDimitry Andric constexpr void // constexpr in C++20 223*0b57cec5SDimitry Andric fill(ForwardIterator first, ForwardIterator last, const T& value); 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andrictemplate <class OutputIterator, class Size, class T> 226*0b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 227*0b57cec5SDimitry Andric fill_n(OutputIterator first, Size n, const T& value); 228*0b57cec5SDimitry Andric 229*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class Generator> 230*0b57cec5SDimitry Andric constexpr void // constexpr in C++20 231*0b57cec5SDimitry Andric generate(ForwardIterator first, ForwardIterator last, Generator gen); 232*0b57cec5SDimitry Andric 233*0b57cec5SDimitry Andrictemplate <class OutputIterator, class Size, class Generator> 234*0b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 235*0b57cec5SDimitry Andric generate_n(OutputIterator first, Size n, Generator gen); 236*0b57cec5SDimitry Andric 237*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 238*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 239*0b57cec5SDimitry Andric remove(ForwardIterator first, ForwardIterator last, const T& value); 240*0b57cec5SDimitry Andric 241*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class Predicate> 242*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 243*0b57cec5SDimitry Andric remove_if(ForwardIterator first, ForwardIterator last, Predicate pred); 244*0b57cec5SDimitry Andric 245*0b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class T> 246*0b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 247*0b57cec5SDimitry Andric remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value); 248*0b57cec5SDimitry Andric 249*0b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class Predicate> 250*0b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 251*0b57cec5SDimitry Andric remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); 252*0b57cec5SDimitry Andric 253*0b57cec5SDimitry Andrictemplate <class ForwardIterator> 254e8d8bef9SDimitry Andric constexpr ForwardIterator // constexpr in C++20 255*0b57cec5SDimitry Andric unique(ForwardIterator first, ForwardIterator last); 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class BinaryPredicate> 258e8d8bef9SDimitry Andric constexpr ForwardIterator // constexpr in C++20 259*0b57cec5SDimitry Andric unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator> 262e8d8bef9SDimitry Andric constexpr OutputIterator // constexpr in C++20 263*0b57cec5SDimitry Andric unique_copy(InputIterator first, InputIterator last, OutputIterator result); 264*0b57cec5SDimitry Andric 265*0b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class BinaryPredicate> 266e8d8bef9SDimitry Andric constexpr OutputIterator // constexpr in C++20 267*0b57cec5SDimitry Andric unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); 268*0b57cec5SDimitry Andric 269*0b57cec5SDimitry Andrictemplate <class BidirectionalIterator> 270e8d8bef9SDimitry Andric constexpr void // constexpr in C++20 271*0b57cec5SDimitry Andric reverse(BidirectionalIterator first, BidirectionalIterator last); 272*0b57cec5SDimitry Andric 273*0b57cec5SDimitry Andrictemplate <class BidirectionalIterator, class OutputIterator> 274*0b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 275*0b57cec5SDimitry Andric reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result); 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andrictemplate <class ForwardIterator> 278e8d8bef9SDimitry Andric constexpr ForwardIterator // constexpr in C++20 279*0b57cec5SDimitry Andric rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last); 280*0b57cec5SDimitry Andric 281*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class OutputIterator> 282e8d8bef9SDimitry Andric constexpr OutputIterator // constexpr in C++20 283*0b57cec5SDimitry Andric rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result); 284*0b57cec5SDimitry Andric 285*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 286*0b57cec5SDimitry Andric void 287*0b57cec5SDimitry Andric random_shuffle(RandomAccessIterator first, RandomAccessIterator last); // deprecated in C++14, removed in C++17 288*0b57cec5SDimitry Andric 289*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class RandomNumberGenerator> 290*0b57cec5SDimitry Andric void 291*0b57cec5SDimitry Andric random_shuffle(RandomAccessIterator first, RandomAccessIterator last, 292*0b57cec5SDimitry Andric RandomNumberGenerator& rand); // deprecated in C++14, removed in C++17 293*0b57cec5SDimitry Andric 294*0b57cec5SDimitry Andrictemplate<class PopulationIterator, class SampleIterator, 295*0b57cec5SDimitry Andric class Distance, class UniformRandomBitGenerator> 296*0b57cec5SDimitry Andric SampleIterator sample(PopulationIterator first, PopulationIterator last, 297*0b57cec5SDimitry Andric SampleIterator out, Distance n, 298*0b57cec5SDimitry Andric UniformRandomBitGenerator&& g); // C++17 299*0b57cec5SDimitry Andric 300*0b57cec5SDimitry Andrictemplate<class RandomAccessIterator, class UniformRandomNumberGenerator> 301*0b57cec5SDimitry Andric void shuffle(RandomAccessIterator first, RandomAccessIterator last, 302*0b57cec5SDimitry Andric UniformRandomNumberGenerator&& g); 303*0b57cec5SDimitry Andric 304e8d8bef9SDimitry Andrictemplate<class ForwardIterator> 305e8d8bef9SDimitry Andric constexpr ForwardIterator 306e8d8bef9SDimitry Andric shift_left(ForwardIterator first, ForwardIterator last, 307e8d8bef9SDimitry Andric typename iterator_traits<ForwardIterator>::difference_type n); // C++20 308e8d8bef9SDimitry Andric 309e8d8bef9SDimitry Andrictemplate<class ForwardIterator> 310e8d8bef9SDimitry Andric constexpr ForwardIterator 311e8d8bef9SDimitry Andric shift_right(ForwardIterator first, ForwardIterator last, 312e8d8bef9SDimitry Andric typename iterator_traits<ForwardIterator>::difference_type n); // C++20 313e8d8bef9SDimitry Andric 314*0b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 315*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 316*0b57cec5SDimitry Andric is_partitioned(InputIterator first, InputIterator last, Predicate pred); 317*0b57cec5SDimitry Andric 318*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class Predicate> 319e8d8bef9SDimitry Andric constexpr ForwardIterator // constexpr in C++20 320*0b57cec5SDimitry Andric partition(ForwardIterator first, ForwardIterator last, Predicate pred); 321*0b57cec5SDimitry Andric 322*0b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator1, 323*0b57cec5SDimitry Andric class OutputIterator2, class Predicate> 324*0b57cec5SDimitry Andric constexpr pair<OutputIterator1, OutputIterator2> // constexpr in C++20 325*0b57cec5SDimitry Andric partition_copy(InputIterator first, InputIterator last, 326*0b57cec5SDimitry Andric OutputIterator1 out_true, OutputIterator2 out_false, 327*0b57cec5SDimitry Andric Predicate pred); 328*0b57cec5SDimitry Andric 329*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class Predicate> 330*0b57cec5SDimitry Andric ForwardIterator 331*0b57cec5SDimitry Andric stable_partition(ForwardIterator first, ForwardIterator last, Predicate pred); 332*0b57cec5SDimitry Andric 333*0b57cec5SDimitry Andrictemplate<class ForwardIterator, class Predicate> 334*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 335*0b57cec5SDimitry Andric partition_point(ForwardIterator first, ForwardIterator last, Predicate pred); 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andrictemplate <class ForwardIterator> 338*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 339*0b57cec5SDimitry Andric is_sorted(ForwardIterator first, ForwardIterator last); 340*0b57cec5SDimitry Andric 341*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class Compare> 342e8d8bef9SDimitry Andric constexpr bool // constexpr in C++20 343*0b57cec5SDimitry Andric is_sorted(ForwardIterator first, ForwardIterator last, Compare comp); 344*0b57cec5SDimitry Andric 345*0b57cec5SDimitry Andrictemplate<class ForwardIterator> 346*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 347*0b57cec5SDimitry Andric is_sorted_until(ForwardIterator first, ForwardIterator last); 348*0b57cec5SDimitry Andric 349*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class Compare> 350*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 351*0b57cec5SDimitry Andric is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp); 352*0b57cec5SDimitry Andric 353*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 354*0b57cec5SDimitry Andric void 355*0b57cec5SDimitry Andric sort(RandomAccessIterator first, RandomAccessIterator last); 356*0b57cec5SDimitry Andric 357*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 358*0b57cec5SDimitry Andric void 359*0b57cec5SDimitry Andric sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 360*0b57cec5SDimitry Andric 361*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 362*0b57cec5SDimitry Andric void 363*0b57cec5SDimitry Andric stable_sort(RandomAccessIterator first, RandomAccessIterator last); 364*0b57cec5SDimitry Andric 365*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 366*0b57cec5SDimitry Andric void 367*0b57cec5SDimitry Andric stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 368*0b57cec5SDimitry Andric 369*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 370*0b57cec5SDimitry Andric void 371*0b57cec5SDimitry Andric partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); 372*0b57cec5SDimitry Andric 373*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 374*0b57cec5SDimitry Andric void 375*0b57cec5SDimitry Andric partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); 376*0b57cec5SDimitry Andric 377*0b57cec5SDimitry Andrictemplate <class InputIterator, class RandomAccessIterator> 378*0b57cec5SDimitry Andric RandomAccessIterator 379*0b57cec5SDimitry Andric partial_sort_copy(InputIterator first, InputIterator last, 380*0b57cec5SDimitry Andric RandomAccessIterator result_first, RandomAccessIterator result_last); 381*0b57cec5SDimitry Andric 382*0b57cec5SDimitry Andrictemplate <class InputIterator, class RandomAccessIterator, class Compare> 383*0b57cec5SDimitry Andric RandomAccessIterator 384*0b57cec5SDimitry Andric partial_sort_copy(InputIterator first, InputIterator last, 385*0b57cec5SDimitry Andric RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp); 386*0b57cec5SDimitry Andric 387*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 388*0b57cec5SDimitry Andric void 389*0b57cec5SDimitry Andric nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); 390*0b57cec5SDimitry Andric 391*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 392*0b57cec5SDimitry Andric void 393*0b57cec5SDimitry Andric nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); 394*0b57cec5SDimitry Andric 395*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 396*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 397*0b57cec5SDimitry Andric lower_bound(ForwardIterator first, ForwardIterator last, const T& value); 398*0b57cec5SDimitry Andric 399*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class T, class Compare> 400*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 401*0b57cec5SDimitry Andric lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 402*0b57cec5SDimitry Andric 403*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 404*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 405*0b57cec5SDimitry Andric upper_bound(ForwardIterator first, ForwardIterator last, const T& value); 406*0b57cec5SDimitry Andric 407*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class T, class Compare> 408*0b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 409*0b57cec5SDimitry Andric upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 410*0b57cec5SDimitry Andric 411*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 412*0b57cec5SDimitry Andric constexpr pair<ForwardIterator, ForwardIterator> // constexpr in C++20 413*0b57cec5SDimitry Andric equal_range(ForwardIterator first, ForwardIterator last, const T& value); 414*0b57cec5SDimitry Andric 415*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class T, class Compare> 416*0b57cec5SDimitry Andric constexpr pair<ForwardIterator, ForwardIterator> // constexpr in C++20 417*0b57cec5SDimitry Andric equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 418*0b57cec5SDimitry Andric 419*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 420*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 421*0b57cec5SDimitry Andric binary_search(ForwardIterator first, ForwardIterator last, const T& value); 422*0b57cec5SDimitry Andric 423*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class T, class Compare> 424*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 425*0b57cec5SDimitry Andric binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 426*0b57cec5SDimitry Andric 427*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator> 428e8d8bef9SDimitry Andric constexpr OutputIterator // constexpr in C++20 429*0b57cec5SDimitry Andric merge(InputIterator1 first1, InputIterator1 last1, 430*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result); 431*0b57cec5SDimitry Andric 432*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 433e8d8bef9SDimitry Andric constexpr OutputIterator // constexpr in C++20 434*0b57cec5SDimitry Andric merge(InputIterator1 first1, InputIterator1 last1, 435*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 436*0b57cec5SDimitry Andric 437*0b57cec5SDimitry Andrictemplate <class BidirectionalIterator> 438*0b57cec5SDimitry Andric void 439*0b57cec5SDimitry Andric inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); 440*0b57cec5SDimitry Andric 441*0b57cec5SDimitry Andrictemplate <class BidirectionalIterator, class Compare> 442*0b57cec5SDimitry Andric void 443*0b57cec5SDimitry Andric inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); 444*0b57cec5SDimitry Andric 445*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 446*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 447*0b57cec5SDimitry Andric includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); 448*0b57cec5SDimitry Andric 449*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class Compare> 450*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 451*0b57cec5SDimitry Andric includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); 452*0b57cec5SDimitry Andric 453*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator> 454e8d8bef9SDimitry Andric constexpr OutputIterator // constexpr in C++20 455*0b57cec5SDimitry Andric set_union(InputIterator1 first1, InputIterator1 last1, 456*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result); 457*0b57cec5SDimitry Andric 458*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 459e8d8bef9SDimitry Andric constexpr OutputIterator // constexpr in C++20 460*0b57cec5SDimitry Andric set_union(InputIterator1 first1, InputIterator1 last1, 461*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 462*0b57cec5SDimitry Andric 463*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator> 464*0b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 465*0b57cec5SDimitry Andric set_intersection(InputIterator1 first1, InputIterator1 last1, 466*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result); 467*0b57cec5SDimitry Andric 468*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 469*0b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 470*0b57cec5SDimitry Andric set_intersection(InputIterator1 first1, InputIterator1 last1, 471*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 472*0b57cec5SDimitry Andric 473*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator> 474e8d8bef9SDimitry Andric constexpr OutputIterator // constexpr in C++20 475*0b57cec5SDimitry Andric set_difference(InputIterator1 first1, InputIterator1 last1, 476*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result); 477*0b57cec5SDimitry Andric 478*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 479e8d8bef9SDimitry Andric constexpr OutputIterator // constexpr in C++20 480*0b57cec5SDimitry Andric set_difference(InputIterator1 first1, InputIterator1 last1, 481*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 482*0b57cec5SDimitry Andric 483*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator> 484e8d8bef9SDimitry Andric constexpr OutputIterator // constexpr in C++20 485*0b57cec5SDimitry Andric set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, 486*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result); 487*0b57cec5SDimitry Andric 488*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 489e8d8bef9SDimitry Andric constexpr OutputIterator // constexpr in C++20 490*0b57cec5SDimitry Andric set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, 491*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 492*0b57cec5SDimitry Andric 493*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 494*0b57cec5SDimitry Andric void 495*0b57cec5SDimitry Andric push_heap(RandomAccessIterator first, RandomAccessIterator last); 496*0b57cec5SDimitry Andric 497*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 498*0b57cec5SDimitry Andric void 499*0b57cec5SDimitry Andric push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 500*0b57cec5SDimitry Andric 501*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 502*0b57cec5SDimitry Andric void 503*0b57cec5SDimitry Andric pop_heap(RandomAccessIterator first, RandomAccessIterator last); 504*0b57cec5SDimitry Andric 505*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 506*0b57cec5SDimitry Andric void 507*0b57cec5SDimitry Andric pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 508*0b57cec5SDimitry Andric 509*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 510*0b57cec5SDimitry Andric void 511*0b57cec5SDimitry Andric make_heap(RandomAccessIterator first, RandomAccessIterator last); 512*0b57cec5SDimitry Andric 513*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 514*0b57cec5SDimitry Andric void 515*0b57cec5SDimitry Andric make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 516*0b57cec5SDimitry Andric 517*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 518*0b57cec5SDimitry Andric void 519*0b57cec5SDimitry Andric sort_heap(RandomAccessIterator first, RandomAccessIterator last); 520*0b57cec5SDimitry Andric 521*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 522*0b57cec5SDimitry Andric void 523*0b57cec5SDimitry Andric sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 524*0b57cec5SDimitry Andric 525*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 526*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 527*0b57cec5SDimitry Andric is_heap(RandomAccessIterator first, RandomAccessiterator last); 528*0b57cec5SDimitry Andric 529*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 530*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 531*0b57cec5SDimitry Andric is_heap(RandomAccessIterator first, RandomAccessiterator last, Compare comp); 532*0b57cec5SDimitry Andric 533*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 534*0b57cec5SDimitry Andric constexpr RandomAccessIterator // constexpr in C++20 535*0b57cec5SDimitry Andric is_heap_until(RandomAccessIterator first, RandomAccessiterator last); 536*0b57cec5SDimitry Andric 537*0b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 538*0b57cec5SDimitry Andric constexpr RandomAccessIterator // constexpr in C++20 539*0b57cec5SDimitry Andric is_heap_until(RandomAccessIterator first, RandomAccessiterator last, Compare comp); 540*0b57cec5SDimitry Andric 541*0b57cec5SDimitry Andrictemplate <class ForwardIterator> 542e8d8bef9SDimitry Andric constexpr ForwardIterator // constexpr in C++14 543e8d8bef9SDimitry Andric min_element(ForwardIterator first, ForwardIterator last); 544*0b57cec5SDimitry Andric 545*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class Compare> 546e8d8bef9SDimitry Andric constexpr ForwardIterator // constexpr in C++14 547e8d8bef9SDimitry Andric min_element(ForwardIterator first, ForwardIterator last, Compare comp); 548*0b57cec5SDimitry Andric 549*0b57cec5SDimitry Andrictemplate <class T> 550e8d8bef9SDimitry Andric constexpr const T& // constexpr in C++14 551e8d8bef9SDimitry Andric min(const T& a, const T& b); 552*0b57cec5SDimitry Andric 553*0b57cec5SDimitry Andrictemplate <class T, class Compare> 554e8d8bef9SDimitry Andric constexpr const T& // constexpr in C++14 555e8d8bef9SDimitry Andric min(const T& a, const T& b, Compare comp); 556*0b57cec5SDimitry Andric 557*0b57cec5SDimitry Andrictemplate<class T> 558e8d8bef9SDimitry Andric constexpr T // constexpr in C++14 559e8d8bef9SDimitry Andric min(initializer_list<T> t); 560*0b57cec5SDimitry Andric 561*0b57cec5SDimitry Andrictemplate<class T, class Compare> 562e8d8bef9SDimitry Andric constexpr T // constexpr in C++14 563e8d8bef9SDimitry Andric min(initializer_list<T> t, Compare comp); 564*0b57cec5SDimitry Andric 565*0b57cec5SDimitry Andrictemplate<class T> 566*0b57cec5SDimitry Andric constexpr const T& clamp(const T& v, const T& lo, const T& hi); // C++17 567*0b57cec5SDimitry Andric 568*0b57cec5SDimitry Andrictemplate<class T, class Compare> 569*0b57cec5SDimitry Andric constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp); // C++17 570*0b57cec5SDimitry Andric 571*0b57cec5SDimitry Andrictemplate <class ForwardIterator> 572e8d8bef9SDimitry Andric constexpr ForwardIterator // constexpr in C++14 573e8d8bef9SDimitry Andric max_element(ForwardIterator first, ForwardIterator last); 574*0b57cec5SDimitry Andric 575*0b57cec5SDimitry Andrictemplate <class ForwardIterator, class Compare> 576e8d8bef9SDimitry Andric constexpr ForwardIterator // constexpr in C++14 577e8d8bef9SDimitry Andric max_element(ForwardIterator first, ForwardIterator last, Compare comp); 578*0b57cec5SDimitry Andric 579*0b57cec5SDimitry Andrictemplate <class T> 580e8d8bef9SDimitry Andric constexpr const T& // constexpr in C++14 581e8d8bef9SDimitry Andric max(const T& a, const T& b); 582*0b57cec5SDimitry Andric 583*0b57cec5SDimitry Andrictemplate <class T, class Compare> 584e8d8bef9SDimitry Andric constexpr const T& // constexpr in C++14 585e8d8bef9SDimitry Andric max(const T& a, const T& b, Compare comp); 586*0b57cec5SDimitry Andric 587*0b57cec5SDimitry Andrictemplate<class T> 588e8d8bef9SDimitry Andric constexpr T // constexpr in C++14 589e8d8bef9SDimitry Andric max(initializer_list<T> t); 590*0b57cec5SDimitry Andric 591*0b57cec5SDimitry Andrictemplate<class T, class Compare> 592e8d8bef9SDimitry Andric constexpr T // constexpr in C++14 593e8d8bef9SDimitry Andric max(initializer_list<T> t, Compare comp); 594*0b57cec5SDimitry Andric 595*0b57cec5SDimitry Andrictemplate<class ForwardIterator> 596e8d8bef9SDimitry Andric constexpr pair<ForwardIterator, ForwardIterator> // constexpr in C++14 597e8d8bef9SDimitry Andric minmax_element(ForwardIterator first, ForwardIterator last); 598*0b57cec5SDimitry Andric 599*0b57cec5SDimitry Andrictemplate<class ForwardIterator, class Compare> 600e8d8bef9SDimitry Andric constexpr pair<ForwardIterator, ForwardIterator> // constexpr in C++14 601e8d8bef9SDimitry Andric minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); 602*0b57cec5SDimitry Andric 603*0b57cec5SDimitry Andrictemplate<class T> 604e8d8bef9SDimitry Andric constexpr pair<const T&, const T&> // constexpr in C++14 605e8d8bef9SDimitry Andric minmax(const T& a, const T& b); 606*0b57cec5SDimitry Andric 607*0b57cec5SDimitry Andrictemplate<class T, class Compare> 608e8d8bef9SDimitry Andric constexpr pair<const T&, const T&> // constexpr in C++14 609e8d8bef9SDimitry Andric minmax(const T& a, const T& b, Compare comp); 610*0b57cec5SDimitry Andric 611*0b57cec5SDimitry Andrictemplate<class T> 612e8d8bef9SDimitry Andric constexpr pair<T, T> // constexpr in C++14 613e8d8bef9SDimitry Andric minmax(initializer_list<T> t); 614*0b57cec5SDimitry Andric 615*0b57cec5SDimitry Andrictemplate<class T, class Compare> 616e8d8bef9SDimitry Andric constexpr pair<T, T> // constexpr in C++14 617e8d8bef9SDimitry Andric minmax(initializer_list<T> t, Compare comp); 618*0b57cec5SDimitry Andric 619*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 620*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 621*0b57cec5SDimitry Andric lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); 622*0b57cec5SDimitry Andric 623*0b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class Compare> 624*0b57cec5SDimitry Andric constexpr bool // constexpr in C++20 625*0b57cec5SDimitry Andric lexicographical_compare(InputIterator1 first1, InputIterator1 last1, 626*0b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, Compare comp); 627*0b57cec5SDimitry Andric 628*0b57cec5SDimitry Andrictemplate <class BidirectionalIterator> 629e8d8bef9SDimitry Andric constexpr bool // constexpr in C++20 630*0b57cec5SDimitry Andric next_permutation(BidirectionalIterator first, BidirectionalIterator last); 631*0b57cec5SDimitry Andric 632*0b57cec5SDimitry Andrictemplate <class BidirectionalIterator, class Compare> 633e8d8bef9SDimitry Andric constexpr bool // constexpr in C++20 634*0b57cec5SDimitry Andric next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); 635*0b57cec5SDimitry Andric 636*0b57cec5SDimitry Andrictemplate <class BidirectionalIterator> 637e8d8bef9SDimitry Andric constexpr bool // constexpr in C++20 638*0b57cec5SDimitry Andric prev_permutation(BidirectionalIterator first, BidirectionalIterator last); 639*0b57cec5SDimitry Andric 640*0b57cec5SDimitry Andrictemplate <class BidirectionalIterator, class Compare> 641e8d8bef9SDimitry Andric constexpr bool // constexpr in C++20 642*0b57cec5SDimitry Andric prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); 643*0b57cec5SDimitry Andric 644*0b57cec5SDimitry Andric} // std 645*0b57cec5SDimitry Andric 646*0b57cec5SDimitry Andric*/ 647*0b57cec5SDimitry Andric 648*0b57cec5SDimitry Andric#include <__config> 649*0b57cec5SDimitry Andric#include <initializer_list> 650*0b57cec5SDimitry Andric#include <type_traits> 651*0b57cec5SDimitry Andric#include <cstring> 652*0b57cec5SDimitry Andric#include <utility> // needed to provide swap_ranges. 653*0b57cec5SDimitry Andric#include <memory> 654*0b57cec5SDimitry Andric#include <functional> 655*0b57cec5SDimitry Andric#include <iterator> 656*0b57cec5SDimitry Andric#include <cstddef> 657*0b57cec5SDimitry Andric#include <bit> 658*0b57cec5SDimitry Andric#include <version> 659*0b57cec5SDimitry Andric 660*0b57cec5SDimitry Andric#include <__debug> 661*0b57cec5SDimitry Andric 662*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 663*0b57cec5SDimitry Andric#pragma GCC system_header 664*0b57cec5SDimitry Andric#endif 665*0b57cec5SDimitry Andric 666*0b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 667*0b57cec5SDimitry Andric#include <__undef_macros> 668*0b57cec5SDimitry Andric 669*0b57cec5SDimitry Andric 670*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 671*0b57cec5SDimitry Andric 672*0b57cec5SDimitry Andric// I'd like to replace these with _VSTD::equal_to<void>, but can't because: 673*0b57cec5SDimitry Andric// * That only works with C++14 and later, and 674*0b57cec5SDimitry Andric// * We haven't included <functional> here. 675*0b57cec5SDimitry Andrictemplate <class _T1, class _T2 = _T1> 676*0b57cec5SDimitry Andricstruct __equal_to 677*0b57cec5SDimitry Andric{ 678*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 679*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;} 680*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;} 681*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;} 682*0b57cec5SDimitry Andric}; 683*0b57cec5SDimitry Andric 684*0b57cec5SDimitry Andrictemplate <class _T1> 685*0b57cec5SDimitry Andricstruct __equal_to<_T1, _T1> 686*0b57cec5SDimitry Andric{ 687*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 688*0b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 689*0b57cec5SDimitry Andric}; 690*0b57cec5SDimitry Andric 691*0b57cec5SDimitry Andrictemplate <class _T1> 692*0b57cec5SDimitry Andricstruct __equal_to<const _T1, _T1> 693*0b57cec5SDimitry Andric{ 694*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 695*0b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 696*0b57cec5SDimitry Andric}; 697*0b57cec5SDimitry Andric 698*0b57cec5SDimitry Andrictemplate <class _T1> 699*0b57cec5SDimitry Andricstruct __equal_to<_T1, const _T1> 700*0b57cec5SDimitry Andric{ 701*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 702*0b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 703*0b57cec5SDimitry Andric}; 704*0b57cec5SDimitry Andric 705*0b57cec5SDimitry Andrictemplate <class _T1, class _T2 = _T1> 706*0b57cec5SDimitry Andricstruct __less 707*0b57cec5SDimitry Andric{ 708*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 709*0b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 710*0b57cec5SDimitry Andric 711*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 712*0b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;} 713*0b57cec5SDimitry Andric 714*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 715*0b57cec5SDimitry Andric bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;} 716*0b57cec5SDimitry Andric 717*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 718*0b57cec5SDimitry Andric bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;} 719*0b57cec5SDimitry Andric}; 720*0b57cec5SDimitry Andric 721*0b57cec5SDimitry Andrictemplate <class _T1> 722*0b57cec5SDimitry Andricstruct __less<_T1, _T1> 723*0b57cec5SDimitry Andric{ 724*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 725*0b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 726*0b57cec5SDimitry Andric}; 727*0b57cec5SDimitry Andric 728*0b57cec5SDimitry Andrictemplate <class _T1> 729*0b57cec5SDimitry Andricstruct __less<const _T1, _T1> 730*0b57cec5SDimitry Andric{ 731*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 732*0b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 733*0b57cec5SDimitry Andric}; 734*0b57cec5SDimitry Andric 735*0b57cec5SDimitry Andrictemplate <class _T1> 736*0b57cec5SDimitry Andricstruct __less<_T1, const _T1> 737*0b57cec5SDimitry Andric{ 738*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 739*0b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 740*0b57cec5SDimitry Andric}; 741*0b57cec5SDimitry Andric 742*0b57cec5SDimitry Andrictemplate <class _Predicate> 743*0b57cec5SDimitry Andricclass __invert // invert the sense of a comparison 744*0b57cec5SDimitry Andric{ 745*0b57cec5SDimitry Andricprivate: 746*0b57cec5SDimitry Andric _Predicate __p_; 747*0b57cec5SDimitry Andricpublic: 748*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __invert() {} 749*0b57cec5SDimitry Andric 750*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 751*0b57cec5SDimitry Andric explicit __invert(_Predicate __p) : __p_(__p) {} 752*0b57cec5SDimitry Andric 753*0b57cec5SDimitry Andric template <class _T1> 754*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 755*0b57cec5SDimitry Andric bool operator()(const _T1& __x) {return !__p_(__x);} 756*0b57cec5SDimitry Andric 757*0b57cec5SDimitry Andric template <class _T1, class _T2> 758*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 759*0b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} 760*0b57cec5SDimitry Andric}; 761*0b57cec5SDimitry Andric 762*0b57cec5SDimitry Andric// Perform division by two quickly for positive integers (llvm.org/PR39129) 763*0b57cec5SDimitry Andric 764*0b57cec5SDimitry Andrictemplate <typename _Integral> 765*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 766*0b57cec5SDimitry Andrictypename enable_if 767*0b57cec5SDimitry Andric< 768*0b57cec5SDimitry Andric is_integral<_Integral>::value, 769*0b57cec5SDimitry Andric _Integral 770*0b57cec5SDimitry Andric>::type 771*0b57cec5SDimitry Andric__half_positive(_Integral __value) 772*0b57cec5SDimitry Andric{ 773*0b57cec5SDimitry Andric return static_cast<_Integral>(static_cast<typename make_unsigned<_Integral>::type>(__value) / 2); 774*0b57cec5SDimitry Andric} 775*0b57cec5SDimitry Andric 776*0b57cec5SDimitry Andrictemplate <typename _Tp> 777*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 778*0b57cec5SDimitry Andrictypename enable_if 779*0b57cec5SDimitry Andric< 780*0b57cec5SDimitry Andric !is_integral<_Tp>::value, 781*0b57cec5SDimitry Andric _Tp 782*0b57cec5SDimitry Andric>::type 783*0b57cec5SDimitry Andric__half_positive(_Tp __value) 784*0b57cec5SDimitry Andric{ 785*0b57cec5SDimitry Andric return __value / 2; 786*0b57cec5SDimitry Andric} 787*0b57cec5SDimitry Andric 788*0b57cec5SDimitry Andric#ifdef _LIBCPP_DEBUG 789*0b57cec5SDimitry Andric 790*0b57cec5SDimitry Andrictemplate <class _Compare> 791*0b57cec5SDimitry Andricstruct __debug_less 792*0b57cec5SDimitry Andric{ 793*0b57cec5SDimitry Andric _Compare &__comp_; 794*0b57cec5SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 795*0b57cec5SDimitry Andric __debug_less(_Compare& __c) : __comp_(__c) {} 796*0b57cec5SDimitry Andric 797*0b57cec5SDimitry Andric template <class _Tp, class _Up> 798*0b57cec5SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 799*0b57cec5SDimitry Andric bool operator()(const _Tp& __x, const _Up& __y) 800*0b57cec5SDimitry Andric { 801*0b57cec5SDimitry Andric bool __r = __comp_(__x, __y); 802*0b57cec5SDimitry Andric if (__r) 803*0b57cec5SDimitry Andric __do_compare_assert(0, __y, __x); 804*0b57cec5SDimitry Andric return __r; 805*0b57cec5SDimitry Andric } 806*0b57cec5SDimitry Andric 807*0b57cec5SDimitry Andric template <class _Tp, class _Up> 808*0b57cec5SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 809*0b57cec5SDimitry Andric bool operator()(_Tp& __x, _Up& __y) 810*0b57cec5SDimitry Andric { 811*0b57cec5SDimitry Andric bool __r = __comp_(__x, __y); 812*0b57cec5SDimitry Andric if (__r) 813*0b57cec5SDimitry Andric __do_compare_assert(0, __y, __x); 814*0b57cec5SDimitry Andric return __r; 815*0b57cec5SDimitry Andric } 816*0b57cec5SDimitry Andric 817*0b57cec5SDimitry Andric template <class _LHS, class _RHS> 818*0b57cec5SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 819*0b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 820*0b57cec5SDimitry Andric decltype((void)_VSTD::declval<_Compare&>()( 821*0b57cec5SDimitry Andric _VSTD::declval<_LHS &>(), _VSTD::declval<_RHS &>())) 822*0b57cec5SDimitry Andric __do_compare_assert(int, _LHS & __l, _RHS & __r) { 823*0b57cec5SDimitry Andric _LIBCPP_ASSERT(!__comp_(__l, __r), 824*0b57cec5SDimitry Andric "Comparator does not induce a strict weak ordering"); 825*0b57cec5SDimitry Andric } 826*0b57cec5SDimitry Andric 827*0b57cec5SDimitry Andric template <class _LHS, class _RHS> 828*0b57cec5SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 829*0b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 830*0b57cec5SDimitry Andric void __do_compare_assert(long, _LHS &, _RHS &) {} 831*0b57cec5SDimitry Andric}; 832*0b57cec5SDimitry Andric 833*0b57cec5SDimitry Andric#endif // _LIBCPP_DEBUG 834*0b57cec5SDimitry Andric 835*0b57cec5SDimitry Andrictemplate <class _Comp> 836*0b57cec5SDimitry Andricstruct __comp_ref_type { 837*0b57cec5SDimitry Andric // Pass the comparator by lvalue reference. Or in debug mode, using a 838*0b57cec5SDimitry Andric // debugging wrapper that stores a reference. 839*0b57cec5SDimitry Andric#ifndef _LIBCPP_DEBUG 840*0b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Comp>::type type; 841*0b57cec5SDimitry Andric#else 842*0b57cec5SDimitry Andric typedef __debug_less<_Comp> type; 843*0b57cec5SDimitry Andric#endif 844*0b57cec5SDimitry Andric}; 845*0b57cec5SDimitry Andric 846*0b57cec5SDimitry Andric// all_of 847*0b57cec5SDimitry Andric 848*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 849*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 850*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 851*0b57cec5SDimitry Andricbool 852*0b57cec5SDimitry Andricall_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 853*0b57cec5SDimitry Andric{ 854*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 855*0b57cec5SDimitry Andric if (!__pred(*__first)) 856*0b57cec5SDimitry Andric return false; 857*0b57cec5SDimitry Andric return true; 858*0b57cec5SDimitry Andric} 859*0b57cec5SDimitry Andric 860*0b57cec5SDimitry Andric// any_of 861*0b57cec5SDimitry Andric 862*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 863*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 864*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 865*0b57cec5SDimitry Andricbool 866*0b57cec5SDimitry Andricany_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 867*0b57cec5SDimitry Andric{ 868*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 869*0b57cec5SDimitry Andric if (__pred(*__first)) 870*0b57cec5SDimitry Andric return true; 871*0b57cec5SDimitry Andric return false; 872*0b57cec5SDimitry Andric} 873*0b57cec5SDimitry Andric 874*0b57cec5SDimitry Andric// none_of 875*0b57cec5SDimitry Andric 876*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 877*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 878*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 879*0b57cec5SDimitry Andricbool 880*0b57cec5SDimitry Andricnone_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 881*0b57cec5SDimitry Andric{ 882*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 883*0b57cec5SDimitry Andric if (__pred(*__first)) 884*0b57cec5SDimitry Andric return false; 885*0b57cec5SDimitry Andric return true; 886*0b57cec5SDimitry Andric} 887*0b57cec5SDimitry Andric 888*0b57cec5SDimitry Andric// for_each 889*0b57cec5SDimitry Andric 890*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _Function> 891*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 892*0b57cec5SDimitry Andric_Function 893*0b57cec5SDimitry Andricfor_each(_InputIterator __first, _InputIterator __last, _Function __f) 894*0b57cec5SDimitry Andric{ 895*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 896*0b57cec5SDimitry Andric __f(*__first); 897*0b57cec5SDimitry Andric return __f; 898*0b57cec5SDimitry Andric} 899*0b57cec5SDimitry Andric 900*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 901*0b57cec5SDimitry Andric// for_each_n 902*0b57cec5SDimitry Andric 903*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _Size, class _Function> 904*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 905*0b57cec5SDimitry Andric_InputIterator 906*0b57cec5SDimitry Andricfor_each_n(_InputIterator __first, _Size __orig_n, _Function __f) 907*0b57cec5SDimitry Andric{ 908e8d8bef9SDimitry Andric typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; 909*0b57cec5SDimitry Andric _IntegralSize __n = __orig_n; 910*0b57cec5SDimitry Andric while (__n > 0) 911*0b57cec5SDimitry Andric { 912*0b57cec5SDimitry Andric __f(*__first); 913*0b57cec5SDimitry Andric ++__first; 914*0b57cec5SDimitry Andric --__n; 915*0b57cec5SDimitry Andric } 916*0b57cec5SDimitry Andric return __first; 917*0b57cec5SDimitry Andric} 918*0b57cec5SDimitry Andric#endif 919*0b57cec5SDimitry Andric 920*0b57cec5SDimitry Andric// find 921*0b57cec5SDimitry Andric 922*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _Tp> 923*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 924*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 925*0b57cec5SDimitry Andric_InputIterator 926*0b57cec5SDimitry Andricfind(_InputIterator __first, _InputIterator __last, const _Tp& __value_) 927*0b57cec5SDimitry Andric{ 928*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 929*0b57cec5SDimitry Andric if (*__first == __value_) 930*0b57cec5SDimitry Andric break; 931*0b57cec5SDimitry Andric return __first; 932*0b57cec5SDimitry Andric} 933*0b57cec5SDimitry Andric 934*0b57cec5SDimitry Andric// find_if 935*0b57cec5SDimitry Andric 936*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 937*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 938*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 939*0b57cec5SDimitry Andric_InputIterator 940*0b57cec5SDimitry Andricfind_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) 941*0b57cec5SDimitry Andric{ 942*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 943*0b57cec5SDimitry Andric if (__pred(*__first)) 944*0b57cec5SDimitry Andric break; 945*0b57cec5SDimitry Andric return __first; 946*0b57cec5SDimitry Andric} 947*0b57cec5SDimitry Andric 948*0b57cec5SDimitry Andric// find_if_not 949*0b57cec5SDimitry Andric 950*0b57cec5SDimitry Andrictemplate<class _InputIterator, class _Predicate> 951*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 952*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 953*0b57cec5SDimitry Andric_InputIterator 954*0b57cec5SDimitry Andricfind_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) 955*0b57cec5SDimitry Andric{ 956*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 957*0b57cec5SDimitry Andric if (!__pred(*__first)) 958*0b57cec5SDimitry Andric break; 959*0b57cec5SDimitry Andric return __first; 960*0b57cec5SDimitry Andric} 961*0b57cec5SDimitry Andric 962*0b57cec5SDimitry Andric// find_end 963*0b57cec5SDimitry Andric 964*0b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> 965*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 966*0b57cec5SDimitry Andric__find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 967*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, 968*0b57cec5SDimitry Andric forward_iterator_tag, forward_iterator_tag) 969*0b57cec5SDimitry Andric{ 970*0b57cec5SDimitry Andric // modeled after search algorithm 971*0b57cec5SDimitry Andric _ForwardIterator1 __r = __last1; // __last1 is the "default" answer 972*0b57cec5SDimitry Andric if (__first2 == __last2) 973*0b57cec5SDimitry Andric return __r; 974*0b57cec5SDimitry Andric while (true) 975*0b57cec5SDimitry Andric { 976*0b57cec5SDimitry Andric while (true) 977*0b57cec5SDimitry Andric { 978*0b57cec5SDimitry Andric if (__first1 == __last1) // if source exhausted return last correct answer 979*0b57cec5SDimitry Andric return __r; // (or __last1 if never found) 980*0b57cec5SDimitry Andric if (__pred(*__first1, *__first2)) 981*0b57cec5SDimitry Andric break; 982*0b57cec5SDimitry Andric ++__first1; 983*0b57cec5SDimitry Andric } 984*0b57cec5SDimitry Andric // *__first1 matches *__first2, now match elements after here 985*0b57cec5SDimitry Andric _ForwardIterator1 __m1 = __first1; 986*0b57cec5SDimitry Andric _ForwardIterator2 __m2 = __first2; 987*0b57cec5SDimitry Andric while (true) 988*0b57cec5SDimitry Andric { 989*0b57cec5SDimitry Andric if (++__m2 == __last2) 990*0b57cec5SDimitry Andric { // Pattern exhaused, record answer and search for another one 991*0b57cec5SDimitry Andric __r = __first1; 992*0b57cec5SDimitry Andric ++__first1; 993*0b57cec5SDimitry Andric break; 994*0b57cec5SDimitry Andric } 995*0b57cec5SDimitry Andric if (++__m1 == __last1) // Source exhausted, return last answer 996*0b57cec5SDimitry Andric return __r; 997*0b57cec5SDimitry Andric if (!__pred(*__m1, *__m2)) // mismatch, restart with a new __first 998*0b57cec5SDimitry Andric { 999*0b57cec5SDimitry Andric ++__first1; 1000*0b57cec5SDimitry Andric break; 1001*0b57cec5SDimitry Andric } // else there is a match, check next elements 1002*0b57cec5SDimitry Andric } 1003*0b57cec5SDimitry Andric } 1004*0b57cec5SDimitry Andric} 1005*0b57cec5SDimitry Andric 1006*0b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2> 1007*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 1008*0b57cec5SDimitry Andric__find_end(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, 1009*0b57cec5SDimitry Andric _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, _BinaryPredicate __pred, 1010*0b57cec5SDimitry Andric bidirectional_iterator_tag, bidirectional_iterator_tag) 1011*0b57cec5SDimitry Andric{ 1012*0b57cec5SDimitry Andric // modeled after search algorithm (in reverse) 1013*0b57cec5SDimitry Andric if (__first2 == __last2) 1014*0b57cec5SDimitry Andric return __last1; // Everything matches an empty sequence 1015*0b57cec5SDimitry Andric _BidirectionalIterator1 __l1 = __last1; 1016*0b57cec5SDimitry Andric _BidirectionalIterator2 __l2 = __last2; 1017*0b57cec5SDimitry Andric --__l2; 1018*0b57cec5SDimitry Andric while (true) 1019*0b57cec5SDimitry Andric { 1020*0b57cec5SDimitry Andric // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks 1021*0b57cec5SDimitry Andric while (true) 1022*0b57cec5SDimitry Andric { 1023*0b57cec5SDimitry Andric if (__first1 == __l1) // return __last1 if no element matches *__first2 1024*0b57cec5SDimitry Andric return __last1; 1025*0b57cec5SDimitry Andric if (__pred(*--__l1, *__l2)) 1026*0b57cec5SDimitry Andric break; 1027*0b57cec5SDimitry Andric } 1028*0b57cec5SDimitry Andric // *__l1 matches *__l2, now match elements before here 1029*0b57cec5SDimitry Andric _BidirectionalIterator1 __m1 = __l1; 1030*0b57cec5SDimitry Andric _BidirectionalIterator2 __m2 = __l2; 1031*0b57cec5SDimitry Andric while (true) 1032*0b57cec5SDimitry Andric { 1033*0b57cec5SDimitry Andric if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern) 1034*0b57cec5SDimitry Andric return __m1; 1035*0b57cec5SDimitry Andric if (__m1 == __first1) // Otherwise if source exhaused, pattern not found 1036*0b57cec5SDimitry Andric return __last1; 1037*0b57cec5SDimitry Andric if (!__pred(*--__m1, *--__m2)) // if there is a mismatch, restart with a new __l1 1038*0b57cec5SDimitry Andric { 1039*0b57cec5SDimitry Andric break; 1040*0b57cec5SDimitry Andric } // else there is a match, check next elements 1041*0b57cec5SDimitry Andric } 1042*0b57cec5SDimitry Andric } 1043*0b57cec5SDimitry Andric} 1044*0b57cec5SDimitry Andric 1045*0b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> 1046*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 1047*0b57cec5SDimitry Andric__find_end(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, 1048*0b57cec5SDimitry Andric _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, 1049*0b57cec5SDimitry Andric random_access_iterator_tag, random_access_iterator_tag) 1050*0b57cec5SDimitry Andric{ 1051*0b57cec5SDimitry Andric // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern 1052*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2; 1053*0b57cec5SDimitry Andric if (__len2 == 0) 1054*0b57cec5SDimitry Andric return __last1; 1055*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1; 1056*0b57cec5SDimitry Andric if (__len1 < __len2) 1057*0b57cec5SDimitry Andric return __last1; 1058*0b57cec5SDimitry Andric const _RandomAccessIterator1 __s = __first1 + (__len2 - 1); // End of pattern match can't go before here 1059*0b57cec5SDimitry Andric _RandomAccessIterator1 __l1 = __last1; 1060*0b57cec5SDimitry Andric _RandomAccessIterator2 __l2 = __last2; 1061*0b57cec5SDimitry Andric --__l2; 1062*0b57cec5SDimitry Andric while (true) 1063*0b57cec5SDimitry Andric { 1064*0b57cec5SDimitry Andric while (true) 1065*0b57cec5SDimitry Andric { 1066*0b57cec5SDimitry Andric if (__s == __l1) 1067*0b57cec5SDimitry Andric return __last1; 1068*0b57cec5SDimitry Andric if (__pred(*--__l1, *__l2)) 1069*0b57cec5SDimitry Andric break; 1070*0b57cec5SDimitry Andric } 1071*0b57cec5SDimitry Andric _RandomAccessIterator1 __m1 = __l1; 1072*0b57cec5SDimitry Andric _RandomAccessIterator2 __m2 = __l2; 1073*0b57cec5SDimitry Andric while (true) 1074*0b57cec5SDimitry Andric { 1075*0b57cec5SDimitry Andric if (__m2 == __first2) 1076*0b57cec5SDimitry Andric return __m1; 1077*0b57cec5SDimitry Andric // no need to check range on __m1 because __s guarantees we have enough source 1078*0b57cec5SDimitry Andric if (!__pred(*--__m1, *--__m2)) 1079*0b57cec5SDimitry Andric { 1080*0b57cec5SDimitry Andric break; 1081*0b57cec5SDimitry Andric } 1082*0b57cec5SDimitry Andric } 1083*0b57cec5SDimitry Andric } 1084*0b57cec5SDimitry Andric} 1085*0b57cec5SDimitry Andric 1086*0b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 1087*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1088*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1089*0b57cec5SDimitry Andric_ForwardIterator1 1090*0b57cec5SDimitry Andricfind_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1091*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 1092*0b57cec5SDimitry Andric{ 1093*0b57cec5SDimitry Andric return _VSTD::__find_end<typename add_lvalue_reference<_BinaryPredicate>::type> 1094*0b57cec5SDimitry Andric (__first1, __last1, __first2, __last2, __pred, 1095*0b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator1>::iterator_category(), 1096*0b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator2>::iterator_category()); 1097*0b57cec5SDimitry Andric} 1098*0b57cec5SDimitry Andric 1099*0b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2> 1100*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1101*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1102*0b57cec5SDimitry Andric_ForwardIterator1 1103*0b57cec5SDimitry Andricfind_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1104*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2) 1105*0b57cec5SDimitry Andric{ 1106*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 1107*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 1108*0b57cec5SDimitry Andric return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 1109*0b57cec5SDimitry Andric} 1110*0b57cec5SDimitry Andric 1111*0b57cec5SDimitry Andric// find_first_of 1112*0b57cec5SDimitry Andric 1113*0b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 1114*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1 1115*0b57cec5SDimitry Andric__find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1116*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 1117*0b57cec5SDimitry Andric{ 1118*0b57cec5SDimitry Andric for (; __first1 != __last1; ++__first1) 1119*0b57cec5SDimitry Andric for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) 1120*0b57cec5SDimitry Andric if (__pred(*__first1, *__j)) 1121*0b57cec5SDimitry Andric return __first1; 1122*0b57cec5SDimitry Andric return __last1; 1123*0b57cec5SDimitry Andric} 1124*0b57cec5SDimitry Andric 1125*0b57cec5SDimitry Andric 1126*0b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 1127*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1128*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1129*0b57cec5SDimitry Andric_ForwardIterator1 1130*0b57cec5SDimitry Andricfind_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1131*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 1132*0b57cec5SDimitry Andric{ 1133*0b57cec5SDimitry Andric return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); 1134*0b57cec5SDimitry Andric} 1135*0b57cec5SDimitry Andric 1136*0b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2> 1137*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1138*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1139*0b57cec5SDimitry Andric_ForwardIterator1 1140*0b57cec5SDimitry Andricfind_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1141*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2) 1142*0b57cec5SDimitry Andric{ 1143*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 1144*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 1145*0b57cec5SDimitry Andric return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 1146*0b57cec5SDimitry Andric} 1147*0b57cec5SDimitry Andric 1148*0b57cec5SDimitry Andric// adjacent_find 1149*0b57cec5SDimitry Andric 1150*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _BinaryPredicate> 1151*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1152*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1153*0b57cec5SDimitry Andric_ForwardIterator 1154*0b57cec5SDimitry Andricadjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) 1155*0b57cec5SDimitry Andric{ 1156*0b57cec5SDimitry Andric if (__first != __last) 1157*0b57cec5SDimitry Andric { 1158*0b57cec5SDimitry Andric _ForwardIterator __i = __first; 1159*0b57cec5SDimitry Andric while (++__i != __last) 1160*0b57cec5SDimitry Andric { 1161*0b57cec5SDimitry Andric if (__pred(*__first, *__i)) 1162*0b57cec5SDimitry Andric return __first; 1163*0b57cec5SDimitry Andric __first = __i; 1164*0b57cec5SDimitry Andric } 1165*0b57cec5SDimitry Andric } 1166*0b57cec5SDimitry Andric return __last; 1167*0b57cec5SDimitry Andric} 1168*0b57cec5SDimitry Andric 1169*0b57cec5SDimitry Andrictemplate <class _ForwardIterator> 1170*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1171*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1172*0b57cec5SDimitry Andric_ForwardIterator 1173*0b57cec5SDimitry Andricadjacent_find(_ForwardIterator __first, _ForwardIterator __last) 1174*0b57cec5SDimitry Andric{ 1175*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type __v; 1176*0b57cec5SDimitry Andric return _VSTD::adjacent_find(__first, __last, __equal_to<__v>()); 1177*0b57cec5SDimitry Andric} 1178*0b57cec5SDimitry Andric 1179*0b57cec5SDimitry Andric// count 1180*0b57cec5SDimitry Andric 1181*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _Tp> 1182*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1183*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1184*0b57cec5SDimitry Andrictypename iterator_traits<_InputIterator>::difference_type 1185*0b57cec5SDimitry Andriccount(_InputIterator __first, _InputIterator __last, const _Tp& __value_) 1186*0b57cec5SDimitry Andric{ 1187*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator>::difference_type __r(0); 1188*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 1189*0b57cec5SDimitry Andric if (*__first == __value_) 1190*0b57cec5SDimitry Andric ++__r; 1191*0b57cec5SDimitry Andric return __r; 1192*0b57cec5SDimitry Andric} 1193*0b57cec5SDimitry Andric 1194*0b57cec5SDimitry Andric// count_if 1195*0b57cec5SDimitry Andric 1196*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 1197*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1198*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1199*0b57cec5SDimitry Andrictypename iterator_traits<_InputIterator>::difference_type 1200*0b57cec5SDimitry Andriccount_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) 1201*0b57cec5SDimitry Andric{ 1202*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator>::difference_type __r(0); 1203*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 1204*0b57cec5SDimitry Andric if (__pred(*__first)) 1205*0b57cec5SDimitry Andric ++__r; 1206*0b57cec5SDimitry Andric return __r; 1207*0b57cec5SDimitry Andric} 1208*0b57cec5SDimitry Andric 1209*0b57cec5SDimitry Andric// mismatch 1210*0b57cec5SDimitry Andric 1211*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 1212*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1213*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1214*0b57cec5SDimitry Andricpair<_InputIterator1, _InputIterator2> 1215*0b57cec5SDimitry Andricmismatch(_InputIterator1 __first1, _InputIterator1 __last1, 1216*0b57cec5SDimitry Andric _InputIterator2 __first2, _BinaryPredicate __pred) 1217*0b57cec5SDimitry Andric{ 1218*0b57cec5SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2) 1219*0b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 1220*0b57cec5SDimitry Andric break; 1221*0b57cec5SDimitry Andric return pair<_InputIterator1, _InputIterator2>(__first1, __first2); 1222*0b57cec5SDimitry Andric} 1223*0b57cec5SDimitry Andric 1224*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 1225*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1226*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1227*0b57cec5SDimitry Andricpair<_InputIterator1, _InputIterator2> 1228*0b57cec5SDimitry Andricmismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) 1229*0b57cec5SDimitry Andric{ 1230*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type __v1; 1231*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator2>::value_type __v2; 1232*0b57cec5SDimitry Andric return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>()); 1233*0b57cec5SDimitry Andric} 1234*0b57cec5SDimitry Andric 1235*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11 1236*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 1237*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1238*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1239*0b57cec5SDimitry Andricpair<_InputIterator1, _InputIterator2> 1240*0b57cec5SDimitry Andricmismatch(_InputIterator1 __first1, _InputIterator1 __last1, 1241*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, 1242*0b57cec5SDimitry Andric _BinaryPredicate __pred) 1243*0b57cec5SDimitry Andric{ 1244*0b57cec5SDimitry Andric for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) 1245*0b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 1246*0b57cec5SDimitry Andric break; 1247*0b57cec5SDimitry Andric return pair<_InputIterator1, _InputIterator2>(__first1, __first2); 1248*0b57cec5SDimitry Andric} 1249*0b57cec5SDimitry Andric 1250*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 1251*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1252*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1253*0b57cec5SDimitry Andricpair<_InputIterator1, _InputIterator2> 1254*0b57cec5SDimitry Andricmismatch(_InputIterator1 __first1, _InputIterator1 __last1, 1255*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2) 1256*0b57cec5SDimitry Andric{ 1257*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type __v1; 1258*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator2>::value_type __v2; 1259*0b57cec5SDimitry Andric return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 1260*0b57cec5SDimitry Andric} 1261*0b57cec5SDimitry Andric#endif 1262*0b57cec5SDimitry Andric 1263*0b57cec5SDimitry Andric// equal 1264*0b57cec5SDimitry Andric 1265*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 1266*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1267*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1268*0b57cec5SDimitry Andricbool 1269*0b57cec5SDimitry Andricequal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) 1270*0b57cec5SDimitry Andric{ 1271*0b57cec5SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2) 1272*0b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 1273*0b57cec5SDimitry Andric return false; 1274*0b57cec5SDimitry Andric return true; 1275*0b57cec5SDimitry Andric} 1276*0b57cec5SDimitry Andric 1277*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 1278*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1279*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1280*0b57cec5SDimitry Andricbool 1281*0b57cec5SDimitry Andricequal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) 1282*0b57cec5SDimitry Andric{ 1283*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type __v1; 1284*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator2>::value_type __v2; 1285*0b57cec5SDimitry Andric return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>()); 1286*0b57cec5SDimitry Andric} 1287*0b57cec5SDimitry Andric 1288*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11 1289*0b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _InputIterator1, class _InputIterator2> 1290*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1291*0b57cec5SDimitry Andricbool 1292*0b57cec5SDimitry Andric__equal(_InputIterator1 __first1, _InputIterator1 __last1, 1293*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred, 1294*0b57cec5SDimitry Andric input_iterator_tag, input_iterator_tag ) 1295*0b57cec5SDimitry Andric{ 1296*0b57cec5SDimitry Andric for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) 1297*0b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 1298*0b57cec5SDimitry Andric return false; 1299*0b57cec5SDimitry Andric return __first1 == __last1 && __first2 == __last2; 1300*0b57cec5SDimitry Andric} 1301*0b57cec5SDimitry Andric 1302*0b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> 1303*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1304*0b57cec5SDimitry Andricbool 1305*0b57cec5SDimitry Andric__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, 1306*0b57cec5SDimitry Andric _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, 1307*0b57cec5SDimitry Andric random_access_iterator_tag, random_access_iterator_tag ) 1308*0b57cec5SDimitry Andric{ 1309*0b57cec5SDimitry Andric if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) 1310*0b57cec5SDimitry Andric return false; 1311*0b57cec5SDimitry Andric return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2, 1312*0b57cec5SDimitry Andric typename add_lvalue_reference<_BinaryPredicate>::type> 1313*0b57cec5SDimitry Andric (__first1, __last1, __first2, __pred ); 1314*0b57cec5SDimitry Andric} 1315*0b57cec5SDimitry Andric 1316*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 1317*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1318*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1319*0b57cec5SDimitry Andricbool 1320*0b57cec5SDimitry Andricequal(_InputIterator1 __first1, _InputIterator1 __last1, 1321*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred ) 1322*0b57cec5SDimitry Andric{ 1323*0b57cec5SDimitry Andric return _VSTD::__equal<typename add_lvalue_reference<_BinaryPredicate>::type> 1324*0b57cec5SDimitry Andric (__first1, __last1, __first2, __last2, __pred, 1325*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator1>::iterator_category(), 1326*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::iterator_category()); 1327*0b57cec5SDimitry Andric} 1328*0b57cec5SDimitry Andric 1329*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 1330*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1331*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1332*0b57cec5SDimitry Andricbool 1333*0b57cec5SDimitry Andricequal(_InputIterator1 __first1, _InputIterator1 __last1, 1334*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2) 1335*0b57cec5SDimitry Andric{ 1336*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type __v1; 1337*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator2>::value_type __v2; 1338*0b57cec5SDimitry Andric return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(), 1339*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator1>::iterator_category(), 1340*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::iterator_category()); 1341*0b57cec5SDimitry Andric} 1342*0b57cec5SDimitry Andric#endif 1343*0b57cec5SDimitry Andric 1344*0b57cec5SDimitry Andric// is_permutation 1345*0b57cec5SDimitry Andric 1346*0b57cec5SDimitry Andrictemplate<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 1347*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool 1348*0b57cec5SDimitry Andricis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1349*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _BinaryPredicate __pred) 1350*0b57cec5SDimitry Andric{ 1351*0b57cec5SDimitry Andric// shorten sequences as much as possible by lopping of any equal prefix 1352*0b57cec5SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2) 1353*0b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 1354*0b57cec5SDimitry Andric break; 1355*0b57cec5SDimitry Andric if (__first1 == __last1) 1356*0b57cec5SDimitry Andric return true; 1357*0b57cec5SDimitry Andric 1358*0b57cec5SDimitry Andric// __first1 != __last1 && *__first1 != *__first2 1359*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; 1360*0b57cec5SDimitry Andric _D1 __l1 = _VSTD::distance(__first1, __last1); 1361*0b57cec5SDimitry Andric if (__l1 == _D1(1)) 1362*0b57cec5SDimitry Andric return false; 1363*0b57cec5SDimitry Andric _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1); 1364*0b57cec5SDimitry Andric // For each element in [f1, l1) see if there are the same number of 1365*0b57cec5SDimitry Andric // equal elements in [f2, l2) 1366*0b57cec5SDimitry Andric for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) 1367*0b57cec5SDimitry Andric { 1368*0b57cec5SDimitry Andric // Have we already counted the number of *__i in [f1, l1)? 1369*0b57cec5SDimitry Andric _ForwardIterator1 __match = __first1; 1370*0b57cec5SDimitry Andric for (; __match != __i; ++__match) 1371*0b57cec5SDimitry Andric if (__pred(*__match, *__i)) 1372*0b57cec5SDimitry Andric break; 1373*0b57cec5SDimitry Andric if (__match == __i) { 1374*0b57cec5SDimitry Andric // Count number of *__i in [f2, l2) 1375*0b57cec5SDimitry Andric _D1 __c2 = 0; 1376*0b57cec5SDimitry Andric for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) 1377*0b57cec5SDimitry Andric if (__pred(*__i, *__j)) 1378*0b57cec5SDimitry Andric ++__c2; 1379*0b57cec5SDimitry Andric if (__c2 == 0) 1380*0b57cec5SDimitry Andric return false; 1381*0b57cec5SDimitry Andric // Count number of *__i in [__i, l1) (we can start with 1) 1382*0b57cec5SDimitry Andric _D1 __c1 = 1; 1383*0b57cec5SDimitry Andric for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) 1384*0b57cec5SDimitry Andric if (__pred(*__i, *__j)) 1385*0b57cec5SDimitry Andric ++__c1; 1386*0b57cec5SDimitry Andric if (__c1 != __c2) 1387*0b57cec5SDimitry Andric return false; 1388*0b57cec5SDimitry Andric } 1389*0b57cec5SDimitry Andric } 1390*0b57cec5SDimitry Andric return true; 1391*0b57cec5SDimitry Andric} 1392*0b57cec5SDimitry Andric 1393*0b57cec5SDimitry Andrictemplate<class _ForwardIterator1, class _ForwardIterator2> 1394*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1395*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1396*0b57cec5SDimitry Andricbool 1397*0b57cec5SDimitry Andricis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1398*0b57cec5SDimitry Andric _ForwardIterator2 __first2) 1399*0b57cec5SDimitry Andric{ 1400*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 1401*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 1402*0b57cec5SDimitry Andric return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>()); 1403*0b57cec5SDimitry Andric} 1404*0b57cec5SDimitry Andric 1405*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11 1406*0b57cec5SDimitry Andrictemplate<class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> 1407*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 1408*0b57cec5SDimitry Andric__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1409*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, 1410*0b57cec5SDimitry Andric _BinaryPredicate __pred, 1411*0b57cec5SDimitry Andric forward_iterator_tag, forward_iterator_tag ) 1412*0b57cec5SDimitry Andric{ 1413*0b57cec5SDimitry Andric// shorten sequences as much as possible by lopping of any equal prefix 1414*0b57cec5SDimitry Andric for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) 1415*0b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 1416*0b57cec5SDimitry Andric break; 1417*0b57cec5SDimitry Andric if (__first1 == __last1) 1418*0b57cec5SDimitry Andric return __first2 == __last2; 1419*0b57cec5SDimitry Andric else if (__first2 == __last2) 1420*0b57cec5SDimitry Andric return false; 1421*0b57cec5SDimitry Andric 1422*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; 1423*0b57cec5SDimitry Andric _D1 __l1 = _VSTD::distance(__first1, __last1); 1424*0b57cec5SDimitry Andric 1425*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2; 1426*0b57cec5SDimitry Andric _D2 __l2 = _VSTD::distance(__first2, __last2); 1427*0b57cec5SDimitry Andric if (__l1 != __l2) 1428*0b57cec5SDimitry Andric return false; 1429*0b57cec5SDimitry Andric 1430*0b57cec5SDimitry Andric // For each element in [f1, l1) see if there are the same number of 1431*0b57cec5SDimitry Andric // equal elements in [f2, l2) 1432*0b57cec5SDimitry Andric for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) 1433*0b57cec5SDimitry Andric { 1434*0b57cec5SDimitry Andric // Have we already counted the number of *__i in [f1, l1)? 1435*0b57cec5SDimitry Andric _ForwardIterator1 __match = __first1; 1436*0b57cec5SDimitry Andric for (; __match != __i; ++__match) 1437*0b57cec5SDimitry Andric if (__pred(*__match, *__i)) 1438*0b57cec5SDimitry Andric break; 1439*0b57cec5SDimitry Andric if (__match == __i) { 1440*0b57cec5SDimitry Andric // Count number of *__i in [f2, l2) 1441*0b57cec5SDimitry Andric _D1 __c2 = 0; 1442*0b57cec5SDimitry Andric for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) 1443*0b57cec5SDimitry Andric if (__pred(*__i, *__j)) 1444*0b57cec5SDimitry Andric ++__c2; 1445*0b57cec5SDimitry Andric if (__c2 == 0) 1446*0b57cec5SDimitry Andric return false; 1447*0b57cec5SDimitry Andric // Count number of *__i in [__i, l1) (we can start with 1) 1448*0b57cec5SDimitry Andric _D1 __c1 = 1; 1449*0b57cec5SDimitry Andric for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) 1450*0b57cec5SDimitry Andric if (__pred(*__i, *__j)) 1451*0b57cec5SDimitry Andric ++__c1; 1452*0b57cec5SDimitry Andric if (__c1 != __c2) 1453*0b57cec5SDimitry Andric return false; 1454*0b57cec5SDimitry Andric } 1455*0b57cec5SDimitry Andric } 1456*0b57cec5SDimitry Andric return true; 1457*0b57cec5SDimitry Andric} 1458*0b57cec5SDimitry Andric 1459*0b57cec5SDimitry Andrictemplate<class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> 1460*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 1461*0b57cec5SDimitry Andric__is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1, 1462*0b57cec5SDimitry Andric _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, 1463*0b57cec5SDimitry Andric _BinaryPredicate __pred, 1464*0b57cec5SDimitry Andric random_access_iterator_tag, random_access_iterator_tag ) 1465*0b57cec5SDimitry Andric{ 1466*0b57cec5SDimitry Andric if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) 1467*0b57cec5SDimitry Andric return false; 1468*0b57cec5SDimitry Andric return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2, 1469*0b57cec5SDimitry Andric typename add_lvalue_reference<_BinaryPredicate>::type> 1470*0b57cec5SDimitry Andric (__first1, __last1, __first2, __pred ); 1471*0b57cec5SDimitry Andric} 1472*0b57cec5SDimitry Andric 1473*0b57cec5SDimitry Andrictemplate<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 1474*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1475*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1476*0b57cec5SDimitry Andricbool 1477*0b57cec5SDimitry Andricis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1478*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, 1479*0b57cec5SDimitry Andric _BinaryPredicate __pred ) 1480*0b57cec5SDimitry Andric{ 1481*0b57cec5SDimitry Andric return _VSTD::__is_permutation<typename add_lvalue_reference<_BinaryPredicate>::type> 1482*0b57cec5SDimitry Andric (__first1, __last1, __first2, __last2, __pred, 1483*0b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator1>::iterator_category(), 1484*0b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator2>::iterator_category()); 1485*0b57cec5SDimitry Andric} 1486*0b57cec5SDimitry Andric 1487*0b57cec5SDimitry Andrictemplate<class _ForwardIterator1, class _ForwardIterator2> 1488*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1489*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1490*0b57cec5SDimitry Andricbool 1491*0b57cec5SDimitry Andricis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1492*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2) 1493*0b57cec5SDimitry Andric{ 1494*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 1495*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 1496*0b57cec5SDimitry Andric return _VSTD::__is_permutation(__first1, __last1, __first2, __last2, 1497*0b57cec5SDimitry Andric __equal_to<__v1, __v2>(), 1498*0b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator1>::iterator_category(), 1499*0b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator2>::iterator_category()); 1500*0b57cec5SDimitry Andric} 1501*0b57cec5SDimitry Andric#endif 1502*0b57cec5SDimitry Andric 1503*0b57cec5SDimitry Andric// search 1504*0b57cec5SDimitry Andric// __search is in <functional> 1505*0b57cec5SDimitry Andric 1506*0b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 1507*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1508*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1509*0b57cec5SDimitry Andric_ForwardIterator1 1510*0b57cec5SDimitry Andricsearch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1511*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 1512*0b57cec5SDimitry Andric{ 1513*0b57cec5SDimitry Andric return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type> 1514*0b57cec5SDimitry Andric (__first1, __last1, __first2, __last2, __pred, 1515*0b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator1>::iterator_category(), 1516*0b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator2>::iterator_category()) 1517*0b57cec5SDimitry Andric .first; 1518*0b57cec5SDimitry Andric} 1519*0b57cec5SDimitry Andric 1520*0b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2> 1521*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1522*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1523*0b57cec5SDimitry Andric_ForwardIterator1 1524*0b57cec5SDimitry Andricsearch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1525*0b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2) 1526*0b57cec5SDimitry Andric{ 1527*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 1528*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 1529*0b57cec5SDimitry Andric return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 1530*0b57cec5SDimitry Andric} 1531*0b57cec5SDimitry Andric 1532*0b57cec5SDimitry Andric 1533*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 1534*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Searcher> 1535*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1536*0b57cec5SDimitry Andric_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s) 1537*0b57cec5SDimitry Andric{ return __s(__f, __l).first; } 1538*0b57cec5SDimitry Andric#endif 1539*0b57cec5SDimitry Andric 1540*0b57cec5SDimitry Andric// search_n 1541*0b57cec5SDimitry Andric 1542*0b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp> 1543*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 1544*0b57cec5SDimitry Andric__search_n(_ForwardIterator __first, _ForwardIterator __last, 1545*0b57cec5SDimitry Andric _Size __count, const _Tp& __value_, _BinaryPredicate __pred, forward_iterator_tag) 1546*0b57cec5SDimitry Andric{ 1547*0b57cec5SDimitry Andric if (__count <= 0) 1548*0b57cec5SDimitry Andric return __first; 1549*0b57cec5SDimitry Andric while (true) 1550*0b57cec5SDimitry Andric { 1551*0b57cec5SDimitry Andric // Find first element in sequence that matchs __value_, with a mininum of loop checks 1552*0b57cec5SDimitry Andric while (true) 1553*0b57cec5SDimitry Andric { 1554*0b57cec5SDimitry Andric if (__first == __last) // return __last if no element matches __value_ 1555*0b57cec5SDimitry Andric return __last; 1556*0b57cec5SDimitry Andric if (__pred(*__first, __value_)) 1557*0b57cec5SDimitry Andric break; 1558*0b57cec5SDimitry Andric ++__first; 1559*0b57cec5SDimitry Andric } 1560*0b57cec5SDimitry Andric // *__first matches __value_, now match elements after here 1561*0b57cec5SDimitry Andric _ForwardIterator __m = __first; 1562*0b57cec5SDimitry Andric _Size __c(0); 1563*0b57cec5SDimitry Andric while (true) 1564*0b57cec5SDimitry Andric { 1565*0b57cec5SDimitry Andric if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) 1566*0b57cec5SDimitry Andric return __first; 1567*0b57cec5SDimitry Andric if (++__m == __last) // Otherwise if source exhaused, pattern not found 1568*0b57cec5SDimitry Andric return __last; 1569*0b57cec5SDimitry Andric if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first 1570*0b57cec5SDimitry Andric { 1571*0b57cec5SDimitry Andric __first = __m; 1572*0b57cec5SDimitry Andric ++__first; 1573*0b57cec5SDimitry Andric break; 1574*0b57cec5SDimitry Andric } // else there is a match, check next elements 1575*0b57cec5SDimitry Andric } 1576*0b57cec5SDimitry Andric } 1577*0b57cec5SDimitry Andric} 1578*0b57cec5SDimitry Andric 1579*0b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp> 1580*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator 1581*0b57cec5SDimitry Andric__search_n(_RandomAccessIterator __first, _RandomAccessIterator __last, 1582*0b57cec5SDimitry Andric _Size __count, const _Tp& __value_, _BinaryPredicate __pred, random_access_iterator_tag) 1583*0b57cec5SDimitry Andric{ 1584*0b57cec5SDimitry Andric if (__count <= 0) 1585*0b57cec5SDimitry Andric return __first; 1586*0b57cec5SDimitry Andric _Size __len = static_cast<_Size>(__last - __first); 1587*0b57cec5SDimitry Andric if (__len < __count) 1588*0b57cec5SDimitry Andric return __last; 1589*0b57cec5SDimitry Andric const _RandomAccessIterator __s = __last - (__count - 1); // Start of pattern match can't go beyond here 1590*0b57cec5SDimitry Andric while (true) 1591*0b57cec5SDimitry Andric { 1592*0b57cec5SDimitry Andric // Find first element in sequence that matchs __value_, with a mininum of loop checks 1593*0b57cec5SDimitry Andric while (true) 1594*0b57cec5SDimitry Andric { 1595*0b57cec5SDimitry Andric if (__first >= __s) // return __last if no element matches __value_ 1596*0b57cec5SDimitry Andric return __last; 1597*0b57cec5SDimitry Andric if (__pred(*__first, __value_)) 1598*0b57cec5SDimitry Andric break; 1599*0b57cec5SDimitry Andric ++__first; 1600*0b57cec5SDimitry Andric } 1601*0b57cec5SDimitry Andric // *__first matches __value_, now match elements after here 1602*0b57cec5SDimitry Andric _RandomAccessIterator __m = __first; 1603*0b57cec5SDimitry Andric _Size __c(0); 1604*0b57cec5SDimitry Andric while (true) 1605*0b57cec5SDimitry Andric { 1606*0b57cec5SDimitry Andric if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) 1607*0b57cec5SDimitry Andric return __first; 1608*0b57cec5SDimitry Andric ++__m; // no need to check range on __m because __s guarantees we have enough source 1609*0b57cec5SDimitry Andric if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first 1610*0b57cec5SDimitry Andric { 1611*0b57cec5SDimitry Andric __first = __m; 1612*0b57cec5SDimitry Andric ++__first; 1613*0b57cec5SDimitry Andric break; 1614*0b57cec5SDimitry Andric } // else there is a match, check next elements 1615*0b57cec5SDimitry Andric } 1616*0b57cec5SDimitry Andric } 1617*0b57cec5SDimitry Andric} 1618*0b57cec5SDimitry Andric 1619*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> 1620*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1621*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1622*0b57cec5SDimitry Andric_ForwardIterator 1623*0b57cec5SDimitry Andricsearch_n(_ForwardIterator __first, _ForwardIterator __last, 1624*0b57cec5SDimitry Andric _Size __count, const _Tp& __value_, _BinaryPredicate __pred) 1625*0b57cec5SDimitry Andric{ 1626*0b57cec5SDimitry Andric return _VSTD::__search_n<typename add_lvalue_reference<_BinaryPredicate>::type> 1627e8d8bef9SDimitry Andric (__first, __last, _VSTD::__convert_to_integral(__count), __value_, __pred, 1628*0b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator>::iterator_category()); 1629*0b57cec5SDimitry Andric} 1630*0b57cec5SDimitry Andric 1631*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size, class _Tp> 1632*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 1633*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1634*0b57cec5SDimitry Andric_ForwardIterator 1635*0b57cec5SDimitry Andricsearch_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_) 1636*0b57cec5SDimitry Andric{ 1637*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type __v; 1638e8d8bef9SDimitry Andric return _VSTD::search_n(__first, __last, _VSTD::__convert_to_integral(__count), 1639*0b57cec5SDimitry Andric __value_, __equal_to<__v, _Tp>()); 1640*0b57cec5SDimitry Andric} 1641*0b57cec5SDimitry Andric 1642*0b57cec5SDimitry Andric// copy 1643*0b57cec5SDimitry Andrictemplate <class _Iter> 1644e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1645*0b57cec5SDimitry Andric_Iter 1646*0b57cec5SDimitry Andric__unwrap_iter(_Iter __i) 1647*0b57cec5SDimitry Andric{ 1648*0b57cec5SDimitry Andric return __i; 1649*0b57cec5SDimitry Andric} 1650*0b57cec5SDimitry Andric 1651*0b57cec5SDimitry Andrictemplate <class _Tp> 1652e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1653*0b57cec5SDimitry Andrictypename enable_if 1654*0b57cec5SDimitry Andric< 1655*0b57cec5SDimitry Andric is_trivially_copy_assignable<_Tp>::value, 1656*0b57cec5SDimitry Andric _Tp* 1657*0b57cec5SDimitry Andric>::type 1658*0b57cec5SDimitry Andric__unwrap_iter(move_iterator<_Tp*> __i) 1659*0b57cec5SDimitry Andric{ 1660*0b57cec5SDimitry Andric return __i.base(); 1661*0b57cec5SDimitry Andric} 1662*0b57cec5SDimitry Andric 1663*0b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL < 2 1664*0b57cec5SDimitry Andric 1665*0b57cec5SDimitry Andrictemplate <class _Tp> 1666e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1667*0b57cec5SDimitry Andrictypename enable_if 1668*0b57cec5SDimitry Andric< 1669*0b57cec5SDimitry Andric is_trivially_copy_assignable<_Tp>::value, 1670*0b57cec5SDimitry Andric _Tp* 1671*0b57cec5SDimitry Andric>::type 1672*0b57cec5SDimitry Andric__unwrap_iter(__wrap_iter<_Tp*> __i) 1673*0b57cec5SDimitry Andric{ 1674*0b57cec5SDimitry Andric return __i.base(); 1675*0b57cec5SDimitry Andric} 1676*0b57cec5SDimitry Andric 1677*0b57cec5SDimitry Andrictemplate <class _Tp> 1678e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1679*0b57cec5SDimitry Andrictypename enable_if 1680*0b57cec5SDimitry Andric< 1681*0b57cec5SDimitry Andric is_trivially_copy_assignable<_Tp>::value, 1682*0b57cec5SDimitry Andric const _Tp* 1683*0b57cec5SDimitry Andric>::type 1684*0b57cec5SDimitry Andric__unwrap_iter(__wrap_iter<const _Tp*> __i) 1685*0b57cec5SDimitry Andric{ 1686*0b57cec5SDimitry Andric return __i.base(); 1687*0b57cec5SDimitry Andric} 1688*0b57cec5SDimitry Andric 1689*0b57cec5SDimitry Andric#else 1690*0b57cec5SDimitry Andric 1691*0b57cec5SDimitry Andrictemplate <class _Tp> 1692e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1693*0b57cec5SDimitry Andrictypename enable_if 1694*0b57cec5SDimitry Andric< 1695*0b57cec5SDimitry Andric is_trivially_copy_assignable<_Tp>::value, 1696*0b57cec5SDimitry Andric __wrap_iter<_Tp*> 1697*0b57cec5SDimitry Andric>::type 1698*0b57cec5SDimitry Andric__unwrap_iter(__wrap_iter<_Tp*> __i) 1699*0b57cec5SDimitry Andric{ 1700*0b57cec5SDimitry Andric return __i; 1701*0b57cec5SDimitry Andric} 1702*0b57cec5SDimitry Andric 1703*0b57cec5SDimitry Andric#endif // _LIBCPP_DEBUG_LEVEL < 2 1704*0b57cec5SDimitry Andric 1705*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 1706480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1707*0b57cec5SDimitry Andric_OutputIterator 1708480093f4SDimitry Andric__copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 1709*0b57cec5SDimitry Andric{ 1710*0b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 1711*0b57cec5SDimitry Andric *__result = *__first; 1712*0b57cec5SDimitry Andric return __result; 1713*0b57cec5SDimitry Andric} 1714*0b57cec5SDimitry Andric 1715480093f4SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 1716480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 1717480093f4SDimitry Andric_OutputIterator 1718480093f4SDimitry Andric__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 1719480093f4SDimitry Andric{ 1720e8d8bef9SDimitry Andric return _VSTD::__copy_constexpr(__first, __last, __result); 1721480093f4SDimitry Andric} 1722480093f4SDimitry Andric 1723*0b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 1724*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 1725*0b57cec5SDimitry Andrictypename enable_if 1726*0b57cec5SDimitry Andric< 1727*0b57cec5SDimitry Andric is_same<typename remove_const<_Tp>::type, _Up>::value && 1728*0b57cec5SDimitry Andric is_trivially_copy_assignable<_Up>::value, 1729*0b57cec5SDimitry Andric _Up* 1730*0b57cec5SDimitry Andric>::type 1731*0b57cec5SDimitry Andric__copy(_Tp* __first, _Tp* __last, _Up* __result) 1732*0b57cec5SDimitry Andric{ 1733*0b57cec5SDimitry Andric const size_t __n = static_cast<size_t>(__last - __first); 1734*0b57cec5SDimitry Andric if (__n > 0) 1735*0b57cec5SDimitry Andric _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 1736*0b57cec5SDimitry Andric return __result + __n; 1737*0b57cec5SDimitry Andric} 1738*0b57cec5SDimitry Andric 1739*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 1740e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1741*0b57cec5SDimitry Andric_OutputIterator 1742*0b57cec5SDimitry Andriccopy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 1743*0b57cec5SDimitry Andric{ 1744480093f4SDimitry Andric if (__libcpp_is_constant_evaluated()) { 1745480093f4SDimitry Andric return _VSTD::__copy_constexpr( 1746e8d8bef9SDimitry Andric _VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _VSTD::__unwrap_iter(__result)); 1747480093f4SDimitry Andric } else { 1748480093f4SDimitry Andric return _VSTD::__copy( 1749e8d8bef9SDimitry Andric _VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _VSTD::__unwrap_iter(__result)); 1750480093f4SDimitry Andric } 1751*0b57cec5SDimitry Andric} 1752*0b57cec5SDimitry Andric 1753*0b57cec5SDimitry Andric// copy_backward 1754*0b57cec5SDimitry Andric 1755*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator, class _OutputIterator> 1756480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1757480093f4SDimitry Andric_OutputIterator 1758480093f4SDimitry Andric__copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 1759480093f4SDimitry Andric{ 1760480093f4SDimitry Andric while (__first != __last) 1761480093f4SDimitry Andric *--__result = *--__last; 1762480093f4SDimitry Andric return __result; 1763480093f4SDimitry Andric} 1764480093f4SDimitry Andric 1765480093f4SDimitry Andrictemplate <class _BidirectionalIterator, class _OutputIterator> 1766*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 1767*0b57cec5SDimitry Andric_OutputIterator 1768*0b57cec5SDimitry Andric__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 1769*0b57cec5SDimitry Andric{ 1770e8d8bef9SDimitry Andric return _VSTD::__copy_backward_constexpr(__first, __last, __result); 1771*0b57cec5SDimitry Andric} 1772*0b57cec5SDimitry Andric 1773*0b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 1774*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 1775*0b57cec5SDimitry Andrictypename enable_if 1776*0b57cec5SDimitry Andric< 1777*0b57cec5SDimitry Andric is_same<typename remove_const<_Tp>::type, _Up>::value && 1778*0b57cec5SDimitry Andric is_trivially_copy_assignable<_Up>::value, 1779*0b57cec5SDimitry Andric _Up* 1780*0b57cec5SDimitry Andric>::type 1781*0b57cec5SDimitry Andric__copy_backward(_Tp* __first, _Tp* __last, _Up* __result) 1782*0b57cec5SDimitry Andric{ 1783*0b57cec5SDimitry Andric const size_t __n = static_cast<size_t>(__last - __first); 1784*0b57cec5SDimitry Andric if (__n > 0) 1785*0b57cec5SDimitry Andric { 1786*0b57cec5SDimitry Andric __result -= __n; 1787*0b57cec5SDimitry Andric _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 1788*0b57cec5SDimitry Andric } 1789*0b57cec5SDimitry Andric return __result; 1790*0b57cec5SDimitry Andric} 1791*0b57cec5SDimitry Andric 1792*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator1, class _BidirectionalIterator2> 1793e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1794*0b57cec5SDimitry Andric_BidirectionalIterator2 1795*0b57cec5SDimitry Andriccopy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, 1796*0b57cec5SDimitry Andric _BidirectionalIterator2 __result) 1797*0b57cec5SDimitry Andric{ 1798480093f4SDimitry Andric if (__libcpp_is_constant_evaluated()) { 1799e8d8bef9SDimitry Andric return _VSTD::__copy_backward_constexpr(_VSTD::__unwrap_iter(__first), 1800e8d8bef9SDimitry Andric _VSTD::__unwrap_iter(__last), 1801e8d8bef9SDimitry Andric _VSTD::__unwrap_iter(__result)); 1802480093f4SDimitry Andric } else { 1803e8d8bef9SDimitry Andric return _VSTD::__copy_backward(_VSTD::__unwrap_iter(__first), 1804e8d8bef9SDimitry Andric _VSTD::__unwrap_iter(__last), 1805e8d8bef9SDimitry Andric _VSTD::__unwrap_iter(__result)); 1806*0b57cec5SDimitry Andric } 1807480093f4SDimitry Andric} 1808*0b57cec5SDimitry Andric 1809*0b57cec5SDimitry Andric// copy_if 1810*0b57cec5SDimitry Andric 1811*0b57cec5SDimitry Andrictemplate<class _InputIterator, class _OutputIterator, class _Predicate> 1812480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1813*0b57cec5SDimitry Andric_OutputIterator 1814*0b57cec5SDimitry Andriccopy_if(_InputIterator __first, _InputIterator __last, 1815*0b57cec5SDimitry Andric _OutputIterator __result, _Predicate __pred) 1816*0b57cec5SDimitry Andric{ 1817*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 1818*0b57cec5SDimitry Andric { 1819*0b57cec5SDimitry Andric if (__pred(*__first)) 1820*0b57cec5SDimitry Andric { 1821*0b57cec5SDimitry Andric *__result = *__first; 1822*0b57cec5SDimitry Andric ++__result; 1823*0b57cec5SDimitry Andric } 1824*0b57cec5SDimitry Andric } 1825*0b57cec5SDimitry Andric return __result; 1826*0b57cec5SDimitry Andric} 1827*0b57cec5SDimitry Andric 1828*0b57cec5SDimitry Andric// copy_n 1829*0b57cec5SDimitry Andric 1830*0b57cec5SDimitry Andrictemplate<class _InputIterator, class _Size, class _OutputIterator> 1831e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1832*0b57cec5SDimitry Andrictypename enable_if 1833*0b57cec5SDimitry Andric< 1834480093f4SDimitry Andric __is_cpp17_input_iterator<_InputIterator>::value && 1835480093f4SDimitry Andric !__is_cpp17_random_access_iterator<_InputIterator>::value, 1836*0b57cec5SDimitry Andric _OutputIterator 1837*0b57cec5SDimitry Andric>::type 1838*0b57cec5SDimitry Andriccopy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) 1839*0b57cec5SDimitry Andric{ 1840e8d8bef9SDimitry Andric typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; 1841*0b57cec5SDimitry Andric _IntegralSize __n = __orig_n; 1842*0b57cec5SDimitry Andric if (__n > 0) 1843*0b57cec5SDimitry Andric { 1844*0b57cec5SDimitry Andric *__result = *__first; 1845*0b57cec5SDimitry Andric ++__result; 1846*0b57cec5SDimitry Andric for (--__n; __n > 0; --__n) 1847*0b57cec5SDimitry Andric { 1848*0b57cec5SDimitry Andric ++__first; 1849*0b57cec5SDimitry Andric *__result = *__first; 1850*0b57cec5SDimitry Andric ++__result; 1851*0b57cec5SDimitry Andric } 1852*0b57cec5SDimitry Andric } 1853*0b57cec5SDimitry Andric return __result; 1854*0b57cec5SDimitry Andric} 1855*0b57cec5SDimitry Andric 1856*0b57cec5SDimitry Andrictemplate<class _InputIterator, class _Size, class _OutputIterator> 1857e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1858*0b57cec5SDimitry Andrictypename enable_if 1859*0b57cec5SDimitry Andric< 1860480093f4SDimitry Andric __is_cpp17_random_access_iterator<_InputIterator>::value, 1861*0b57cec5SDimitry Andric _OutputIterator 1862*0b57cec5SDimitry Andric>::type 1863*0b57cec5SDimitry Andriccopy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) 1864*0b57cec5SDimitry Andric{ 1865e8d8bef9SDimitry Andric typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; 1866*0b57cec5SDimitry Andric _IntegralSize __n = __orig_n; 1867*0b57cec5SDimitry Andric return _VSTD::copy(__first, __first + __n, __result); 1868*0b57cec5SDimitry Andric} 1869*0b57cec5SDimitry Andric 1870*0b57cec5SDimitry Andric// move 1871*0b57cec5SDimitry Andric 1872e8d8bef9SDimitry Andric// __move_constexpr exists so that __move doesn't call itself when delegating to the constexpr 1873e8d8bef9SDimitry Andric// version of __move. 1874*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 1875e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 1876*0b57cec5SDimitry Andric_OutputIterator 1877e8d8bef9SDimitry Andric__move_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 1878*0b57cec5SDimitry Andric{ 1879*0b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 1880*0b57cec5SDimitry Andric *__result = _VSTD::move(*__first); 1881*0b57cec5SDimitry Andric return __result; 1882*0b57cec5SDimitry Andric} 1883*0b57cec5SDimitry Andric 1884e8d8bef9SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 1885e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 1886e8d8bef9SDimitry Andric_OutputIterator 1887e8d8bef9SDimitry Andric__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 1888e8d8bef9SDimitry Andric{ 1889e8d8bef9SDimitry Andric return _VSTD::__move_constexpr(__first, __last, __result); 1890e8d8bef9SDimitry Andric} 1891e8d8bef9SDimitry Andric 1892*0b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 1893e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 1894*0b57cec5SDimitry Andrictypename enable_if 1895*0b57cec5SDimitry Andric< 1896*0b57cec5SDimitry Andric is_same<typename remove_const<_Tp>::type, _Up>::value && 1897*0b57cec5SDimitry Andric is_trivially_copy_assignable<_Up>::value, 1898*0b57cec5SDimitry Andric _Up* 1899*0b57cec5SDimitry Andric>::type 1900*0b57cec5SDimitry Andric__move(_Tp* __first, _Tp* __last, _Up* __result) 1901*0b57cec5SDimitry Andric{ 1902e8d8bef9SDimitry Andric if (__libcpp_is_constant_evaluated()) 1903e8d8bef9SDimitry Andric return _VSTD::__move_constexpr(__first, __last, __result); 1904*0b57cec5SDimitry Andric const size_t __n = static_cast<size_t>(__last - __first); 1905*0b57cec5SDimitry Andric if (__n > 0) 1906*0b57cec5SDimitry Andric _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 1907*0b57cec5SDimitry Andric return __result + __n; 1908*0b57cec5SDimitry Andric} 1909*0b57cec5SDimitry Andric 1910*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 1911e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1912*0b57cec5SDimitry Andric_OutputIterator 1913*0b57cec5SDimitry Andricmove(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 1914*0b57cec5SDimitry Andric{ 1915e8d8bef9SDimitry Andric return _VSTD::__move(_VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _VSTD::__unwrap_iter(__result)); 1916*0b57cec5SDimitry Andric} 1917*0b57cec5SDimitry Andric 1918*0b57cec5SDimitry Andric// move_backward 1919*0b57cec5SDimitry Andric 1920e8d8bef9SDimitry Andric// __move_backward_constexpr exists so that __move_backward doesn't call itself when delegating to 1921e8d8bef9SDimitry Andric// the constexpr version of __move_backward. 1922*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 1923e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 1924*0b57cec5SDimitry Andric_OutputIterator 1925e8d8bef9SDimitry Andric__move_backward_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 1926*0b57cec5SDimitry Andric{ 1927*0b57cec5SDimitry Andric while (__first != __last) 1928*0b57cec5SDimitry Andric *--__result = _VSTD::move(*--__last); 1929*0b57cec5SDimitry Andric return __result; 1930*0b57cec5SDimitry Andric} 1931*0b57cec5SDimitry Andric 1932e8d8bef9SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 1933e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 1934e8d8bef9SDimitry Andric_OutputIterator 1935e8d8bef9SDimitry Andric__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 1936e8d8bef9SDimitry Andric{ 1937e8d8bef9SDimitry Andric return _VSTD::__move_backward_constexpr(__first, __last, __result); 1938e8d8bef9SDimitry Andric} 1939e8d8bef9SDimitry Andric 1940*0b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 1941e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 1942*0b57cec5SDimitry Andrictypename enable_if 1943*0b57cec5SDimitry Andric< 1944*0b57cec5SDimitry Andric is_same<typename remove_const<_Tp>::type, _Up>::value && 1945*0b57cec5SDimitry Andric is_trivially_copy_assignable<_Up>::value, 1946*0b57cec5SDimitry Andric _Up* 1947*0b57cec5SDimitry Andric>::type 1948*0b57cec5SDimitry Andric__move_backward(_Tp* __first, _Tp* __last, _Up* __result) 1949*0b57cec5SDimitry Andric{ 1950e8d8bef9SDimitry Andric if (__libcpp_is_constant_evaluated()) 1951e8d8bef9SDimitry Andric return _VSTD::__move_backward_constexpr(__first, __last, __result); 1952*0b57cec5SDimitry Andric const size_t __n = static_cast<size_t>(__last - __first); 1953*0b57cec5SDimitry Andric if (__n > 0) 1954*0b57cec5SDimitry Andric { 1955*0b57cec5SDimitry Andric __result -= __n; 1956*0b57cec5SDimitry Andric _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 1957*0b57cec5SDimitry Andric } 1958*0b57cec5SDimitry Andric return __result; 1959*0b57cec5SDimitry Andric} 1960*0b57cec5SDimitry Andric 1961*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator1, class _BidirectionalIterator2> 1962e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1963*0b57cec5SDimitry Andric_BidirectionalIterator2 1964*0b57cec5SDimitry Andricmove_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, 1965*0b57cec5SDimitry Andric _BidirectionalIterator2 __result) 1966*0b57cec5SDimitry Andric{ 1967e8d8bef9SDimitry Andric return _VSTD::__move_backward(_VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _VSTD::__unwrap_iter(__result)); 1968*0b57cec5SDimitry Andric} 1969*0b57cec5SDimitry Andric 1970*0b57cec5SDimitry Andric// iter_swap 1971*0b57cec5SDimitry Andric 1972*0b57cec5SDimitry Andric// moved to <type_traits> for better swap / noexcept support 1973*0b57cec5SDimitry Andric 1974*0b57cec5SDimitry Andric// transform 1975*0b57cec5SDimitry Andric 1976*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _UnaryOperation> 1977*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1978*0b57cec5SDimitry Andric_OutputIterator 1979*0b57cec5SDimitry Andrictransform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) 1980*0b57cec5SDimitry Andric{ 1981*0b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 1982*0b57cec5SDimitry Andric *__result = __op(*__first); 1983*0b57cec5SDimitry Andric return __result; 1984*0b57cec5SDimitry Andric} 1985*0b57cec5SDimitry Andric 1986*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation> 1987*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1988*0b57cec5SDimitry Andric_OutputIterator 1989*0b57cec5SDimitry Andrictransform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, 1990*0b57cec5SDimitry Andric _OutputIterator __result, _BinaryOperation __binary_op) 1991*0b57cec5SDimitry Andric{ 1992*0b57cec5SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result) 1993*0b57cec5SDimitry Andric *__result = __binary_op(*__first1, *__first2); 1994*0b57cec5SDimitry Andric return __result; 1995*0b57cec5SDimitry Andric} 1996*0b57cec5SDimitry Andric 1997*0b57cec5SDimitry Andric// replace 1998*0b57cec5SDimitry Andric 1999*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 2000*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2001*0b57cec5SDimitry Andricvoid 2002*0b57cec5SDimitry Andricreplace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) 2003*0b57cec5SDimitry Andric{ 2004*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 2005*0b57cec5SDimitry Andric if (*__first == __old_value) 2006*0b57cec5SDimitry Andric *__first = __new_value; 2007*0b57cec5SDimitry Andric} 2008*0b57cec5SDimitry Andric 2009*0b57cec5SDimitry Andric// replace_if 2010*0b57cec5SDimitry Andric 2011*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Predicate, class _Tp> 2012*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2013*0b57cec5SDimitry Andricvoid 2014*0b57cec5SDimitry Andricreplace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) 2015*0b57cec5SDimitry Andric{ 2016*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 2017*0b57cec5SDimitry Andric if (__pred(*__first)) 2018*0b57cec5SDimitry Andric *__first = __new_value; 2019*0b57cec5SDimitry Andric} 2020*0b57cec5SDimitry Andric 2021*0b57cec5SDimitry Andric// replace_copy 2022*0b57cec5SDimitry Andric 2023*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Tp> 2024*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2025*0b57cec5SDimitry Andric_OutputIterator 2026*0b57cec5SDimitry Andricreplace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, 2027*0b57cec5SDimitry Andric const _Tp& __old_value, const _Tp& __new_value) 2028*0b57cec5SDimitry Andric{ 2029*0b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 2030*0b57cec5SDimitry Andric if (*__first == __old_value) 2031*0b57cec5SDimitry Andric *__result = __new_value; 2032*0b57cec5SDimitry Andric else 2033*0b57cec5SDimitry Andric *__result = *__first; 2034*0b57cec5SDimitry Andric return __result; 2035*0b57cec5SDimitry Andric} 2036*0b57cec5SDimitry Andric 2037*0b57cec5SDimitry Andric// replace_copy_if 2038*0b57cec5SDimitry Andric 2039*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp> 2040*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2041*0b57cec5SDimitry Andric_OutputIterator 2042*0b57cec5SDimitry Andricreplace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, 2043*0b57cec5SDimitry Andric _Predicate __pred, const _Tp& __new_value) 2044*0b57cec5SDimitry Andric{ 2045*0b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 2046*0b57cec5SDimitry Andric if (__pred(*__first)) 2047*0b57cec5SDimitry Andric *__result = __new_value; 2048*0b57cec5SDimitry Andric else 2049*0b57cec5SDimitry Andric *__result = *__first; 2050*0b57cec5SDimitry Andric return __result; 2051*0b57cec5SDimitry Andric} 2052*0b57cec5SDimitry Andric 2053*0b57cec5SDimitry Andric// fill_n 2054*0b57cec5SDimitry Andric 2055*0b57cec5SDimitry Andrictemplate <class _OutputIterator, class _Size, class _Tp> 2056*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2057*0b57cec5SDimitry Andric_OutputIterator 2058*0b57cec5SDimitry Andric__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) 2059*0b57cec5SDimitry Andric{ 2060*0b57cec5SDimitry Andric for (; __n > 0; ++__first, (void) --__n) 2061*0b57cec5SDimitry Andric *__first = __value_; 2062*0b57cec5SDimitry Andric return __first; 2063*0b57cec5SDimitry Andric} 2064*0b57cec5SDimitry Andric 2065*0b57cec5SDimitry Andrictemplate <class _OutputIterator, class _Size, class _Tp> 2066*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2067*0b57cec5SDimitry Andric_OutputIterator 2068*0b57cec5SDimitry Andricfill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) 2069*0b57cec5SDimitry Andric{ 2070e8d8bef9SDimitry Andric return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value_); 2071*0b57cec5SDimitry Andric} 2072*0b57cec5SDimitry Andric 2073*0b57cec5SDimitry Andric// fill 2074*0b57cec5SDimitry Andric 2075*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 2076*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2077*0b57cec5SDimitry Andricvoid 2078*0b57cec5SDimitry Andric__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag) 2079*0b57cec5SDimitry Andric{ 2080*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 2081*0b57cec5SDimitry Andric *__first = __value_; 2082*0b57cec5SDimitry Andric} 2083*0b57cec5SDimitry Andric 2084*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Tp> 2085*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2086*0b57cec5SDimitry Andricvoid 2087*0b57cec5SDimitry Andric__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag) 2088*0b57cec5SDimitry Andric{ 2089*0b57cec5SDimitry Andric _VSTD::fill_n(__first, __last - __first, __value_); 2090*0b57cec5SDimitry Andric} 2091*0b57cec5SDimitry Andric 2092*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 2093*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2094*0b57cec5SDimitry Andricvoid 2095*0b57cec5SDimitry Andricfill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 2096*0b57cec5SDimitry Andric{ 2097*0b57cec5SDimitry Andric _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category()); 2098*0b57cec5SDimitry Andric} 2099*0b57cec5SDimitry Andric 2100*0b57cec5SDimitry Andric// generate 2101*0b57cec5SDimitry Andric 2102*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Generator> 2103*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2104*0b57cec5SDimitry Andricvoid 2105*0b57cec5SDimitry Andricgenerate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) 2106*0b57cec5SDimitry Andric{ 2107*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 2108*0b57cec5SDimitry Andric *__first = __gen(); 2109*0b57cec5SDimitry Andric} 2110*0b57cec5SDimitry Andric 2111*0b57cec5SDimitry Andric// generate_n 2112*0b57cec5SDimitry Andric 2113*0b57cec5SDimitry Andrictemplate <class _OutputIterator, class _Size, class _Generator> 2114*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2115*0b57cec5SDimitry Andric_OutputIterator 2116*0b57cec5SDimitry Andricgenerate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) 2117*0b57cec5SDimitry Andric{ 2118e8d8bef9SDimitry Andric typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; 2119*0b57cec5SDimitry Andric _IntegralSize __n = __orig_n; 2120*0b57cec5SDimitry Andric for (; __n > 0; ++__first, (void) --__n) 2121*0b57cec5SDimitry Andric *__first = __gen(); 2122*0b57cec5SDimitry Andric return __first; 2123*0b57cec5SDimitry Andric} 2124*0b57cec5SDimitry Andric 2125*0b57cec5SDimitry Andric// remove 2126*0b57cec5SDimitry Andric 2127*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 2128*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 2129*0b57cec5SDimitry Andricremove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 2130*0b57cec5SDimitry Andric{ 2131*0b57cec5SDimitry Andric __first = _VSTD::find(__first, __last, __value_); 2132*0b57cec5SDimitry Andric if (__first != __last) 2133*0b57cec5SDimitry Andric { 2134*0b57cec5SDimitry Andric _ForwardIterator __i = __first; 2135*0b57cec5SDimitry Andric while (++__i != __last) 2136*0b57cec5SDimitry Andric { 2137*0b57cec5SDimitry Andric if (!(*__i == __value_)) 2138*0b57cec5SDimitry Andric { 2139*0b57cec5SDimitry Andric *__first = _VSTD::move(*__i); 2140*0b57cec5SDimitry Andric ++__first; 2141*0b57cec5SDimitry Andric } 2142*0b57cec5SDimitry Andric } 2143*0b57cec5SDimitry Andric } 2144*0b57cec5SDimitry Andric return __first; 2145*0b57cec5SDimitry Andric} 2146*0b57cec5SDimitry Andric 2147*0b57cec5SDimitry Andric// remove_if 2148*0b57cec5SDimitry Andric 2149*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Predicate> 2150*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 2151*0b57cec5SDimitry Andricremove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 2152*0b57cec5SDimitry Andric{ 2153*0b57cec5SDimitry Andric __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type> 2154*0b57cec5SDimitry Andric (__first, __last, __pred); 2155*0b57cec5SDimitry Andric if (__first != __last) 2156*0b57cec5SDimitry Andric { 2157*0b57cec5SDimitry Andric _ForwardIterator __i = __first; 2158*0b57cec5SDimitry Andric while (++__i != __last) 2159*0b57cec5SDimitry Andric { 2160*0b57cec5SDimitry Andric if (!__pred(*__i)) 2161*0b57cec5SDimitry Andric { 2162*0b57cec5SDimitry Andric *__first = _VSTD::move(*__i); 2163*0b57cec5SDimitry Andric ++__first; 2164*0b57cec5SDimitry Andric } 2165*0b57cec5SDimitry Andric } 2166*0b57cec5SDimitry Andric } 2167*0b57cec5SDimitry Andric return __first; 2168*0b57cec5SDimitry Andric} 2169*0b57cec5SDimitry Andric 2170*0b57cec5SDimitry Andric// remove_copy 2171*0b57cec5SDimitry Andric 2172*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Tp> 2173*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2174*0b57cec5SDimitry Andric_OutputIterator 2175*0b57cec5SDimitry Andricremove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_) 2176*0b57cec5SDimitry Andric{ 2177*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 2178*0b57cec5SDimitry Andric { 2179*0b57cec5SDimitry Andric if (!(*__first == __value_)) 2180*0b57cec5SDimitry Andric { 2181*0b57cec5SDimitry Andric *__result = *__first; 2182*0b57cec5SDimitry Andric ++__result; 2183*0b57cec5SDimitry Andric } 2184*0b57cec5SDimitry Andric } 2185*0b57cec5SDimitry Andric return __result; 2186*0b57cec5SDimitry Andric} 2187*0b57cec5SDimitry Andric 2188*0b57cec5SDimitry Andric// remove_copy_if 2189*0b57cec5SDimitry Andric 2190*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Predicate> 2191*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2192*0b57cec5SDimitry Andric_OutputIterator 2193*0b57cec5SDimitry Andricremove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) 2194*0b57cec5SDimitry Andric{ 2195*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 2196*0b57cec5SDimitry Andric { 2197*0b57cec5SDimitry Andric if (!__pred(*__first)) 2198*0b57cec5SDimitry Andric { 2199*0b57cec5SDimitry Andric *__result = *__first; 2200*0b57cec5SDimitry Andric ++__result; 2201*0b57cec5SDimitry Andric } 2202*0b57cec5SDimitry Andric } 2203*0b57cec5SDimitry Andric return __result; 2204*0b57cec5SDimitry Andric} 2205*0b57cec5SDimitry Andric 2206*0b57cec5SDimitry Andric// unique 2207*0b57cec5SDimitry Andric 2208*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _BinaryPredicate> 2209*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 2210*0b57cec5SDimitry Andricunique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) 2211*0b57cec5SDimitry Andric{ 2212*0b57cec5SDimitry Andric __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type> 2213*0b57cec5SDimitry Andric (__first, __last, __pred); 2214*0b57cec5SDimitry Andric if (__first != __last) 2215*0b57cec5SDimitry Andric { 2216*0b57cec5SDimitry Andric // ... a a ? ... 2217*0b57cec5SDimitry Andric // f i 2218*0b57cec5SDimitry Andric _ForwardIterator __i = __first; 2219*0b57cec5SDimitry Andric for (++__i; ++__i != __last;) 2220*0b57cec5SDimitry Andric if (!__pred(*__first, *__i)) 2221*0b57cec5SDimitry Andric *++__first = _VSTD::move(*__i); 2222*0b57cec5SDimitry Andric ++__first; 2223*0b57cec5SDimitry Andric } 2224*0b57cec5SDimitry Andric return __first; 2225*0b57cec5SDimitry Andric} 2226*0b57cec5SDimitry Andric 2227*0b57cec5SDimitry Andrictemplate <class _ForwardIterator> 2228*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2229*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2230*0b57cec5SDimitry Andric_ForwardIterator 2231*0b57cec5SDimitry Andricunique(_ForwardIterator __first, _ForwardIterator __last) 2232*0b57cec5SDimitry Andric{ 2233*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type __v; 2234*0b57cec5SDimitry Andric return _VSTD::unique(__first, __last, __equal_to<__v>()); 2235*0b57cec5SDimitry Andric} 2236*0b57cec5SDimitry Andric 2237*0b57cec5SDimitry Andric// unique_copy 2238*0b57cec5SDimitry Andric 2239*0b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _InputIterator, class _OutputIterator> 2240*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 2241*0b57cec5SDimitry Andric__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred, 2242*0b57cec5SDimitry Andric input_iterator_tag, output_iterator_tag) 2243*0b57cec5SDimitry Andric{ 2244*0b57cec5SDimitry Andric if (__first != __last) 2245*0b57cec5SDimitry Andric { 2246*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator>::value_type __t(*__first); 2247*0b57cec5SDimitry Andric *__result = __t; 2248*0b57cec5SDimitry Andric ++__result; 2249*0b57cec5SDimitry Andric while (++__first != __last) 2250*0b57cec5SDimitry Andric { 2251*0b57cec5SDimitry Andric if (!__pred(__t, *__first)) 2252*0b57cec5SDimitry Andric { 2253*0b57cec5SDimitry Andric __t = *__first; 2254*0b57cec5SDimitry Andric *__result = __t; 2255*0b57cec5SDimitry Andric ++__result; 2256*0b57cec5SDimitry Andric } 2257*0b57cec5SDimitry Andric } 2258*0b57cec5SDimitry Andric } 2259*0b57cec5SDimitry Andric return __result; 2260*0b57cec5SDimitry Andric} 2261*0b57cec5SDimitry Andric 2262*0b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator> 2263*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 2264*0b57cec5SDimitry Andric__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred, 2265*0b57cec5SDimitry Andric forward_iterator_tag, output_iterator_tag) 2266*0b57cec5SDimitry Andric{ 2267*0b57cec5SDimitry Andric if (__first != __last) 2268*0b57cec5SDimitry Andric { 2269*0b57cec5SDimitry Andric _ForwardIterator __i = __first; 2270*0b57cec5SDimitry Andric *__result = *__i; 2271*0b57cec5SDimitry Andric ++__result; 2272*0b57cec5SDimitry Andric while (++__first != __last) 2273*0b57cec5SDimitry Andric { 2274*0b57cec5SDimitry Andric if (!__pred(*__i, *__first)) 2275*0b57cec5SDimitry Andric { 2276*0b57cec5SDimitry Andric *__result = *__first; 2277*0b57cec5SDimitry Andric ++__result; 2278*0b57cec5SDimitry Andric __i = __first; 2279*0b57cec5SDimitry Andric } 2280*0b57cec5SDimitry Andric } 2281*0b57cec5SDimitry Andric } 2282*0b57cec5SDimitry Andric return __result; 2283*0b57cec5SDimitry Andric} 2284*0b57cec5SDimitry Andric 2285*0b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _InputIterator, class _ForwardIterator> 2286*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 2287*0b57cec5SDimitry Andric__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred, 2288*0b57cec5SDimitry Andric input_iterator_tag, forward_iterator_tag) 2289*0b57cec5SDimitry Andric{ 2290*0b57cec5SDimitry Andric if (__first != __last) 2291*0b57cec5SDimitry Andric { 2292*0b57cec5SDimitry Andric *__result = *__first; 2293*0b57cec5SDimitry Andric while (++__first != __last) 2294*0b57cec5SDimitry Andric if (!__pred(*__result, *__first)) 2295*0b57cec5SDimitry Andric *++__result = *__first; 2296*0b57cec5SDimitry Andric ++__result; 2297*0b57cec5SDimitry Andric } 2298*0b57cec5SDimitry Andric return __result; 2299*0b57cec5SDimitry Andric} 2300*0b57cec5SDimitry Andric 2301*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _BinaryPredicate> 2302*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2303*0b57cec5SDimitry Andric_OutputIterator 2304*0b57cec5SDimitry Andricunique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) 2305*0b57cec5SDimitry Andric{ 2306*0b57cec5SDimitry Andric return _VSTD::__unique_copy<typename add_lvalue_reference<_BinaryPredicate>::type> 2307*0b57cec5SDimitry Andric (__first, __last, __result, __pred, 2308*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator>::iterator_category(), 2309*0b57cec5SDimitry Andric typename iterator_traits<_OutputIterator>::iterator_category()); 2310*0b57cec5SDimitry Andric} 2311*0b57cec5SDimitry Andric 2312*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 2313*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2314*0b57cec5SDimitry Andric_OutputIterator 2315*0b57cec5SDimitry Andricunique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 2316*0b57cec5SDimitry Andric{ 2317*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator>::value_type __v; 2318*0b57cec5SDimitry Andric return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>()); 2319*0b57cec5SDimitry Andric} 2320*0b57cec5SDimitry Andric 2321*0b57cec5SDimitry Andric// reverse 2322*0b57cec5SDimitry Andric 2323*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 2324e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2325*0b57cec5SDimitry Andricvoid 2326*0b57cec5SDimitry Andric__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) 2327*0b57cec5SDimitry Andric{ 2328*0b57cec5SDimitry Andric while (__first != __last) 2329*0b57cec5SDimitry Andric { 2330*0b57cec5SDimitry Andric if (__first == --__last) 2331*0b57cec5SDimitry Andric break; 2332*0b57cec5SDimitry Andric _VSTD::iter_swap(__first, __last); 2333*0b57cec5SDimitry Andric ++__first; 2334*0b57cec5SDimitry Andric } 2335*0b57cec5SDimitry Andric} 2336*0b57cec5SDimitry Andric 2337*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 2338e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2339*0b57cec5SDimitry Andricvoid 2340*0b57cec5SDimitry Andric__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) 2341*0b57cec5SDimitry Andric{ 2342*0b57cec5SDimitry Andric if (__first != __last) 2343*0b57cec5SDimitry Andric for (; __first < --__last; ++__first) 2344*0b57cec5SDimitry Andric _VSTD::iter_swap(__first, __last); 2345*0b57cec5SDimitry Andric} 2346*0b57cec5SDimitry Andric 2347*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 2348e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2349*0b57cec5SDimitry Andricvoid 2350*0b57cec5SDimitry Andricreverse(_BidirectionalIterator __first, _BidirectionalIterator __last) 2351*0b57cec5SDimitry Andric{ 2352*0b57cec5SDimitry Andric _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category()); 2353*0b57cec5SDimitry Andric} 2354*0b57cec5SDimitry Andric 2355*0b57cec5SDimitry Andric// reverse_copy 2356*0b57cec5SDimitry Andric 2357*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator, class _OutputIterator> 2358*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2359*0b57cec5SDimitry Andric_OutputIterator 2360*0b57cec5SDimitry Andricreverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 2361*0b57cec5SDimitry Andric{ 2362*0b57cec5SDimitry Andric for (; __first != __last; ++__result) 2363*0b57cec5SDimitry Andric *__result = *--__last; 2364*0b57cec5SDimitry Andric return __result; 2365*0b57cec5SDimitry Andric} 2366*0b57cec5SDimitry Andric 2367*0b57cec5SDimitry Andric// rotate 2368*0b57cec5SDimitry Andric 2369*0b57cec5SDimitry Andrictemplate <class _ForwardIterator> 2370e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator 2371*0b57cec5SDimitry Andric__rotate_left(_ForwardIterator __first, _ForwardIterator __last) 2372*0b57cec5SDimitry Andric{ 2373*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type value_type; 2374*0b57cec5SDimitry Andric value_type __tmp = _VSTD::move(*__first); 2375*0b57cec5SDimitry Andric _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first); 2376*0b57cec5SDimitry Andric *__lm1 = _VSTD::move(__tmp); 2377*0b57cec5SDimitry Andric return __lm1; 2378*0b57cec5SDimitry Andric} 2379*0b57cec5SDimitry Andric 2380*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 2381e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator 2382*0b57cec5SDimitry Andric__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) 2383*0b57cec5SDimitry Andric{ 2384*0b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 2385*0b57cec5SDimitry Andric _BidirectionalIterator __lm1 = _VSTD::prev(__last); 2386*0b57cec5SDimitry Andric value_type __tmp = _VSTD::move(*__lm1); 2387*0b57cec5SDimitry Andric _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last); 2388*0b57cec5SDimitry Andric *__first = _VSTD::move(__tmp); 2389*0b57cec5SDimitry Andric return __fp1; 2390*0b57cec5SDimitry Andric} 2391*0b57cec5SDimitry Andric 2392*0b57cec5SDimitry Andrictemplate <class _ForwardIterator> 2393e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX14 _ForwardIterator 2394*0b57cec5SDimitry Andric__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) 2395*0b57cec5SDimitry Andric{ 2396*0b57cec5SDimitry Andric _ForwardIterator __i = __middle; 2397*0b57cec5SDimitry Andric while (true) 2398*0b57cec5SDimitry Andric { 2399*0b57cec5SDimitry Andric swap(*__first, *__i); 2400*0b57cec5SDimitry Andric ++__first; 2401*0b57cec5SDimitry Andric if (++__i == __last) 2402*0b57cec5SDimitry Andric break; 2403*0b57cec5SDimitry Andric if (__first == __middle) 2404*0b57cec5SDimitry Andric __middle = __i; 2405*0b57cec5SDimitry Andric } 2406*0b57cec5SDimitry Andric _ForwardIterator __r = __first; 2407*0b57cec5SDimitry Andric if (__first != __middle) 2408*0b57cec5SDimitry Andric { 2409*0b57cec5SDimitry Andric __i = __middle; 2410*0b57cec5SDimitry Andric while (true) 2411*0b57cec5SDimitry Andric { 2412*0b57cec5SDimitry Andric swap(*__first, *__i); 2413*0b57cec5SDimitry Andric ++__first; 2414*0b57cec5SDimitry Andric if (++__i == __last) 2415*0b57cec5SDimitry Andric { 2416*0b57cec5SDimitry Andric if (__first == __middle) 2417*0b57cec5SDimitry Andric break; 2418*0b57cec5SDimitry Andric __i = __middle; 2419*0b57cec5SDimitry Andric } 2420*0b57cec5SDimitry Andric else if (__first == __middle) 2421*0b57cec5SDimitry Andric __middle = __i; 2422*0b57cec5SDimitry Andric } 2423*0b57cec5SDimitry Andric } 2424*0b57cec5SDimitry Andric return __r; 2425*0b57cec5SDimitry Andric} 2426*0b57cec5SDimitry Andric 2427*0b57cec5SDimitry Andrictemplate<typename _Integral> 2428*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2429e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX14 _Integral 2430*0b57cec5SDimitry Andric__algo_gcd(_Integral __x, _Integral __y) 2431*0b57cec5SDimitry Andric{ 2432*0b57cec5SDimitry Andric do 2433*0b57cec5SDimitry Andric { 2434*0b57cec5SDimitry Andric _Integral __t = __x % __y; 2435*0b57cec5SDimitry Andric __x = __y; 2436*0b57cec5SDimitry Andric __y = __t; 2437*0b57cec5SDimitry Andric } while (__y); 2438*0b57cec5SDimitry Andric return __x; 2439*0b57cec5SDimitry Andric} 2440*0b57cec5SDimitry Andric 2441*0b57cec5SDimitry Andrictemplate<typename _RandomAccessIterator> 2442e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX14 _RandomAccessIterator 2443*0b57cec5SDimitry Andric__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) 2444*0b57cec5SDimitry Andric{ 2445*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 2446*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 2447*0b57cec5SDimitry Andric 2448*0b57cec5SDimitry Andric const difference_type __m1 = __middle - __first; 2449*0b57cec5SDimitry Andric const difference_type __m2 = __last - __middle; 2450*0b57cec5SDimitry Andric if (__m1 == __m2) 2451*0b57cec5SDimitry Andric { 2452*0b57cec5SDimitry Andric _VSTD::swap_ranges(__first, __middle, __middle); 2453*0b57cec5SDimitry Andric return __middle; 2454*0b57cec5SDimitry Andric } 2455*0b57cec5SDimitry Andric const difference_type __g = _VSTD::__algo_gcd(__m1, __m2); 2456*0b57cec5SDimitry Andric for (_RandomAccessIterator __p = __first + __g; __p != __first;) 2457*0b57cec5SDimitry Andric { 2458*0b57cec5SDimitry Andric value_type __t(_VSTD::move(*--__p)); 2459*0b57cec5SDimitry Andric _RandomAccessIterator __p1 = __p; 2460*0b57cec5SDimitry Andric _RandomAccessIterator __p2 = __p1 + __m1; 2461*0b57cec5SDimitry Andric do 2462*0b57cec5SDimitry Andric { 2463*0b57cec5SDimitry Andric *__p1 = _VSTD::move(*__p2); 2464*0b57cec5SDimitry Andric __p1 = __p2; 2465*0b57cec5SDimitry Andric const difference_type __d = __last - __p2; 2466*0b57cec5SDimitry Andric if (__m1 < __d) 2467*0b57cec5SDimitry Andric __p2 += __m1; 2468*0b57cec5SDimitry Andric else 2469*0b57cec5SDimitry Andric __p2 = __first + (__m1 - __d); 2470*0b57cec5SDimitry Andric } while (__p2 != __p); 2471*0b57cec5SDimitry Andric *__p1 = _VSTD::move(__t); 2472*0b57cec5SDimitry Andric } 2473*0b57cec5SDimitry Andric return __first + __m2; 2474*0b57cec5SDimitry Andric} 2475*0b57cec5SDimitry Andric 2476*0b57cec5SDimitry Andrictemplate <class _ForwardIterator> 2477*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2478e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator 2479*0b57cec5SDimitry Andric__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, 2480*0b57cec5SDimitry Andric _VSTD::forward_iterator_tag) 2481*0b57cec5SDimitry Andric{ 2482*0b57cec5SDimitry Andric typedef typename _VSTD::iterator_traits<_ForwardIterator>::value_type value_type; 2483*0b57cec5SDimitry Andric if (_VSTD::is_trivially_move_assignable<value_type>::value) 2484*0b57cec5SDimitry Andric { 2485*0b57cec5SDimitry Andric if (_VSTD::next(__first) == __middle) 2486*0b57cec5SDimitry Andric return _VSTD::__rotate_left(__first, __last); 2487*0b57cec5SDimitry Andric } 2488*0b57cec5SDimitry Andric return _VSTD::__rotate_forward(__first, __middle, __last); 2489*0b57cec5SDimitry Andric} 2490*0b57cec5SDimitry Andric 2491*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 2492*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2493e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator 2494*0b57cec5SDimitry Andric__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 2495*0b57cec5SDimitry Andric _VSTD::bidirectional_iterator_tag) 2496*0b57cec5SDimitry Andric{ 2497*0b57cec5SDimitry Andric typedef typename _VSTD::iterator_traits<_BidirectionalIterator>::value_type value_type; 2498*0b57cec5SDimitry Andric if (_VSTD::is_trivially_move_assignable<value_type>::value) 2499*0b57cec5SDimitry Andric { 2500*0b57cec5SDimitry Andric if (_VSTD::next(__first) == __middle) 2501*0b57cec5SDimitry Andric return _VSTD::__rotate_left(__first, __last); 2502*0b57cec5SDimitry Andric if (_VSTD::next(__middle) == __last) 2503*0b57cec5SDimitry Andric return _VSTD::__rotate_right(__first, __last); 2504*0b57cec5SDimitry Andric } 2505*0b57cec5SDimitry Andric return _VSTD::__rotate_forward(__first, __middle, __last); 2506*0b57cec5SDimitry Andric} 2507*0b57cec5SDimitry Andric 2508*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 2509*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2510e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator 2511*0b57cec5SDimitry Andric__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, 2512*0b57cec5SDimitry Andric _VSTD::random_access_iterator_tag) 2513*0b57cec5SDimitry Andric{ 2514*0b57cec5SDimitry Andric typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::value_type value_type; 2515*0b57cec5SDimitry Andric if (_VSTD::is_trivially_move_assignable<value_type>::value) 2516*0b57cec5SDimitry Andric { 2517*0b57cec5SDimitry Andric if (_VSTD::next(__first) == __middle) 2518*0b57cec5SDimitry Andric return _VSTD::__rotate_left(__first, __last); 2519*0b57cec5SDimitry Andric if (_VSTD::next(__middle) == __last) 2520*0b57cec5SDimitry Andric return _VSTD::__rotate_right(__first, __last); 2521*0b57cec5SDimitry Andric return _VSTD::__rotate_gcd(__first, __middle, __last); 2522*0b57cec5SDimitry Andric } 2523*0b57cec5SDimitry Andric return _VSTD::__rotate_forward(__first, __middle, __last); 2524*0b57cec5SDimitry Andric} 2525*0b57cec5SDimitry Andric 2526*0b57cec5SDimitry Andrictemplate <class _ForwardIterator> 2527*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2528e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 2529*0b57cec5SDimitry Andricrotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) 2530*0b57cec5SDimitry Andric{ 2531*0b57cec5SDimitry Andric if (__first == __middle) 2532*0b57cec5SDimitry Andric return __last; 2533*0b57cec5SDimitry Andric if (__middle == __last) 2534*0b57cec5SDimitry Andric return __first; 2535*0b57cec5SDimitry Andric return _VSTD::__rotate(__first, __middle, __last, 2536*0b57cec5SDimitry Andric typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category()); 2537*0b57cec5SDimitry Andric} 2538*0b57cec5SDimitry Andric 2539*0b57cec5SDimitry Andric// rotate_copy 2540*0b57cec5SDimitry Andric 2541*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _OutputIterator> 2542e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 2543*0b57cec5SDimitry Andric_OutputIterator 2544*0b57cec5SDimitry Andricrotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) 2545*0b57cec5SDimitry Andric{ 2546*0b57cec5SDimitry Andric return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result)); 2547*0b57cec5SDimitry Andric} 2548*0b57cec5SDimitry Andric 2549*0b57cec5SDimitry Andric// min_element 2550*0b57cec5SDimitry Andric 2551*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Compare> 2552*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2553*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2554*0b57cec5SDimitry Andric_ForwardIterator 2555*0b57cec5SDimitry Andricmin_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 2556*0b57cec5SDimitry Andric{ 2557480093f4SDimitry Andric static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, 2558*0b57cec5SDimitry Andric "std::min_element requires a ForwardIterator"); 2559*0b57cec5SDimitry Andric if (__first != __last) 2560*0b57cec5SDimitry Andric { 2561*0b57cec5SDimitry Andric _ForwardIterator __i = __first; 2562*0b57cec5SDimitry Andric while (++__i != __last) 2563*0b57cec5SDimitry Andric if (__comp(*__i, *__first)) 2564*0b57cec5SDimitry Andric __first = __i; 2565*0b57cec5SDimitry Andric } 2566*0b57cec5SDimitry Andric return __first; 2567*0b57cec5SDimitry Andric} 2568*0b57cec5SDimitry Andric 2569*0b57cec5SDimitry Andrictemplate <class _ForwardIterator> 2570*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2571*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2572*0b57cec5SDimitry Andric_ForwardIterator 2573*0b57cec5SDimitry Andricmin_element(_ForwardIterator __first, _ForwardIterator __last) 2574*0b57cec5SDimitry Andric{ 2575*0b57cec5SDimitry Andric return _VSTD::min_element(__first, __last, 2576*0b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type>()); 2577*0b57cec5SDimitry Andric} 2578*0b57cec5SDimitry Andric 2579*0b57cec5SDimitry Andric// min 2580*0b57cec5SDimitry Andric 2581*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare> 2582*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2583*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2584*0b57cec5SDimitry Andricconst _Tp& 2585*0b57cec5SDimitry Andricmin(const _Tp& __a, const _Tp& __b, _Compare __comp) 2586*0b57cec5SDimitry Andric{ 2587*0b57cec5SDimitry Andric return __comp(__b, __a) ? __b : __a; 2588*0b57cec5SDimitry Andric} 2589*0b57cec5SDimitry Andric 2590*0b57cec5SDimitry Andrictemplate <class _Tp> 2591*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2592*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2593*0b57cec5SDimitry Andricconst _Tp& 2594*0b57cec5SDimitry Andricmin(const _Tp& __a, const _Tp& __b) 2595*0b57cec5SDimitry Andric{ 2596*0b57cec5SDimitry Andric return _VSTD::min(__a, __b, __less<_Tp>()); 2597*0b57cec5SDimitry Andric} 2598*0b57cec5SDimitry Andric 2599*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2600*0b57cec5SDimitry Andric 2601*0b57cec5SDimitry Andrictemplate<class _Tp, class _Compare> 2602*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2603*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2604*0b57cec5SDimitry Andric_Tp 2605*0b57cec5SDimitry Andricmin(initializer_list<_Tp> __t, _Compare __comp) 2606*0b57cec5SDimitry Andric{ 2607*0b57cec5SDimitry Andric return *_VSTD::min_element(__t.begin(), __t.end(), __comp); 2608*0b57cec5SDimitry Andric} 2609*0b57cec5SDimitry Andric 2610*0b57cec5SDimitry Andrictemplate<class _Tp> 2611*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2612*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2613*0b57cec5SDimitry Andric_Tp 2614*0b57cec5SDimitry Andricmin(initializer_list<_Tp> __t) 2615*0b57cec5SDimitry Andric{ 2616*0b57cec5SDimitry Andric return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>()); 2617*0b57cec5SDimitry Andric} 2618*0b57cec5SDimitry Andric 2619*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 2620*0b57cec5SDimitry Andric 2621*0b57cec5SDimitry Andric// max_element 2622*0b57cec5SDimitry Andric 2623*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Compare> 2624*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2625*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2626*0b57cec5SDimitry Andric_ForwardIterator 2627*0b57cec5SDimitry Andricmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 2628*0b57cec5SDimitry Andric{ 2629480093f4SDimitry Andric static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, 2630*0b57cec5SDimitry Andric "std::max_element requires a ForwardIterator"); 2631*0b57cec5SDimitry Andric if (__first != __last) 2632*0b57cec5SDimitry Andric { 2633*0b57cec5SDimitry Andric _ForwardIterator __i = __first; 2634*0b57cec5SDimitry Andric while (++__i != __last) 2635*0b57cec5SDimitry Andric if (__comp(*__first, *__i)) 2636*0b57cec5SDimitry Andric __first = __i; 2637*0b57cec5SDimitry Andric } 2638*0b57cec5SDimitry Andric return __first; 2639*0b57cec5SDimitry Andric} 2640*0b57cec5SDimitry Andric 2641*0b57cec5SDimitry Andric 2642*0b57cec5SDimitry Andrictemplate <class _ForwardIterator> 2643*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2644*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2645*0b57cec5SDimitry Andric_ForwardIterator 2646*0b57cec5SDimitry Andricmax_element(_ForwardIterator __first, _ForwardIterator __last) 2647*0b57cec5SDimitry Andric{ 2648*0b57cec5SDimitry Andric return _VSTD::max_element(__first, __last, 2649*0b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type>()); 2650*0b57cec5SDimitry Andric} 2651*0b57cec5SDimitry Andric 2652*0b57cec5SDimitry Andric// max 2653*0b57cec5SDimitry Andric 2654*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare> 2655*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2656*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2657*0b57cec5SDimitry Andricconst _Tp& 2658*0b57cec5SDimitry Andricmax(const _Tp& __a, const _Tp& __b, _Compare __comp) 2659*0b57cec5SDimitry Andric{ 2660*0b57cec5SDimitry Andric return __comp(__a, __b) ? __b : __a; 2661*0b57cec5SDimitry Andric} 2662*0b57cec5SDimitry Andric 2663*0b57cec5SDimitry Andrictemplate <class _Tp> 2664*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2665*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2666*0b57cec5SDimitry Andricconst _Tp& 2667*0b57cec5SDimitry Andricmax(const _Tp& __a, const _Tp& __b) 2668*0b57cec5SDimitry Andric{ 2669*0b57cec5SDimitry Andric return _VSTD::max(__a, __b, __less<_Tp>()); 2670*0b57cec5SDimitry Andric} 2671*0b57cec5SDimitry Andric 2672*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2673*0b57cec5SDimitry Andric 2674*0b57cec5SDimitry Andrictemplate<class _Tp, class _Compare> 2675*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2676*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2677*0b57cec5SDimitry Andric_Tp 2678*0b57cec5SDimitry Andricmax(initializer_list<_Tp> __t, _Compare __comp) 2679*0b57cec5SDimitry Andric{ 2680*0b57cec5SDimitry Andric return *_VSTD::max_element(__t.begin(), __t.end(), __comp); 2681*0b57cec5SDimitry Andric} 2682*0b57cec5SDimitry Andric 2683*0b57cec5SDimitry Andrictemplate<class _Tp> 2684*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2685*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2686*0b57cec5SDimitry Andric_Tp 2687*0b57cec5SDimitry Andricmax(initializer_list<_Tp> __t) 2688*0b57cec5SDimitry Andric{ 2689*0b57cec5SDimitry Andric return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>()); 2690*0b57cec5SDimitry Andric} 2691*0b57cec5SDimitry Andric 2692*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 2693*0b57cec5SDimitry Andric 2694*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 2695*0b57cec5SDimitry Andric// clamp 2696*0b57cec5SDimitry Andrictemplate<class _Tp, class _Compare> 2697*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2698*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 2699*0b57cec5SDimitry Andricconst _Tp& 2700*0b57cec5SDimitry Andricclamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) 2701*0b57cec5SDimitry Andric{ 2702*0b57cec5SDimitry Andric _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp"); 2703*0b57cec5SDimitry Andric return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v; 2704*0b57cec5SDimitry Andric 2705*0b57cec5SDimitry Andric} 2706*0b57cec5SDimitry Andric 2707*0b57cec5SDimitry Andrictemplate<class _Tp> 2708*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2709*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 2710*0b57cec5SDimitry Andricconst _Tp& 2711*0b57cec5SDimitry Andricclamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) 2712*0b57cec5SDimitry Andric{ 2713*0b57cec5SDimitry Andric return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>()); 2714*0b57cec5SDimitry Andric} 2715*0b57cec5SDimitry Andric#endif 2716*0b57cec5SDimitry Andric 2717*0b57cec5SDimitry Andric// minmax_element 2718*0b57cec5SDimitry Andric 2719*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Compare> 2720*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11 2721e8d8bef9SDimitry Andricpair<_ForwardIterator, _ForwardIterator> 2722*0b57cec5SDimitry Andricminmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 2723*0b57cec5SDimitry Andric{ 2724480093f4SDimitry Andric static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, 2725*0b57cec5SDimitry Andric "std::minmax_element requires a ForwardIterator"); 2726e8d8bef9SDimitry Andric pair<_ForwardIterator, _ForwardIterator> __result(__first, __first); 2727*0b57cec5SDimitry Andric if (__first != __last) 2728*0b57cec5SDimitry Andric { 2729*0b57cec5SDimitry Andric if (++__first != __last) 2730*0b57cec5SDimitry Andric { 2731*0b57cec5SDimitry Andric if (__comp(*__first, *__result.first)) 2732*0b57cec5SDimitry Andric __result.first = __first; 2733*0b57cec5SDimitry Andric else 2734*0b57cec5SDimitry Andric __result.second = __first; 2735*0b57cec5SDimitry Andric while (++__first != __last) 2736*0b57cec5SDimitry Andric { 2737*0b57cec5SDimitry Andric _ForwardIterator __i = __first; 2738*0b57cec5SDimitry Andric if (++__first == __last) 2739*0b57cec5SDimitry Andric { 2740*0b57cec5SDimitry Andric if (__comp(*__i, *__result.first)) 2741*0b57cec5SDimitry Andric __result.first = __i; 2742*0b57cec5SDimitry Andric else if (!__comp(*__i, *__result.second)) 2743*0b57cec5SDimitry Andric __result.second = __i; 2744*0b57cec5SDimitry Andric break; 2745*0b57cec5SDimitry Andric } 2746*0b57cec5SDimitry Andric else 2747*0b57cec5SDimitry Andric { 2748*0b57cec5SDimitry Andric if (__comp(*__first, *__i)) 2749*0b57cec5SDimitry Andric { 2750*0b57cec5SDimitry Andric if (__comp(*__first, *__result.first)) 2751*0b57cec5SDimitry Andric __result.first = __first; 2752*0b57cec5SDimitry Andric if (!__comp(*__i, *__result.second)) 2753*0b57cec5SDimitry Andric __result.second = __i; 2754*0b57cec5SDimitry Andric } 2755*0b57cec5SDimitry Andric else 2756*0b57cec5SDimitry Andric { 2757*0b57cec5SDimitry Andric if (__comp(*__i, *__result.first)) 2758*0b57cec5SDimitry Andric __result.first = __i; 2759*0b57cec5SDimitry Andric if (!__comp(*__first, *__result.second)) 2760*0b57cec5SDimitry Andric __result.second = __first; 2761*0b57cec5SDimitry Andric } 2762*0b57cec5SDimitry Andric } 2763*0b57cec5SDimitry Andric } 2764*0b57cec5SDimitry Andric } 2765*0b57cec5SDimitry Andric } 2766*0b57cec5SDimitry Andric return __result; 2767*0b57cec5SDimitry Andric} 2768*0b57cec5SDimitry Andric 2769*0b57cec5SDimitry Andrictemplate <class _ForwardIterator> 2770*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2771*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2772e8d8bef9SDimitry Andricpair<_ForwardIterator, _ForwardIterator> 2773*0b57cec5SDimitry Andricminmax_element(_ForwardIterator __first, _ForwardIterator __last) 2774*0b57cec5SDimitry Andric{ 2775*0b57cec5SDimitry Andric return _VSTD::minmax_element(__first, __last, 2776*0b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type>()); 2777*0b57cec5SDimitry Andric} 2778*0b57cec5SDimitry Andric 2779*0b57cec5SDimitry Andric// minmax 2780*0b57cec5SDimitry Andric 2781*0b57cec5SDimitry Andrictemplate<class _Tp, class _Compare> 2782*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2783*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2784*0b57cec5SDimitry Andricpair<const _Tp&, const _Tp&> 2785*0b57cec5SDimitry Andricminmax(const _Tp& __a, const _Tp& __b, _Compare __comp) 2786*0b57cec5SDimitry Andric{ 2787*0b57cec5SDimitry Andric return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) : 2788*0b57cec5SDimitry Andric pair<const _Tp&, const _Tp&>(__a, __b); 2789*0b57cec5SDimitry Andric} 2790*0b57cec5SDimitry Andric 2791*0b57cec5SDimitry Andrictemplate<class _Tp> 2792*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2793*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2794*0b57cec5SDimitry Andricpair<const _Tp&, const _Tp&> 2795*0b57cec5SDimitry Andricminmax(const _Tp& __a, const _Tp& __b) 2796*0b57cec5SDimitry Andric{ 2797*0b57cec5SDimitry Andric return _VSTD::minmax(__a, __b, __less<_Tp>()); 2798*0b57cec5SDimitry Andric} 2799*0b57cec5SDimitry Andric 2800*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2801*0b57cec5SDimitry Andric 2802*0b57cec5SDimitry Andrictemplate<class _Tp, class _Compare> 2803*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2804*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2805*0b57cec5SDimitry Andricpair<_Tp, _Tp> 2806*0b57cec5SDimitry Andricminmax(initializer_list<_Tp> __t, _Compare __comp) 2807*0b57cec5SDimitry Andric{ 2808*0b57cec5SDimitry Andric typedef typename initializer_list<_Tp>::const_iterator _Iter; 2809*0b57cec5SDimitry Andric _Iter __first = __t.begin(); 2810*0b57cec5SDimitry Andric _Iter __last = __t.end(); 2811e8d8bef9SDimitry Andric pair<_Tp, _Tp> __result(*__first, *__first); 2812*0b57cec5SDimitry Andric 2813*0b57cec5SDimitry Andric ++__first; 2814*0b57cec5SDimitry Andric if (__t.size() % 2 == 0) 2815*0b57cec5SDimitry Andric { 2816*0b57cec5SDimitry Andric if (__comp(*__first, __result.first)) 2817*0b57cec5SDimitry Andric __result.first = *__first; 2818*0b57cec5SDimitry Andric else 2819*0b57cec5SDimitry Andric __result.second = *__first; 2820*0b57cec5SDimitry Andric ++__first; 2821*0b57cec5SDimitry Andric } 2822*0b57cec5SDimitry Andric 2823*0b57cec5SDimitry Andric while (__first != __last) 2824*0b57cec5SDimitry Andric { 2825*0b57cec5SDimitry Andric _Tp __prev = *__first++; 2826*0b57cec5SDimitry Andric if (__comp(*__first, __prev)) { 2827*0b57cec5SDimitry Andric if ( __comp(*__first, __result.first)) __result.first = *__first; 2828*0b57cec5SDimitry Andric if (!__comp(__prev, __result.second)) __result.second = __prev; 2829*0b57cec5SDimitry Andric } 2830*0b57cec5SDimitry Andric else { 2831*0b57cec5SDimitry Andric if ( __comp(__prev, __result.first)) __result.first = __prev; 2832*0b57cec5SDimitry Andric if (!__comp(*__first, __result.second)) __result.second = *__first; 2833*0b57cec5SDimitry Andric } 2834*0b57cec5SDimitry Andric 2835*0b57cec5SDimitry Andric __first++; 2836*0b57cec5SDimitry Andric } 2837*0b57cec5SDimitry Andric return __result; 2838*0b57cec5SDimitry Andric} 2839*0b57cec5SDimitry Andric 2840*0b57cec5SDimitry Andrictemplate<class _Tp> 2841*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 2842*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2843*0b57cec5SDimitry Andricpair<_Tp, _Tp> 2844*0b57cec5SDimitry Andricminmax(initializer_list<_Tp> __t) 2845*0b57cec5SDimitry Andric{ 2846*0b57cec5SDimitry Andric return _VSTD::minmax(__t, __less<_Tp>()); 2847*0b57cec5SDimitry Andric} 2848*0b57cec5SDimitry Andric 2849*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 2850*0b57cec5SDimitry Andric 2851*0b57cec5SDimitry Andric// random_shuffle 2852*0b57cec5SDimitry Andric 2853*0b57cec5SDimitry Andric// __independent_bits_engine 2854*0b57cec5SDimitry Andric 2855*0b57cec5SDimitry Andrictemplate <unsigned long long _Xp, size_t _Rp> 2856*0b57cec5SDimitry Andricstruct __log2_imp 2857*0b57cec5SDimitry Andric{ 2858*0b57cec5SDimitry Andric static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp 2859*0b57cec5SDimitry Andric : __log2_imp<_Xp, _Rp - 1>::value; 2860*0b57cec5SDimitry Andric}; 2861*0b57cec5SDimitry Andric 2862*0b57cec5SDimitry Andrictemplate <unsigned long long _Xp> 2863*0b57cec5SDimitry Andricstruct __log2_imp<_Xp, 0> 2864*0b57cec5SDimitry Andric{ 2865*0b57cec5SDimitry Andric static const size_t value = 0; 2866*0b57cec5SDimitry Andric}; 2867*0b57cec5SDimitry Andric 2868*0b57cec5SDimitry Andrictemplate <size_t _Rp> 2869*0b57cec5SDimitry Andricstruct __log2_imp<0, _Rp> 2870*0b57cec5SDimitry Andric{ 2871*0b57cec5SDimitry Andric static const size_t value = _Rp + 1; 2872*0b57cec5SDimitry Andric}; 2873*0b57cec5SDimitry Andric 2874*0b57cec5SDimitry Andrictemplate <class _UIntType, _UIntType _Xp> 2875*0b57cec5SDimitry Andricstruct __log2 2876*0b57cec5SDimitry Andric{ 2877*0b57cec5SDimitry Andric static const size_t value = __log2_imp<_Xp, 2878*0b57cec5SDimitry Andric sizeof(_UIntType) * __CHAR_BIT__ - 1>::value; 2879*0b57cec5SDimitry Andric}; 2880*0b57cec5SDimitry Andric 2881*0b57cec5SDimitry Andrictemplate<class _Engine, class _UIntType> 2882*0b57cec5SDimitry Andricclass __independent_bits_engine 2883*0b57cec5SDimitry Andric{ 2884*0b57cec5SDimitry Andricpublic: 2885*0b57cec5SDimitry Andric // types 2886*0b57cec5SDimitry Andric typedef _UIntType result_type; 2887*0b57cec5SDimitry Andric 2888*0b57cec5SDimitry Andricprivate: 2889*0b57cec5SDimitry Andric typedef typename _Engine::result_type _Engine_result_type; 2890*0b57cec5SDimitry Andric typedef typename conditional 2891*0b57cec5SDimitry Andric < 2892*0b57cec5SDimitry Andric sizeof(_Engine_result_type) <= sizeof(result_type), 2893*0b57cec5SDimitry Andric result_type, 2894*0b57cec5SDimitry Andric _Engine_result_type 2895*0b57cec5SDimitry Andric >::type _Working_result_type; 2896*0b57cec5SDimitry Andric 2897*0b57cec5SDimitry Andric _Engine& __e_; 2898*0b57cec5SDimitry Andric size_t __w_; 2899*0b57cec5SDimitry Andric size_t __w0_; 2900*0b57cec5SDimitry Andric size_t __n_; 2901*0b57cec5SDimitry Andric size_t __n0_; 2902*0b57cec5SDimitry Andric _Working_result_type __y0_; 2903*0b57cec5SDimitry Andric _Working_result_type __y1_; 2904*0b57cec5SDimitry Andric _Engine_result_type __mask0_; 2905*0b57cec5SDimitry Andric _Engine_result_type __mask1_; 2906*0b57cec5SDimitry Andric 2907*0b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG 2908*0b57cec5SDimitry Andric static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min 2909*0b57cec5SDimitry Andric + _Working_result_type(1); 2910*0b57cec5SDimitry Andric#else 2911*0b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min() 2912*0b57cec5SDimitry Andric + _Working_result_type(1); 2913*0b57cec5SDimitry Andric#endif 2914*0b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value; 2915*0b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits; 2916*0b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits; 2917*0b57cec5SDimitry Andric 2918*0b57cec5SDimitry Andricpublic: 2919*0b57cec5SDimitry Andric // constructors and seeding functions 2920*0b57cec5SDimitry Andric __independent_bits_engine(_Engine& __e, size_t __w); 2921*0b57cec5SDimitry Andric 2922*0b57cec5SDimitry Andric // generating functions 2923*0b57cec5SDimitry Andric result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());} 2924*0b57cec5SDimitry Andric 2925*0b57cec5SDimitry Andricprivate: 2926*0b57cec5SDimitry Andric result_type __eval(false_type); 2927*0b57cec5SDimitry Andric result_type __eval(true_type); 2928*0b57cec5SDimitry Andric}; 2929*0b57cec5SDimitry Andric 2930*0b57cec5SDimitry Andrictemplate<class _Engine, class _UIntType> 2931*0b57cec5SDimitry Andric__independent_bits_engine<_Engine, _UIntType> 2932*0b57cec5SDimitry Andric ::__independent_bits_engine(_Engine& __e, size_t __w) 2933*0b57cec5SDimitry Andric : __e_(__e), 2934*0b57cec5SDimitry Andric __w_(__w) 2935*0b57cec5SDimitry Andric{ 2936*0b57cec5SDimitry Andric __n_ = __w_ / __m + (__w_ % __m != 0); 2937*0b57cec5SDimitry Andric __w0_ = __w_ / __n_; 2938*0b57cec5SDimitry Andric if (_Rp == 0) 2939*0b57cec5SDimitry Andric __y0_ = _Rp; 2940*0b57cec5SDimitry Andric else if (__w0_ < _WDt) 2941*0b57cec5SDimitry Andric __y0_ = (_Rp >> __w0_) << __w0_; 2942*0b57cec5SDimitry Andric else 2943*0b57cec5SDimitry Andric __y0_ = 0; 2944*0b57cec5SDimitry Andric if (_Rp - __y0_ > __y0_ / __n_) 2945*0b57cec5SDimitry Andric { 2946*0b57cec5SDimitry Andric ++__n_; 2947*0b57cec5SDimitry Andric __w0_ = __w_ / __n_; 2948*0b57cec5SDimitry Andric if (__w0_ < _WDt) 2949*0b57cec5SDimitry Andric __y0_ = (_Rp >> __w0_) << __w0_; 2950*0b57cec5SDimitry Andric else 2951*0b57cec5SDimitry Andric __y0_ = 0; 2952*0b57cec5SDimitry Andric } 2953*0b57cec5SDimitry Andric __n0_ = __n_ - __w_ % __n_; 2954*0b57cec5SDimitry Andric if (__w0_ < _WDt - 1) 2955*0b57cec5SDimitry Andric __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1); 2956*0b57cec5SDimitry Andric else 2957*0b57cec5SDimitry Andric __y1_ = 0; 2958*0b57cec5SDimitry Andric __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) : 2959*0b57cec5SDimitry Andric _Engine_result_type(0); 2960*0b57cec5SDimitry Andric __mask1_ = __w0_ < _EDt - 1 ? 2961*0b57cec5SDimitry Andric _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) : 2962*0b57cec5SDimitry Andric _Engine_result_type(~0); 2963*0b57cec5SDimitry Andric} 2964*0b57cec5SDimitry Andric 2965*0b57cec5SDimitry Andrictemplate<class _Engine, class _UIntType> 2966*0b57cec5SDimitry Andricinline 2967*0b57cec5SDimitry Andric_UIntType 2968*0b57cec5SDimitry Andric__independent_bits_engine<_Engine, _UIntType>::__eval(false_type) 2969*0b57cec5SDimitry Andric{ 2970*0b57cec5SDimitry Andric return static_cast<result_type>(__e_() & __mask0_); 2971*0b57cec5SDimitry Andric} 2972*0b57cec5SDimitry Andric 2973*0b57cec5SDimitry Andrictemplate<class _Engine, class _UIntType> 2974*0b57cec5SDimitry Andric_UIntType 2975*0b57cec5SDimitry Andric__independent_bits_engine<_Engine, _UIntType>::__eval(true_type) 2976*0b57cec5SDimitry Andric{ 2977*0b57cec5SDimitry Andric const size_t _WRt = numeric_limits<result_type>::digits; 2978*0b57cec5SDimitry Andric result_type _Sp = 0; 2979*0b57cec5SDimitry Andric for (size_t __k = 0; __k < __n0_; ++__k) 2980*0b57cec5SDimitry Andric { 2981*0b57cec5SDimitry Andric _Engine_result_type __u; 2982*0b57cec5SDimitry Andric do 2983*0b57cec5SDimitry Andric { 2984*0b57cec5SDimitry Andric __u = __e_() - _Engine::min(); 2985*0b57cec5SDimitry Andric } while (__u >= __y0_); 2986*0b57cec5SDimitry Andric if (__w0_ < _WRt) 2987*0b57cec5SDimitry Andric _Sp <<= __w0_; 2988*0b57cec5SDimitry Andric else 2989*0b57cec5SDimitry Andric _Sp = 0; 2990*0b57cec5SDimitry Andric _Sp += __u & __mask0_; 2991*0b57cec5SDimitry Andric } 2992*0b57cec5SDimitry Andric for (size_t __k = __n0_; __k < __n_; ++__k) 2993*0b57cec5SDimitry Andric { 2994*0b57cec5SDimitry Andric _Engine_result_type __u; 2995*0b57cec5SDimitry Andric do 2996*0b57cec5SDimitry Andric { 2997*0b57cec5SDimitry Andric __u = __e_() - _Engine::min(); 2998*0b57cec5SDimitry Andric } while (__u >= __y1_); 2999*0b57cec5SDimitry Andric if (__w0_ < _WRt - 1) 3000*0b57cec5SDimitry Andric _Sp <<= __w0_ + 1; 3001*0b57cec5SDimitry Andric else 3002*0b57cec5SDimitry Andric _Sp = 0; 3003*0b57cec5SDimitry Andric _Sp += __u & __mask1_; 3004*0b57cec5SDimitry Andric } 3005*0b57cec5SDimitry Andric return _Sp; 3006*0b57cec5SDimitry Andric} 3007*0b57cec5SDimitry Andric 3008*0b57cec5SDimitry Andric// uniform_int_distribution 3009*0b57cec5SDimitry Andric 3010*0b57cec5SDimitry Andrictemplate<class _IntType = int> 3011*0b57cec5SDimitry Andricclass uniform_int_distribution 3012*0b57cec5SDimitry Andric{ 3013*0b57cec5SDimitry Andricpublic: 3014*0b57cec5SDimitry Andric // types 3015*0b57cec5SDimitry Andric typedef _IntType result_type; 3016*0b57cec5SDimitry Andric 3017*0b57cec5SDimitry Andric class param_type 3018*0b57cec5SDimitry Andric { 3019*0b57cec5SDimitry Andric result_type __a_; 3020*0b57cec5SDimitry Andric result_type __b_; 3021*0b57cec5SDimitry Andric public: 3022*0b57cec5SDimitry Andric typedef uniform_int_distribution distribution_type; 3023*0b57cec5SDimitry Andric 3024*0b57cec5SDimitry Andric explicit param_type(result_type __a = 0, 3025*0b57cec5SDimitry Andric result_type __b = numeric_limits<result_type>::max()) 3026*0b57cec5SDimitry Andric : __a_(__a), __b_(__b) {} 3027*0b57cec5SDimitry Andric 3028*0b57cec5SDimitry Andric result_type a() const {return __a_;} 3029*0b57cec5SDimitry Andric result_type b() const {return __b_;} 3030*0b57cec5SDimitry Andric 3031*0b57cec5SDimitry Andric friend bool operator==(const param_type& __x, const param_type& __y) 3032*0b57cec5SDimitry Andric {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} 3033*0b57cec5SDimitry Andric friend bool operator!=(const param_type& __x, const param_type& __y) 3034*0b57cec5SDimitry Andric {return !(__x == __y);} 3035*0b57cec5SDimitry Andric }; 3036*0b57cec5SDimitry Andric 3037*0b57cec5SDimitry Andricprivate: 3038*0b57cec5SDimitry Andric param_type __p_; 3039*0b57cec5SDimitry Andric 3040*0b57cec5SDimitry Andricpublic: 3041*0b57cec5SDimitry Andric // constructors and reset functions 3042e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 3043e8d8bef9SDimitry Andric uniform_int_distribution() : uniform_int_distribution(0) {} 3044e8d8bef9SDimitry Andric explicit uniform_int_distribution( 3045e8d8bef9SDimitry Andric result_type __a, result_type __b = numeric_limits<result_type>::max()) 3046e8d8bef9SDimitry Andric : __p_(param_type(__a, __b)) {} 3047e8d8bef9SDimitry Andric#else 3048e8d8bef9SDimitry Andric explicit uniform_int_distribution( 3049e8d8bef9SDimitry Andric result_type __a = 0, 3050*0b57cec5SDimitry Andric result_type __b = numeric_limits<result_type>::max()) 3051*0b57cec5SDimitry Andric : __p_(param_type(__a, __b)) {} 3052e8d8bef9SDimitry Andric#endif 3053*0b57cec5SDimitry Andric explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {} 3054*0b57cec5SDimitry Andric void reset() {} 3055*0b57cec5SDimitry Andric 3056*0b57cec5SDimitry Andric // generating functions 3057*0b57cec5SDimitry Andric template<class _URNG> result_type operator()(_URNG& __g) 3058*0b57cec5SDimitry Andric {return (*this)(__g, __p_);} 3059*0b57cec5SDimitry Andric template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); 3060*0b57cec5SDimitry Andric 3061*0b57cec5SDimitry Andric // property functions 3062*0b57cec5SDimitry Andric result_type a() const {return __p_.a();} 3063*0b57cec5SDimitry Andric result_type b() const {return __p_.b();} 3064*0b57cec5SDimitry Andric 3065*0b57cec5SDimitry Andric param_type param() const {return __p_;} 3066*0b57cec5SDimitry Andric void param(const param_type& __p) {__p_ = __p;} 3067*0b57cec5SDimitry Andric 3068*0b57cec5SDimitry Andric result_type min() const {return a();} 3069*0b57cec5SDimitry Andric result_type max() const {return b();} 3070*0b57cec5SDimitry Andric 3071*0b57cec5SDimitry Andric friend bool operator==(const uniform_int_distribution& __x, 3072*0b57cec5SDimitry Andric const uniform_int_distribution& __y) 3073*0b57cec5SDimitry Andric {return __x.__p_ == __y.__p_;} 3074*0b57cec5SDimitry Andric friend bool operator!=(const uniform_int_distribution& __x, 3075*0b57cec5SDimitry Andric const uniform_int_distribution& __y) 3076*0b57cec5SDimitry Andric {return !(__x == __y);} 3077*0b57cec5SDimitry Andric}; 3078*0b57cec5SDimitry Andric 3079*0b57cec5SDimitry Andrictemplate<class _IntType> 3080*0b57cec5SDimitry Andrictemplate<class _URNG> 3081*0b57cec5SDimitry Andrictypename uniform_int_distribution<_IntType>::result_type 3082*0b57cec5SDimitry Andricuniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p) 3083*0b57cec5SDimitry Andric_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 3084*0b57cec5SDimitry Andric{ 3085*0b57cec5SDimitry Andric typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t), 3086*0b57cec5SDimitry Andric uint32_t, uint64_t>::type _UIntType; 3087*0b57cec5SDimitry Andric const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1); 3088*0b57cec5SDimitry Andric if (_Rp == 1) 3089*0b57cec5SDimitry Andric return __p.a(); 3090*0b57cec5SDimitry Andric const size_t _Dt = numeric_limits<_UIntType>::digits; 3091*0b57cec5SDimitry Andric typedef __independent_bits_engine<_URNG, _UIntType> _Eng; 3092*0b57cec5SDimitry Andric if (_Rp == 0) 3093*0b57cec5SDimitry Andric return static_cast<result_type>(_Eng(__g, _Dt)()); 3094*0b57cec5SDimitry Andric size_t __w = _Dt - __libcpp_clz(_Rp) - 1; 3095e8d8bef9SDimitry Andric if ((_Rp & (numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0) 3096*0b57cec5SDimitry Andric ++__w; 3097*0b57cec5SDimitry Andric _Eng __e(__g, __w); 3098*0b57cec5SDimitry Andric _UIntType __u; 3099*0b57cec5SDimitry Andric do 3100*0b57cec5SDimitry Andric { 3101*0b57cec5SDimitry Andric __u = __e(); 3102*0b57cec5SDimitry Andric } while (__u >= _Rp); 3103*0b57cec5SDimitry Andric return static_cast<result_type>(__u + __p.a()); 3104*0b57cec5SDimitry Andric} 3105*0b57cec5SDimitry Andric 3106*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \ 3107*0b57cec5SDimitry Andric || defined(_LIBCPP_BUILDING_LIBRARY) 3108*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __rs_default; 3109*0b57cec5SDimitry Andric 3110*0b57cec5SDimitry Andric_LIBCPP_FUNC_VIS __rs_default __rs_get(); 3111*0b57cec5SDimitry Andric 3112*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __rs_default 3113*0b57cec5SDimitry Andric{ 3114*0b57cec5SDimitry Andric static unsigned __c_; 3115*0b57cec5SDimitry Andric 3116*0b57cec5SDimitry Andric __rs_default(); 3117*0b57cec5SDimitry Andricpublic: 3118*0b57cec5SDimitry Andric typedef uint_fast32_t result_type; 3119*0b57cec5SDimitry Andric 3120*0b57cec5SDimitry Andric static const result_type _Min = 0; 3121*0b57cec5SDimitry Andric static const result_type _Max = 0xFFFFFFFF; 3122*0b57cec5SDimitry Andric 3123*0b57cec5SDimitry Andric __rs_default(const __rs_default&); 3124*0b57cec5SDimitry Andric ~__rs_default(); 3125*0b57cec5SDimitry Andric 3126*0b57cec5SDimitry Andric result_type operator()(); 3127*0b57cec5SDimitry Andric 3128*0b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR result_type min() {return _Min;} 3129*0b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR result_type max() {return _Max;} 3130*0b57cec5SDimitry Andric 3131*0b57cec5SDimitry Andric friend _LIBCPP_FUNC_VIS __rs_default __rs_get(); 3132*0b57cec5SDimitry Andric}; 3133*0b57cec5SDimitry Andric 3134*0b57cec5SDimitry Andric_LIBCPP_FUNC_VIS __rs_default __rs_get(); 3135*0b57cec5SDimitry Andric 3136*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 3137*0b57cec5SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX14 void 3138*0b57cec5SDimitry Andricrandom_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) 3139*0b57cec5SDimitry Andric{ 3140*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 3141*0b57cec5SDimitry Andric typedef uniform_int_distribution<ptrdiff_t> _Dp; 3142*0b57cec5SDimitry Andric typedef typename _Dp::param_type _Pp; 3143*0b57cec5SDimitry Andric difference_type __d = __last - __first; 3144*0b57cec5SDimitry Andric if (__d > 1) 3145*0b57cec5SDimitry Andric { 3146*0b57cec5SDimitry Andric _Dp __uid; 3147*0b57cec5SDimitry Andric __rs_default __g = __rs_get(); 3148*0b57cec5SDimitry Andric for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) 3149*0b57cec5SDimitry Andric { 3150*0b57cec5SDimitry Andric difference_type __i = __uid(__g, _Pp(0, __d)); 3151*0b57cec5SDimitry Andric if (__i != difference_type(0)) 3152*0b57cec5SDimitry Andric swap(*__first, *(__first + __i)); 3153*0b57cec5SDimitry Andric } 3154*0b57cec5SDimitry Andric } 3155*0b57cec5SDimitry Andric} 3156*0b57cec5SDimitry Andric 3157*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _RandomNumberGenerator> 3158*0b57cec5SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX14 void 3159*0b57cec5SDimitry Andricrandom_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, 3160*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 3161*0b57cec5SDimitry Andric _RandomNumberGenerator&& __rand) 3162*0b57cec5SDimitry Andric#else 3163*0b57cec5SDimitry Andric _RandomNumberGenerator& __rand) 3164*0b57cec5SDimitry Andric#endif 3165*0b57cec5SDimitry Andric{ 3166*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 3167*0b57cec5SDimitry Andric difference_type __d = __last - __first; 3168*0b57cec5SDimitry Andric if (__d > 1) 3169*0b57cec5SDimitry Andric { 3170*0b57cec5SDimitry Andric for (--__last; __first < __last; ++__first, (void) --__d) 3171*0b57cec5SDimitry Andric { 3172*0b57cec5SDimitry Andric difference_type __i = __rand(__d); 3173*0b57cec5SDimitry Andric if (__i != difference_type(0)) 3174*0b57cec5SDimitry Andric swap(*__first, *(__first + __i)); 3175*0b57cec5SDimitry Andric } 3176*0b57cec5SDimitry Andric } 3177*0b57cec5SDimitry Andric} 3178*0b57cec5SDimitry Andric#endif 3179*0b57cec5SDimitry Andric 3180*0b57cec5SDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 3181*0b57cec5SDimitry Andric class _UniformRandomNumberGenerator> 3182*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3183*0b57cec5SDimitry Andric_SampleIterator __sample(_PopulationIterator __first, 3184*0b57cec5SDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 3185*0b57cec5SDimitry Andric _Distance __n, 3186*0b57cec5SDimitry Andric _UniformRandomNumberGenerator & __g, 3187*0b57cec5SDimitry Andric input_iterator_tag) { 3188*0b57cec5SDimitry Andric 3189*0b57cec5SDimitry Andric _Distance __k = 0; 3190*0b57cec5SDimitry Andric for (; __first != __last && __k < __n; ++__first, (void) ++__k) 3191*0b57cec5SDimitry Andric __output_iter[__k] = *__first; 3192*0b57cec5SDimitry Andric _Distance __sz = __k; 3193*0b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__k) { 3194*0b57cec5SDimitry Andric _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g); 3195*0b57cec5SDimitry Andric if (__r < __sz) 3196*0b57cec5SDimitry Andric __output_iter[__r] = *__first; 3197*0b57cec5SDimitry Andric } 3198*0b57cec5SDimitry Andric return __output_iter + _VSTD::min(__n, __k); 3199*0b57cec5SDimitry Andric} 3200*0b57cec5SDimitry Andric 3201*0b57cec5SDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 3202*0b57cec5SDimitry Andric class _UniformRandomNumberGenerator> 3203*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3204*0b57cec5SDimitry Andric_SampleIterator __sample(_PopulationIterator __first, 3205*0b57cec5SDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 3206*0b57cec5SDimitry Andric _Distance __n, 3207*0b57cec5SDimitry Andric _UniformRandomNumberGenerator& __g, 3208*0b57cec5SDimitry Andric forward_iterator_tag) { 3209*0b57cec5SDimitry Andric _Distance __unsampled_sz = _VSTD::distance(__first, __last); 3210*0b57cec5SDimitry Andric for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { 3211*0b57cec5SDimitry Andric _Distance __r = 3212*0b57cec5SDimitry Andric _VSTD::uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); 3213*0b57cec5SDimitry Andric if (__r < __n) { 3214*0b57cec5SDimitry Andric *__output_iter++ = *__first; 3215*0b57cec5SDimitry Andric --__n; 3216*0b57cec5SDimitry Andric } 3217*0b57cec5SDimitry Andric } 3218*0b57cec5SDimitry Andric return __output_iter; 3219*0b57cec5SDimitry Andric} 3220*0b57cec5SDimitry Andric 3221*0b57cec5SDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 3222*0b57cec5SDimitry Andric class _UniformRandomNumberGenerator> 3223*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3224*0b57cec5SDimitry Andric_SampleIterator __sample(_PopulationIterator __first, 3225*0b57cec5SDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 3226*0b57cec5SDimitry Andric _Distance __n, _UniformRandomNumberGenerator& __g) { 3227*0b57cec5SDimitry Andric typedef typename iterator_traits<_PopulationIterator>::iterator_category 3228*0b57cec5SDimitry Andric _PopCategory; 3229*0b57cec5SDimitry Andric typedef typename iterator_traits<_PopulationIterator>::difference_type 3230*0b57cec5SDimitry Andric _Difference; 3231480093f4SDimitry Andric static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value || 3232480093f4SDimitry Andric __is_cpp17_random_access_iterator<_SampleIterator>::value, 3233*0b57cec5SDimitry Andric "SampleIterator must meet the requirements of RandomAccessIterator"); 3234*0b57cec5SDimitry Andric typedef typename common_type<_Distance, _Difference>::type _CommonType; 3235*0b57cec5SDimitry Andric _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); 3236*0b57cec5SDimitry Andric return _VSTD::__sample( 3237*0b57cec5SDimitry Andric __first, __last, __output_iter, _CommonType(__n), 3238*0b57cec5SDimitry Andric __g, _PopCategory()); 3239*0b57cec5SDimitry Andric} 3240*0b57cec5SDimitry Andric 3241*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 3242*0b57cec5SDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 3243*0b57cec5SDimitry Andric class _UniformRandomNumberGenerator> 3244*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 3245*0b57cec5SDimitry Andric_SampleIterator sample(_PopulationIterator __first, 3246*0b57cec5SDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 3247*0b57cec5SDimitry Andric _Distance __n, _UniformRandomNumberGenerator&& __g) { 3248*0b57cec5SDimitry Andric return _VSTD::__sample(__first, __last, __output_iter, __n, __g); 3249*0b57cec5SDimitry Andric} 3250*0b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14 3251*0b57cec5SDimitry Andric 3252*0b57cec5SDimitry Andrictemplate<class _RandomAccessIterator, class _UniformRandomNumberGenerator> 3253*0b57cec5SDimitry Andric void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, 3254*0b57cec5SDimitry Andric _UniformRandomNumberGenerator&& __g) 3255*0b57cec5SDimitry Andric{ 3256*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 3257*0b57cec5SDimitry Andric typedef uniform_int_distribution<ptrdiff_t> _Dp; 3258*0b57cec5SDimitry Andric typedef typename _Dp::param_type _Pp; 3259*0b57cec5SDimitry Andric difference_type __d = __last - __first; 3260*0b57cec5SDimitry Andric if (__d > 1) 3261*0b57cec5SDimitry Andric { 3262*0b57cec5SDimitry Andric _Dp __uid; 3263e40139ffSDimitry Andric for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) 3264*0b57cec5SDimitry Andric { 3265*0b57cec5SDimitry Andric difference_type __i = __uid(__g, _Pp(0, __d)); 3266*0b57cec5SDimitry Andric if (__i != difference_type(0)) 3267*0b57cec5SDimitry Andric swap(*__first, *(__first + __i)); 3268*0b57cec5SDimitry Andric } 3269*0b57cec5SDimitry Andric } 3270*0b57cec5SDimitry Andric} 3271*0b57cec5SDimitry Andric 3272e8d8bef9SDimitry Andric#if _LIBCPP_STD_VER > 17 3273e8d8bef9SDimitry Andric 3274e8d8bef9SDimitry Andric// shift_left, shift_right 3275e8d8bef9SDimitry Andric 3276e8d8bef9SDimitry Andrictemplate <class _ForwardIterator> 3277e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY constexpr 3278e8d8bef9SDimitry Andric_ForwardIterator 3279e8d8bef9SDimitry Andricshift_left(_ForwardIterator __first, _ForwardIterator __last, 3280e8d8bef9SDimitry Andric typename iterator_traits<_ForwardIterator>::difference_type __n) 3281e8d8bef9SDimitry Andric{ 3282e8d8bef9SDimitry Andric if (__n == 0) { 3283e8d8bef9SDimitry Andric return __last; 3284e8d8bef9SDimitry Andric } 3285e8d8bef9SDimitry Andric 3286e8d8bef9SDimitry Andric _ForwardIterator __m = __first; 3287e8d8bef9SDimitry Andric if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) { 3288e8d8bef9SDimitry Andric if (__n >= __last - __first) { 3289e8d8bef9SDimitry Andric return __first; 3290e8d8bef9SDimitry Andric } 3291e8d8bef9SDimitry Andric __m += __n; 3292e8d8bef9SDimitry Andric } else { 3293e8d8bef9SDimitry Andric for (; __n > 0; --__n) { 3294e8d8bef9SDimitry Andric if (__m == __last) { 3295e8d8bef9SDimitry Andric return __first; 3296e8d8bef9SDimitry Andric } 3297e8d8bef9SDimitry Andric ++__m; 3298e8d8bef9SDimitry Andric } 3299e8d8bef9SDimitry Andric } 3300e8d8bef9SDimitry Andric return _VSTD::move(__m, __last, __first); 3301e8d8bef9SDimitry Andric} 3302e8d8bef9SDimitry Andric 3303e8d8bef9SDimitry Andrictemplate <class _ForwardIterator> 3304e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY constexpr 3305e8d8bef9SDimitry Andric_ForwardIterator 3306e8d8bef9SDimitry Andricshift_right(_ForwardIterator __first, _ForwardIterator __last, 3307e8d8bef9SDimitry Andric typename iterator_traits<_ForwardIterator>::difference_type __n) 3308e8d8bef9SDimitry Andric{ 3309e8d8bef9SDimitry Andric if (__n == 0) { 3310e8d8bef9SDimitry Andric return __first; 3311e8d8bef9SDimitry Andric } 3312e8d8bef9SDimitry Andric 3313e8d8bef9SDimitry Andric if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) { 3314e8d8bef9SDimitry Andric decltype(__n) __d = __last - __first; 3315e8d8bef9SDimitry Andric if (__n >= __d) { 3316e8d8bef9SDimitry Andric return __last; 3317e8d8bef9SDimitry Andric } 3318e8d8bef9SDimitry Andric _ForwardIterator __m = __first + (__d - __n); 3319e8d8bef9SDimitry Andric return _VSTD::move_backward(__first, __m, __last); 3320e8d8bef9SDimitry Andric } else if constexpr (__is_cpp17_bidirectional_iterator<_ForwardIterator>::value) { 3321e8d8bef9SDimitry Andric _ForwardIterator __m = __last; 3322e8d8bef9SDimitry Andric for (; __n > 0; --__n) { 3323e8d8bef9SDimitry Andric if (__m == __first) { 3324e8d8bef9SDimitry Andric return __last; 3325e8d8bef9SDimitry Andric } 3326e8d8bef9SDimitry Andric --__m; 3327e8d8bef9SDimitry Andric } 3328e8d8bef9SDimitry Andric return _VSTD::move_backward(__first, __m, __last); 3329e8d8bef9SDimitry Andric } else { 3330e8d8bef9SDimitry Andric _ForwardIterator __ret = __first; 3331e8d8bef9SDimitry Andric for (; __n > 0; --__n) { 3332e8d8bef9SDimitry Andric if (__ret == __last) { 3333e8d8bef9SDimitry Andric return __last; 3334e8d8bef9SDimitry Andric } 3335e8d8bef9SDimitry Andric ++__ret; 3336e8d8bef9SDimitry Andric } 3337e8d8bef9SDimitry Andric 3338e8d8bef9SDimitry Andric // We have an __n-element scratch space from __first to __ret. 3339e8d8bef9SDimitry Andric // Slide an __n-element window [__trail, __lead) from left to right. 3340e8d8bef9SDimitry Andric // We're essentially doing swap_ranges(__first, __ret, __trail, __lead) 3341e8d8bef9SDimitry Andric // over and over; but once __lead reaches __last we needn't bother 3342e8d8bef9SDimitry Andric // to save the values of elements [__trail, __last). 3343e8d8bef9SDimitry Andric 3344e8d8bef9SDimitry Andric auto __trail = __first; 3345e8d8bef9SDimitry Andric auto __lead = __ret; 3346e8d8bef9SDimitry Andric while (__trail != __ret) { 3347e8d8bef9SDimitry Andric if (__lead == __last) { 3348e8d8bef9SDimitry Andric _VSTD::move(__first, __trail, __ret); 3349e8d8bef9SDimitry Andric return __ret; 3350e8d8bef9SDimitry Andric } 3351e8d8bef9SDimitry Andric ++__trail; 3352e8d8bef9SDimitry Andric ++__lead; 3353e8d8bef9SDimitry Andric } 3354e8d8bef9SDimitry Andric 3355e8d8bef9SDimitry Andric _ForwardIterator __mid = __first; 3356e8d8bef9SDimitry Andric while (true) { 3357e8d8bef9SDimitry Andric if (__lead == __last) { 3358e8d8bef9SDimitry Andric __trail = _VSTD::move(__mid, __ret, __trail); 3359e8d8bef9SDimitry Andric _VSTD::move(__first, __mid, __trail); 3360e8d8bef9SDimitry Andric return __ret; 3361e8d8bef9SDimitry Andric } 3362e8d8bef9SDimitry Andric swap(*__mid, *__trail); 3363e8d8bef9SDimitry Andric ++__mid; 3364e8d8bef9SDimitry Andric ++__trail; 3365e8d8bef9SDimitry Andric ++__lead; 3366e8d8bef9SDimitry Andric if (__mid == __ret) { 3367e8d8bef9SDimitry Andric __mid = __first; 3368e8d8bef9SDimitry Andric } 3369e8d8bef9SDimitry Andric } 3370e8d8bef9SDimitry Andric } 3371e8d8bef9SDimitry Andric} 3372e8d8bef9SDimitry Andric 3373e8d8bef9SDimitry Andric#endif // _LIBCPP_STD_VER > 17 3374e8d8bef9SDimitry Andric 3375e8d8bef9SDimitry Andric// is_partitioned 3376e8d8bef9SDimitry Andric 3377*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 3378*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool 3379*0b57cec5SDimitry Andricis_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) 3380*0b57cec5SDimitry Andric{ 3381*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 3382*0b57cec5SDimitry Andric if (!__pred(*__first)) 3383*0b57cec5SDimitry Andric break; 3384*0b57cec5SDimitry Andric if ( __first == __last ) 3385*0b57cec5SDimitry Andric return true; 3386*0b57cec5SDimitry Andric ++__first; 3387*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 3388*0b57cec5SDimitry Andric if (__pred(*__first)) 3389*0b57cec5SDimitry Andric return false; 3390*0b57cec5SDimitry Andric return true; 3391*0b57cec5SDimitry Andric} 3392*0b57cec5SDimitry Andric 3393*0b57cec5SDimitry Andric// partition 3394*0b57cec5SDimitry Andric 3395*0b57cec5SDimitry Andrictemplate <class _Predicate, class _ForwardIterator> 3396e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 3397*0b57cec5SDimitry Andric__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) 3398*0b57cec5SDimitry Andric{ 3399*0b57cec5SDimitry Andric while (true) 3400*0b57cec5SDimitry Andric { 3401*0b57cec5SDimitry Andric if (__first == __last) 3402*0b57cec5SDimitry Andric return __first; 3403*0b57cec5SDimitry Andric if (!__pred(*__first)) 3404*0b57cec5SDimitry Andric break; 3405*0b57cec5SDimitry Andric ++__first; 3406*0b57cec5SDimitry Andric } 3407*0b57cec5SDimitry Andric for (_ForwardIterator __p = __first; ++__p != __last;) 3408*0b57cec5SDimitry Andric { 3409*0b57cec5SDimitry Andric if (__pred(*__p)) 3410*0b57cec5SDimitry Andric { 3411*0b57cec5SDimitry Andric swap(*__first, *__p); 3412*0b57cec5SDimitry Andric ++__first; 3413*0b57cec5SDimitry Andric } 3414*0b57cec5SDimitry Andric } 3415*0b57cec5SDimitry Andric return __first; 3416*0b57cec5SDimitry Andric} 3417*0b57cec5SDimitry Andric 3418*0b57cec5SDimitry Andrictemplate <class _Predicate, class _BidirectionalIterator> 3419e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator 3420*0b57cec5SDimitry Andric__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, 3421*0b57cec5SDimitry Andric bidirectional_iterator_tag) 3422*0b57cec5SDimitry Andric{ 3423*0b57cec5SDimitry Andric while (true) 3424*0b57cec5SDimitry Andric { 3425*0b57cec5SDimitry Andric while (true) 3426*0b57cec5SDimitry Andric { 3427*0b57cec5SDimitry Andric if (__first == __last) 3428*0b57cec5SDimitry Andric return __first; 3429*0b57cec5SDimitry Andric if (!__pred(*__first)) 3430*0b57cec5SDimitry Andric break; 3431*0b57cec5SDimitry Andric ++__first; 3432*0b57cec5SDimitry Andric } 3433*0b57cec5SDimitry Andric do 3434*0b57cec5SDimitry Andric { 3435*0b57cec5SDimitry Andric if (__first == --__last) 3436*0b57cec5SDimitry Andric return __first; 3437*0b57cec5SDimitry Andric } while (!__pred(*__last)); 3438*0b57cec5SDimitry Andric swap(*__first, *__last); 3439*0b57cec5SDimitry Andric ++__first; 3440*0b57cec5SDimitry Andric } 3441*0b57cec5SDimitry Andric} 3442*0b57cec5SDimitry Andric 3443*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Predicate> 3444e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 3445*0b57cec5SDimitry Andric_ForwardIterator 3446*0b57cec5SDimitry Andricpartition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 3447*0b57cec5SDimitry Andric{ 3448*0b57cec5SDimitry Andric return _VSTD::__partition<typename add_lvalue_reference<_Predicate>::type> 3449*0b57cec5SDimitry Andric (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); 3450*0b57cec5SDimitry Andric} 3451*0b57cec5SDimitry Andric 3452*0b57cec5SDimitry Andric// partition_copy 3453*0b57cec5SDimitry Andric 3454*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator1, 3455*0b57cec5SDimitry Andric class _OutputIterator2, class _Predicate> 3456*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_OutputIterator1, _OutputIterator2> 3457*0b57cec5SDimitry Andricpartition_copy(_InputIterator __first, _InputIterator __last, 3458*0b57cec5SDimitry Andric _OutputIterator1 __out_true, _OutputIterator2 __out_false, 3459*0b57cec5SDimitry Andric _Predicate __pred) 3460*0b57cec5SDimitry Andric{ 3461*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 3462*0b57cec5SDimitry Andric { 3463*0b57cec5SDimitry Andric if (__pred(*__first)) 3464*0b57cec5SDimitry Andric { 3465*0b57cec5SDimitry Andric *__out_true = *__first; 3466*0b57cec5SDimitry Andric ++__out_true; 3467*0b57cec5SDimitry Andric } 3468*0b57cec5SDimitry Andric else 3469*0b57cec5SDimitry Andric { 3470*0b57cec5SDimitry Andric *__out_false = *__first; 3471*0b57cec5SDimitry Andric ++__out_false; 3472*0b57cec5SDimitry Andric } 3473*0b57cec5SDimitry Andric } 3474*0b57cec5SDimitry Andric return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); 3475*0b57cec5SDimitry Andric} 3476*0b57cec5SDimitry Andric 3477*0b57cec5SDimitry Andric// partition_point 3478*0b57cec5SDimitry Andric 3479*0b57cec5SDimitry Andrictemplate<class _ForwardIterator, class _Predicate> 3480*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 3481*0b57cec5SDimitry Andricpartition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 3482*0b57cec5SDimitry Andric{ 3483*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 3484*0b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last); 3485*0b57cec5SDimitry Andric while (__len != 0) 3486*0b57cec5SDimitry Andric { 3487*0b57cec5SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 3488*0b57cec5SDimitry Andric _ForwardIterator __m = __first; 3489*0b57cec5SDimitry Andric _VSTD::advance(__m, __l2); 3490*0b57cec5SDimitry Andric if (__pred(*__m)) 3491*0b57cec5SDimitry Andric { 3492*0b57cec5SDimitry Andric __first = ++__m; 3493*0b57cec5SDimitry Andric __len -= __l2 + 1; 3494*0b57cec5SDimitry Andric } 3495*0b57cec5SDimitry Andric else 3496*0b57cec5SDimitry Andric __len = __l2; 3497*0b57cec5SDimitry Andric } 3498*0b57cec5SDimitry Andric return __first; 3499*0b57cec5SDimitry Andric} 3500*0b57cec5SDimitry Andric 3501*0b57cec5SDimitry Andric// stable_partition 3502*0b57cec5SDimitry Andric 3503*0b57cec5SDimitry Andrictemplate <class _Predicate, class _ForwardIterator, class _Distance, class _Pair> 3504*0b57cec5SDimitry Andric_ForwardIterator 3505*0b57cec5SDimitry Andric__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, 3506*0b57cec5SDimitry Andric _Distance __len, _Pair __p, forward_iterator_tag __fit) 3507*0b57cec5SDimitry Andric{ 3508*0b57cec5SDimitry Andric // *__first is known to be false 3509*0b57cec5SDimitry Andric // __len >= 1 3510*0b57cec5SDimitry Andric if (__len == 1) 3511*0b57cec5SDimitry Andric return __first; 3512*0b57cec5SDimitry Andric if (__len == 2) 3513*0b57cec5SDimitry Andric { 3514*0b57cec5SDimitry Andric _ForwardIterator __m = __first; 3515*0b57cec5SDimitry Andric if (__pred(*++__m)) 3516*0b57cec5SDimitry Andric { 3517*0b57cec5SDimitry Andric swap(*__first, *__m); 3518*0b57cec5SDimitry Andric return __m; 3519*0b57cec5SDimitry Andric } 3520*0b57cec5SDimitry Andric return __first; 3521*0b57cec5SDimitry Andric } 3522*0b57cec5SDimitry Andric if (__len <= __p.second) 3523*0b57cec5SDimitry Andric { // The buffer is big enough to use 3524*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type value_type; 3525*0b57cec5SDimitry Andric __destruct_n __d(0); 3526*0b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h(__p.first, __d); 3527*0b57cec5SDimitry Andric // Move the falses into the temporary buffer, and the trues to the front of the line 3528*0b57cec5SDimitry Andric // Update __first to always point to the end of the trues 3529*0b57cec5SDimitry Andric value_type* __t = __p.first; 3530e8d8bef9SDimitry Andric ::new ((void*)__t) value_type(_VSTD::move(*__first)); 3531e8d8bef9SDimitry Andric __d.template __incr<value_type>(); 3532*0b57cec5SDimitry Andric ++__t; 3533*0b57cec5SDimitry Andric _ForwardIterator __i = __first; 3534*0b57cec5SDimitry Andric while (++__i != __last) 3535*0b57cec5SDimitry Andric { 3536*0b57cec5SDimitry Andric if (__pred(*__i)) 3537*0b57cec5SDimitry Andric { 3538*0b57cec5SDimitry Andric *__first = _VSTD::move(*__i); 3539*0b57cec5SDimitry Andric ++__first; 3540*0b57cec5SDimitry Andric } 3541*0b57cec5SDimitry Andric else 3542*0b57cec5SDimitry Andric { 3543e8d8bef9SDimitry Andric ::new ((void*)__t) value_type(_VSTD::move(*__i)); 3544e8d8bef9SDimitry Andric __d.template __incr<value_type>(); 3545*0b57cec5SDimitry Andric ++__t; 3546*0b57cec5SDimitry Andric } 3547*0b57cec5SDimitry Andric } 3548*0b57cec5SDimitry Andric // All trues now at start of range, all falses in buffer 3549*0b57cec5SDimitry Andric // Move falses back into range, but don't mess up __first which points to first false 3550*0b57cec5SDimitry Andric __i = __first; 3551e40139ffSDimitry Andric for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) 3552*0b57cec5SDimitry Andric *__i = _VSTD::move(*__t2); 3553*0b57cec5SDimitry Andric // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer 3554*0b57cec5SDimitry Andric return __first; 3555*0b57cec5SDimitry Andric } 3556*0b57cec5SDimitry Andric // Else not enough buffer, do in place 3557*0b57cec5SDimitry Andric // __len >= 3 3558*0b57cec5SDimitry Andric _ForwardIterator __m = __first; 3559*0b57cec5SDimitry Andric _Distance __len2 = __len / 2; // __len2 >= 2 3560*0b57cec5SDimitry Andric _VSTD::advance(__m, __len2); 3561*0b57cec5SDimitry Andric // recurse on [__first, __m), *__first know to be false 3562*0b57cec5SDimitry Andric // F????????????????? 3563*0b57cec5SDimitry Andric // f m l 3564*0b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Predicate>::type _PredRef; 3565e8d8bef9SDimitry Andric _ForwardIterator __first_false = _VSTD::__stable_partition<_PredRef>(__first, __m, __pred, __len2, __p, __fit); 3566*0b57cec5SDimitry Andric // TTTFFFFF?????????? 3567*0b57cec5SDimitry Andric // f ff m l 3568*0b57cec5SDimitry Andric // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true 3569*0b57cec5SDimitry Andric _ForwardIterator __m1 = __m; 3570*0b57cec5SDimitry Andric _ForwardIterator __second_false = __last; 3571*0b57cec5SDimitry Andric _Distance __len_half = __len - __len2; 3572*0b57cec5SDimitry Andric while (__pred(*__m1)) 3573*0b57cec5SDimitry Andric { 3574*0b57cec5SDimitry Andric if (++__m1 == __last) 3575*0b57cec5SDimitry Andric goto __second_half_done; 3576*0b57cec5SDimitry Andric --__len_half; 3577*0b57cec5SDimitry Andric } 3578*0b57cec5SDimitry Andric // TTTFFFFFTTTF?????? 3579*0b57cec5SDimitry Andric // f ff m m1 l 3580e8d8bef9SDimitry Andric __second_false = _VSTD::__stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __fit); 3581*0b57cec5SDimitry Andric__second_half_done: 3582*0b57cec5SDimitry Andric // TTTFFFFFTTTTTFFFFF 3583*0b57cec5SDimitry Andric // f ff m sf l 3584*0b57cec5SDimitry Andric return _VSTD::rotate(__first_false, __m, __second_false); 3585*0b57cec5SDimitry Andric // TTTTTTTTFFFFFFFFFF 3586*0b57cec5SDimitry Andric // | 3587*0b57cec5SDimitry Andric} 3588*0b57cec5SDimitry Andric 3589*0b57cec5SDimitry Andricstruct __return_temporary_buffer 3590*0b57cec5SDimitry Andric{ 3591*0b57cec5SDimitry Andric template <class _Tp> 3592*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);} 3593*0b57cec5SDimitry Andric}; 3594*0b57cec5SDimitry Andric 3595*0b57cec5SDimitry Andrictemplate <class _Predicate, class _ForwardIterator> 3596*0b57cec5SDimitry Andric_ForwardIterator 3597*0b57cec5SDimitry Andric__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, 3598*0b57cec5SDimitry Andric forward_iterator_tag) 3599*0b57cec5SDimitry Andric{ 3600*0b57cec5SDimitry Andric const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment 3601*0b57cec5SDimitry Andric // Either prove all true and return __first or point to first false 3602*0b57cec5SDimitry Andric while (true) 3603*0b57cec5SDimitry Andric { 3604*0b57cec5SDimitry Andric if (__first == __last) 3605*0b57cec5SDimitry Andric return __first; 3606*0b57cec5SDimitry Andric if (!__pred(*__first)) 3607*0b57cec5SDimitry Andric break; 3608*0b57cec5SDimitry Andric ++__first; 3609*0b57cec5SDimitry Andric } 3610*0b57cec5SDimitry Andric // We now have a reduced range [__first, __last) 3611*0b57cec5SDimitry Andric // *__first is known to be false 3612*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 3613*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type value_type; 3614*0b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last); 3615*0b57cec5SDimitry Andric pair<value_type*, ptrdiff_t> __p(0, 0); 3616*0b57cec5SDimitry Andric unique_ptr<value_type, __return_temporary_buffer> __h; 3617*0b57cec5SDimitry Andric if (__len >= __alloc_limit) 3618*0b57cec5SDimitry Andric { 3619*0b57cec5SDimitry Andric __p = _VSTD::get_temporary_buffer<value_type>(__len); 3620*0b57cec5SDimitry Andric __h.reset(__p.first); 3621*0b57cec5SDimitry Andric } 3622e8d8bef9SDimitry Andric return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type> 3623*0b57cec5SDimitry Andric (__first, __last, __pred, __len, __p, forward_iterator_tag()); 3624*0b57cec5SDimitry Andric} 3625*0b57cec5SDimitry Andric 3626*0b57cec5SDimitry Andrictemplate <class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair> 3627*0b57cec5SDimitry Andric_BidirectionalIterator 3628*0b57cec5SDimitry Andric__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, 3629*0b57cec5SDimitry Andric _Distance __len, _Pair __p, bidirectional_iterator_tag __bit) 3630*0b57cec5SDimitry Andric{ 3631*0b57cec5SDimitry Andric // *__first is known to be false 3632*0b57cec5SDimitry Andric // *__last is known to be true 3633*0b57cec5SDimitry Andric // __len >= 2 3634*0b57cec5SDimitry Andric if (__len == 2) 3635*0b57cec5SDimitry Andric { 3636*0b57cec5SDimitry Andric swap(*__first, *__last); 3637*0b57cec5SDimitry Andric return __last; 3638*0b57cec5SDimitry Andric } 3639*0b57cec5SDimitry Andric if (__len == 3) 3640*0b57cec5SDimitry Andric { 3641*0b57cec5SDimitry Andric _BidirectionalIterator __m = __first; 3642*0b57cec5SDimitry Andric if (__pred(*++__m)) 3643*0b57cec5SDimitry Andric { 3644*0b57cec5SDimitry Andric swap(*__first, *__m); 3645*0b57cec5SDimitry Andric swap(*__m, *__last); 3646*0b57cec5SDimitry Andric return __last; 3647*0b57cec5SDimitry Andric } 3648*0b57cec5SDimitry Andric swap(*__m, *__last); 3649*0b57cec5SDimitry Andric swap(*__first, *__m); 3650*0b57cec5SDimitry Andric return __m; 3651*0b57cec5SDimitry Andric } 3652*0b57cec5SDimitry Andric if (__len <= __p.second) 3653*0b57cec5SDimitry Andric { // The buffer is big enough to use 3654*0b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 3655*0b57cec5SDimitry Andric __destruct_n __d(0); 3656*0b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h(__p.first, __d); 3657*0b57cec5SDimitry Andric // Move the falses into the temporary buffer, and the trues to the front of the line 3658*0b57cec5SDimitry Andric // Update __first to always point to the end of the trues 3659*0b57cec5SDimitry Andric value_type* __t = __p.first; 3660e8d8bef9SDimitry Andric ::new ((void*)__t) value_type(_VSTD::move(*__first)); 3661e8d8bef9SDimitry Andric __d.template __incr<value_type>(); 3662*0b57cec5SDimitry Andric ++__t; 3663*0b57cec5SDimitry Andric _BidirectionalIterator __i = __first; 3664*0b57cec5SDimitry Andric while (++__i != __last) 3665*0b57cec5SDimitry Andric { 3666*0b57cec5SDimitry Andric if (__pred(*__i)) 3667*0b57cec5SDimitry Andric { 3668*0b57cec5SDimitry Andric *__first = _VSTD::move(*__i); 3669*0b57cec5SDimitry Andric ++__first; 3670*0b57cec5SDimitry Andric } 3671*0b57cec5SDimitry Andric else 3672*0b57cec5SDimitry Andric { 3673e8d8bef9SDimitry Andric ::new ((void*)__t) value_type(_VSTD::move(*__i)); 3674e8d8bef9SDimitry Andric __d.template __incr<value_type>(); 3675*0b57cec5SDimitry Andric ++__t; 3676*0b57cec5SDimitry Andric } 3677*0b57cec5SDimitry Andric } 3678*0b57cec5SDimitry Andric // move *__last, known to be true 3679*0b57cec5SDimitry Andric *__first = _VSTD::move(*__i); 3680*0b57cec5SDimitry Andric __i = ++__first; 3681*0b57cec5SDimitry Andric // All trues now at start of range, all falses in buffer 3682*0b57cec5SDimitry Andric // Move falses back into range, but don't mess up __first which points to first false 3683e40139ffSDimitry Andric for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) 3684*0b57cec5SDimitry Andric *__i = _VSTD::move(*__t2); 3685*0b57cec5SDimitry Andric // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer 3686*0b57cec5SDimitry Andric return __first; 3687*0b57cec5SDimitry Andric } 3688*0b57cec5SDimitry Andric // Else not enough buffer, do in place 3689*0b57cec5SDimitry Andric // __len >= 4 3690*0b57cec5SDimitry Andric _BidirectionalIterator __m = __first; 3691*0b57cec5SDimitry Andric _Distance __len2 = __len / 2; // __len2 >= 2 3692*0b57cec5SDimitry Andric _VSTD::advance(__m, __len2); 3693*0b57cec5SDimitry Andric // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false 3694*0b57cec5SDimitry Andric // F????????????????T 3695*0b57cec5SDimitry Andric // f m l 3696*0b57cec5SDimitry Andric _BidirectionalIterator __m1 = __m; 3697*0b57cec5SDimitry Andric _BidirectionalIterator __first_false = __first; 3698*0b57cec5SDimitry Andric _Distance __len_half = __len2; 3699*0b57cec5SDimitry Andric while (!__pred(*--__m1)) 3700*0b57cec5SDimitry Andric { 3701*0b57cec5SDimitry Andric if (__m1 == __first) 3702*0b57cec5SDimitry Andric goto __first_half_done; 3703*0b57cec5SDimitry Andric --__len_half; 3704*0b57cec5SDimitry Andric } 3705*0b57cec5SDimitry Andric // F???TFFF?????????T 3706*0b57cec5SDimitry Andric // f m1 m l 3707*0b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Predicate>::type _PredRef; 3708e8d8bef9SDimitry Andric __first_false = _VSTD::__stable_partition<_PredRef>(__first, __m1, __pred, __len_half, __p, __bit); 3709*0b57cec5SDimitry Andric__first_half_done: 3710*0b57cec5SDimitry Andric // TTTFFFFF?????????T 3711*0b57cec5SDimitry Andric // f ff m l 3712*0b57cec5SDimitry Andric // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true 3713*0b57cec5SDimitry Andric __m1 = __m; 3714*0b57cec5SDimitry Andric _BidirectionalIterator __second_false = __last; 3715*0b57cec5SDimitry Andric ++__second_false; 3716*0b57cec5SDimitry Andric __len_half = __len - __len2; 3717*0b57cec5SDimitry Andric while (__pred(*__m1)) 3718*0b57cec5SDimitry Andric { 3719*0b57cec5SDimitry Andric if (++__m1 == __last) 3720*0b57cec5SDimitry Andric goto __second_half_done; 3721*0b57cec5SDimitry Andric --__len_half; 3722*0b57cec5SDimitry Andric } 3723*0b57cec5SDimitry Andric // TTTFFFFFTTTF?????T 3724*0b57cec5SDimitry Andric // f ff m m1 l 3725e8d8bef9SDimitry Andric __second_false = _VSTD::__stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __bit); 3726*0b57cec5SDimitry Andric__second_half_done: 3727*0b57cec5SDimitry Andric // TTTFFFFFTTTTTFFFFF 3728*0b57cec5SDimitry Andric // f ff m sf l 3729*0b57cec5SDimitry Andric return _VSTD::rotate(__first_false, __m, __second_false); 3730*0b57cec5SDimitry Andric // TTTTTTTTFFFFFFFFFF 3731*0b57cec5SDimitry Andric // | 3732*0b57cec5SDimitry Andric} 3733*0b57cec5SDimitry Andric 3734*0b57cec5SDimitry Andrictemplate <class _Predicate, class _BidirectionalIterator> 3735*0b57cec5SDimitry Andric_BidirectionalIterator 3736*0b57cec5SDimitry Andric__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, 3737*0b57cec5SDimitry Andric bidirectional_iterator_tag) 3738*0b57cec5SDimitry Andric{ 3739*0b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; 3740*0b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 3741*0b57cec5SDimitry Andric const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment 3742*0b57cec5SDimitry Andric // Either prove all true and return __first or point to first false 3743*0b57cec5SDimitry Andric while (true) 3744*0b57cec5SDimitry Andric { 3745*0b57cec5SDimitry Andric if (__first == __last) 3746*0b57cec5SDimitry Andric return __first; 3747*0b57cec5SDimitry Andric if (!__pred(*__first)) 3748*0b57cec5SDimitry Andric break; 3749*0b57cec5SDimitry Andric ++__first; 3750*0b57cec5SDimitry Andric } 3751*0b57cec5SDimitry Andric // __first points to first false, everything prior to __first is already set. 3752*0b57cec5SDimitry Andric // Either prove [__first, __last) is all false and return __first, or point __last to last true 3753*0b57cec5SDimitry Andric do 3754*0b57cec5SDimitry Andric { 3755*0b57cec5SDimitry Andric if (__first == --__last) 3756*0b57cec5SDimitry Andric return __first; 3757*0b57cec5SDimitry Andric } while (!__pred(*__last)); 3758*0b57cec5SDimitry Andric // We now have a reduced range [__first, __last] 3759*0b57cec5SDimitry Andric // *__first is known to be false 3760*0b57cec5SDimitry Andric // *__last is known to be true 3761*0b57cec5SDimitry Andric // __len >= 2 3762*0b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last) + 1; 3763*0b57cec5SDimitry Andric pair<value_type*, ptrdiff_t> __p(0, 0); 3764*0b57cec5SDimitry Andric unique_ptr<value_type, __return_temporary_buffer> __h; 3765*0b57cec5SDimitry Andric if (__len >= __alloc_limit) 3766*0b57cec5SDimitry Andric { 3767*0b57cec5SDimitry Andric __p = _VSTD::get_temporary_buffer<value_type>(__len); 3768*0b57cec5SDimitry Andric __h.reset(__p.first); 3769*0b57cec5SDimitry Andric } 3770e8d8bef9SDimitry Andric return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type> 3771*0b57cec5SDimitry Andric (__first, __last, __pred, __len, __p, bidirectional_iterator_tag()); 3772*0b57cec5SDimitry Andric} 3773*0b57cec5SDimitry Andric 3774*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Predicate> 3775*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 3776*0b57cec5SDimitry Andric_ForwardIterator 3777*0b57cec5SDimitry Andricstable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 3778*0b57cec5SDimitry Andric{ 3779e8d8bef9SDimitry Andric return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type> 3780*0b57cec5SDimitry Andric (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); 3781*0b57cec5SDimitry Andric} 3782*0b57cec5SDimitry Andric 3783*0b57cec5SDimitry Andric// is_sorted_until 3784*0b57cec5SDimitry Andric 3785*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Compare> 3786*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 3787*0b57cec5SDimitry Andricis_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 3788*0b57cec5SDimitry Andric{ 3789*0b57cec5SDimitry Andric if (__first != __last) 3790*0b57cec5SDimitry Andric { 3791*0b57cec5SDimitry Andric _ForwardIterator __i = __first; 3792*0b57cec5SDimitry Andric while (++__i != __last) 3793*0b57cec5SDimitry Andric { 3794*0b57cec5SDimitry Andric if (__comp(*__i, *__first)) 3795*0b57cec5SDimitry Andric return __i; 3796*0b57cec5SDimitry Andric __first = __i; 3797*0b57cec5SDimitry Andric } 3798*0b57cec5SDimitry Andric } 3799*0b57cec5SDimitry Andric return __last; 3800*0b57cec5SDimitry Andric} 3801*0b57cec5SDimitry Andric 3802*0b57cec5SDimitry Andrictemplate<class _ForwardIterator> 3803*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 3804*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 3805*0b57cec5SDimitry Andric_ForwardIterator 3806*0b57cec5SDimitry Andricis_sorted_until(_ForwardIterator __first, _ForwardIterator __last) 3807*0b57cec5SDimitry Andric{ 3808*0b57cec5SDimitry Andric return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>()); 3809*0b57cec5SDimitry Andric} 3810*0b57cec5SDimitry Andric 3811*0b57cec5SDimitry Andric// is_sorted 3812*0b57cec5SDimitry Andric 3813*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Compare> 3814*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 3815*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 3816*0b57cec5SDimitry Andricbool 3817*0b57cec5SDimitry Andricis_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 3818*0b57cec5SDimitry Andric{ 3819*0b57cec5SDimitry Andric return _VSTD::is_sorted_until(__first, __last, __comp) == __last; 3820*0b57cec5SDimitry Andric} 3821*0b57cec5SDimitry Andric 3822*0b57cec5SDimitry Andrictemplate<class _ForwardIterator> 3823*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 3824*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 3825*0b57cec5SDimitry Andricbool 3826*0b57cec5SDimitry Andricis_sorted(_ForwardIterator __first, _ForwardIterator __last) 3827*0b57cec5SDimitry Andric{ 3828*0b57cec5SDimitry Andric return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>()); 3829*0b57cec5SDimitry Andric} 3830*0b57cec5SDimitry Andric 3831*0b57cec5SDimitry Andric// sort 3832*0b57cec5SDimitry Andric 3833*0b57cec5SDimitry Andric// stable, 2-3 compares, 0-2 swaps 3834*0b57cec5SDimitry Andric 3835*0b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator> 3836*0b57cec5SDimitry Andricunsigned 3837*0b57cec5SDimitry Andric__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c) 3838*0b57cec5SDimitry Andric{ 3839*0b57cec5SDimitry Andric unsigned __r = 0; 3840*0b57cec5SDimitry Andric if (!__c(*__y, *__x)) // if x <= y 3841*0b57cec5SDimitry Andric { 3842*0b57cec5SDimitry Andric if (!__c(*__z, *__y)) // if y <= z 3843*0b57cec5SDimitry Andric return __r; // x <= y && y <= z 3844*0b57cec5SDimitry Andric // x <= y && y > z 3845*0b57cec5SDimitry Andric swap(*__y, *__z); // x <= z && y < z 3846*0b57cec5SDimitry Andric __r = 1; 3847*0b57cec5SDimitry Andric if (__c(*__y, *__x)) // if x > y 3848*0b57cec5SDimitry Andric { 3849*0b57cec5SDimitry Andric swap(*__x, *__y); // x < y && y <= z 3850*0b57cec5SDimitry Andric __r = 2; 3851*0b57cec5SDimitry Andric } 3852*0b57cec5SDimitry Andric return __r; // x <= y && y < z 3853*0b57cec5SDimitry Andric } 3854*0b57cec5SDimitry Andric if (__c(*__z, *__y)) // x > y, if y > z 3855*0b57cec5SDimitry Andric { 3856*0b57cec5SDimitry Andric swap(*__x, *__z); // x < y && y < z 3857*0b57cec5SDimitry Andric __r = 1; 3858*0b57cec5SDimitry Andric return __r; 3859*0b57cec5SDimitry Andric } 3860*0b57cec5SDimitry Andric swap(*__x, *__y); // x > y && y <= z 3861*0b57cec5SDimitry Andric __r = 1; // x < y && x <= z 3862*0b57cec5SDimitry Andric if (__c(*__z, *__y)) // if y > z 3863*0b57cec5SDimitry Andric { 3864*0b57cec5SDimitry Andric swap(*__y, *__z); // x <= y && y < z 3865*0b57cec5SDimitry Andric __r = 2; 3866*0b57cec5SDimitry Andric } 3867*0b57cec5SDimitry Andric return __r; 3868*0b57cec5SDimitry Andric} // x <= y && y <= z 3869*0b57cec5SDimitry Andric 3870*0b57cec5SDimitry Andric// stable, 3-6 compares, 0-5 swaps 3871*0b57cec5SDimitry Andric 3872*0b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator> 3873*0b57cec5SDimitry Andricunsigned 3874*0b57cec5SDimitry Andric__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, 3875*0b57cec5SDimitry Andric _ForwardIterator __x4, _Compare __c) 3876*0b57cec5SDimitry Andric{ 3877e8d8bef9SDimitry Andric unsigned __r = _VSTD::__sort3<_Compare>(__x1, __x2, __x3, __c); 3878*0b57cec5SDimitry Andric if (__c(*__x4, *__x3)) 3879*0b57cec5SDimitry Andric { 3880*0b57cec5SDimitry Andric swap(*__x3, *__x4); 3881*0b57cec5SDimitry Andric ++__r; 3882*0b57cec5SDimitry Andric if (__c(*__x3, *__x2)) 3883*0b57cec5SDimitry Andric { 3884*0b57cec5SDimitry Andric swap(*__x2, *__x3); 3885*0b57cec5SDimitry Andric ++__r; 3886*0b57cec5SDimitry Andric if (__c(*__x2, *__x1)) 3887*0b57cec5SDimitry Andric { 3888*0b57cec5SDimitry Andric swap(*__x1, *__x2); 3889*0b57cec5SDimitry Andric ++__r; 3890*0b57cec5SDimitry Andric } 3891*0b57cec5SDimitry Andric } 3892*0b57cec5SDimitry Andric } 3893*0b57cec5SDimitry Andric return __r; 3894*0b57cec5SDimitry Andric} 3895*0b57cec5SDimitry Andric 3896*0b57cec5SDimitry Andric// stable, 4-10 compares, 0-9 swaps 3897*0b57cec5SDimitry Andric 3898*0b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator> 3899*0b57cec5SDimitry Andric_LIBCPP_HIDDEN 3900*0b57cec5SDimitry Andricunsigned 3901*0b57cec5SDimitry Andric__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, 3902*0b57cec5SDimitry Andric _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c) 3903*0b57cec5SDimitry Andric{ 3904e8d8bef9SDimitry Andric unsigned __r = _VSTD::__sort4<_Compare>(__x1, __x2, __x3, __x4, __c); 3905*0b57cec5SDimitry Andric if (__c(*__x5, *__x4)) 3906*0b57cec5SDimitry Andric { 3907*0b57cec5SDimitry Andric swap(*__x4, *__x5); 3908*0b57cec5SDimitry Andric ++__r; 3909*0b57cec5SDimitry Andric if (__c(*__x4, *__x3)) 3910*0b57cec5SDimitry Andric { 3911*0b57cec5SDimitry Andric swap(*__x3, *__x4); 3912*0b57cec5SDimitry Andric ++__r; 3913*0b57cec5SDimitry Andric if (__c(*__x3, *__x2)) 3914*0b57cec5SDimitry Andric { 3915*0b57cec5SDimitry Andric swap(*__x2, *__x3); 3916*0b57cec5SDimitry Andric ++__r; 3917*0b57cec5SDimitry Andric if (__c(*__x2, *__x1)) 3918*0b57cec5SDimitry Andric { 3919*0b57cec5SDimitry Andric swap(*__x1, *__x2); 3920*0b57cec5SDimitry Andric ++__r; 3921*0b57cec5SDimitry Andric } 3922*0b57cec5SDimitry Andric } 3923*0b57cec5SDimitry Andric } 3924*0b57cec5SDimitry Andric } 3925*0b57cec5SDimitry Andric return __r; 3926*0b57cec5SDimitry Andric} 3927*0b57cec5SDimitry Andric 3928*0b57cec5SDimitry Andric// Assumes size > 0 3929e8d8bef9SDimitry Andrictemplate <class _Compare, class _BidirectionalIterator> 3930*0b57cec5SDimitry Andricvoid 3931e8d8bef9SDimitry Andric__selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 3932*0b57cec5SDimitry Andric{ 3933e8d8bef9SDimitry Andric _BidirectionalIterator __lm1 = __last; 3934*0b57cec5SDimitry Andric for (--__lm1; __first != __lm1; ++__first) 3935*0b57cec5SDimitry Andric { 3936e8d8bef9SDimitry Andric _BidirectionalIterator __i = _VSTD::min_element<_BidirectionalIterator, 3937*0b57cec5SDimitry Andric typename add_lvalue_reference<_Compare>::type> 3938*0b57cec5SDimitry Andric (__first, __last, __comp); 3939*0b57cec5SDimitry Andric if (__i != __first) 3940*0b57cec5SDimitry Andric swap(*__first, *__i); 3941*0b57cec5SDimitry Andric } 3942*0b57cec5SDimitry Andric} 3943*0b57cec5SDimitry Andric 3944e8d8bef9SDimitry Andrictemplate <class _Compare, class _BidirectionalIterator> 3945*0b57cec5SDimitry Andricvoid 3946e8d8bef9SDimitry Andric__insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 3947*0b57cec5SDimitry Andric{ 3948e8d8bef9SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 3949*0b57cec5SDimitry Andric if (__first != __last) 3950*0b57cec5SDimitry Andric { 3951e8d8bef9SDimitry Andric _BidirectionalIterator __i = __first; 3952*0b57cec5SDimitry Andric for (++__i; __i != __last; ++__i) 3953*0b57cec5SDimitry Andric { 3954e8d8bef9SDimitry Andric _BidirectionalIterator __j = __i; 3955*0b57cec5SDimitry Andric value_type __t(_VSTD::move(*__j)); 3956e8d8bef9SDimitry Andric for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j) 3957*0b57cec5SDimitry Andric *__j = _VSTD::move(*__k); 3958*0b57cec5SDimitry Andric *__j = _VSTD::move(__t); 3959*0b57cec5SDimitry Andric } 3960*0b57cec5SDimitry Andric } 3961*0b57cec5SDimitry Andric} 3962*0b57cec5SDimitry Andric 3963*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 3964*0b57cec5SDimitry Andricvoid 3965*0b57cec5SDimitry Andric__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 3966*0b57cec5SDimitry Andric{ 3967*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 3968*0b57cec5SDimitry Andric _RandomAccessIterator __j = __first+2; 3969e8d8bef9SDimitry Andric _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp); 3970*0b57cec5SDimitry Andric for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) 3971*0b57cec5SDimitry Andric { 3972*0b57cec5SDimitry Andric if (__comp(*__i, *__j)) 3973*0b57cec5SDimitry Andric { 3974*0b57cec5SDimitry Andric value_type __t(_VSTD::move(*__i)); 3975*0b57cec5SDimitry Andric _RandomAccessIterator __k = __j; 3976*0b57cec5SDimitry Andric __j = __i; 3977*0b57cec5SDimitry Andric do 3978*0b57cec5SDimitry Andric { 3979*0b57cec5SDimitry Andric *__j = _VSTD::move(*__k); 3980*0b57cec5SDimitry Andric __j = __k; 3981*0b57cec5SDimitry Andric } while (__j != __first && __comp(__t, *--__k)); 3982*0b57cec5SDimitry Andric *__j = _VSTD::move(__t); 3983*0b57cec5SDimitry Andric } 3984*0b57cec5SDimitry Andric __j = __i; 3985*0b57cec5SDimitry Andric } 3986*0b57cec5SDimitry Andric} 3987*0b57cec5SDimitry Andric 3988*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 3989*0b57cec5SDimitry Andricbool 3990*0b57cec5SDimitry Andric__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 3991*0b57cec5SDimitry Andric{ 3992*0b57cec5SDimitry Andric switch (__last - __first) 3993*0b57cec5SDimitry Andric { 3994*0b57cec5SDimitry Andric case 0: 3995*0b57cec5SDimitry Andric case 1: 3996*0b57cec5SDimitry Andric return true; 3997*0b57cec5SDimitry Andric case 2: 3998*0b57cec5SDimitry Andric if (__comp(*--__last, *__first)) 3999*0b57cec5SDimitry Andric swap(*__first, *__last); 4000*0b57cec5SDimitry Andric return true; 4001*0b57cec5SDimitry Andric case 3: 4002*0b57cec5SDimitry Andric _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); 4003*0b57cec5SDimitry Andric return true; 4004*0b57cec5SDimitry Andric case 4: 4005*0b57cec5SDimitry Andric _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); 4006*0b57cec5SDimitry Andric return true; 4007*0b57cec5SDimitry Andric case 5: 4008*0b57cec5SDimitry Andric _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); 4009*0b57cec5SDimitry Andric return true; 4010*0b57cec5SDimitry Andric } 4011*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 4012*0b57cec5SDimitry Andric _RandomAccessIterator __j = __first+2; 4013e8d8bef9SDimitry Andric _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp); 4014*0b57cec5SDimitry Andric const unsigned __limit = 8; 4015*0b57cec5SDimitry Andric unsigned __count = 0; 4016*0b57cec5SDimitry Andric for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) 4017*0b57cec5SDimitry Andric { 4018*0b57cec5SDimitry Andric if (__comp(*__i, *__j)) 4019*0b57cec5SDimitry Andric { 4020*0b57cec5SDimitry Andric value_type __t(_VSTD::move(*__i)); 4021*0b57cec5SDimitry Andric _RandomAccessIterator __k = __j; 4022*0b57cec5SDimitry Andric __j = __i; 4023*0b57cec5SDimitry Andric do 4024*0b57cec5SDimitry Andric { 4025*0b57cec5SDimitry Andric *__j = _VSTD::move(*__k); 4026*0b57cec5SDimitry Andric __j = __k; 4027*0b57cec5SDimitry Andric } while (__j != __first && __comp(__t, *--__k)); 4028*0b57cec5SDimitry Andric *__j = _VSTD::move(__t); 4029*0b57cec5SDimitry Andric if (++__count == __limit) 4030*0b57cec5SDimitry Andric return ++__i == __last; 4031*0b57cec5SDimitry Andric } 4032*0b57cec5SDimitry Andric __j = __i; 4033*0b57cec5SDimitry Andric } 4034*0b57cec5SDimitry Andric return true; 4035*0b57cec5SDimitry Andric} 4036*0b57cec5SDimitry Andric 4037e8d8bef9SDimitry Andrictemplate <class _Compare, class _BidirectionalIterator> 4038*0b57cec5SDimitry Andricvoid 4039e8d8bef9SDimitry Andric__insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1, 4040e8d8bef9SDimitry Andric typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) 4041*0b57cec5SDimitry Andric{ 4042e8d8bef9SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 4043*0b57cec5SDimitry Andric if (__first1 != __last1) 4044*0b57cec5SDimitry Andric { 4045*0b57cec5SDimitry Andric __destruct_n __d(0); 4046*0b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h(__first2, __d); 4047*0b57cec5SDimitry Andric value_type* __last2 = __first2; 4048e8d8bef9SDimitry Andric ::new ((void*)__last2) value_type(_VSTD::move(*__first1)); 4049e8d8bef9SDimitry Andric __d.template __incr<value_type>(); 4050*0b57cec5SDimitry Andric for (++__last2; ++__first1 != __last1; ++__last2) 4051*0b57cec5SDimitry Andric { 4052*0b57cec5SDimitry Andric value_type* __j2 = __last2; 4053*0b57cec5SDimitry Andric value_type* __i2 = __j2; 4054*0b57cec5SDimitry Andric if (__comp(*__first1, *--__i2)) 4055*0b57cec5SDimitry Andric { 4056e8d8bef9SDimitry Andric ::new ((void*)__j2) value_type(_VSTD::move(*__i2)); 4057e8d8bef9SDimitry Andric __d.template __incr<value_type>(); 4058*0b57cec5SDimitry Andric for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2) 4059*0b57cec5SDimitry Andric *__j2 = _VSTD::move(*__i2); 4060*0b57cec5SDimitry Andric *__j2 = _VSTD::move(*__first1); 4061*0b57cec5SDimitry Andric } 4062*0b57cec5SDimitry Andric else 4063*0b57cec5SDimitry Andric { 4064e8d8bef9SDimitry Andric ::new ((void*)__j2) value_type(_VSTD::move(*__first1)); 4065e8d8bef9SDimitry Andric __d.template __incr<value_type>(); 4066*0b57cec5SDimitry Andric } 4067*0b57cec5SDimitry Andric } 4068*0b57cec5SDimitry Andric __h.release(); 4069*0b57cec5SDimitry Andric } 4070*0b57cec5SDimitry Andric} 4071*0b57cec5SDimitry Andric 4072*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 4073*0b57cec5SDimitry Andricvoid 4074*0b57cec5SDimitry Andric__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 4075*0b57cec5SDimitry Andric{ 4076*0b57cec5SDimitry Andric // _Compare is known to be a reference type 4077*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 4078*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 4079*0b57cec5SDimitry Andric const difference_type __limit = is_trivially_copy_constructible<value_type>::value && 4080*0b57cec5SDimitry Andric is_trivially_copy_assignable<value_type>::value ? 30 : 6; 4081*0b57cec5SDimitry Andric while (true) 4082*0b57cec5SDimitry Andric { 4083*0b57cec5SDimitry Andric __restart: 4084*0b57cec5SDimitry Andric difference_type __len = __last - __first; 4085*0b57cec5SDimitry Andric switch (__len) 4086*0b57cec5SDimitry Andric { 4087*0b57cec5SDimitry Andric case 0: 4088*0b57cec5SDimitry Andric case 1: 4089*0b57cec5SDimitry Andric return; 4090*0b57cec5SDimitry Andric case 2: 4091*0b57cec5SDimitry Andric if (__comp(*--__last, *__first)) 4092*0b57cec5SDimitry Andric swap(*__first, *__last); 4093*0b57cec5SDimitry Andric return; 4094*0b57cec5SDimitry Andric case 3: 4095*0b57cec5SDimitry Andric _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); 4096*0b57cec5SDimitry Andric return; 4097*0b57cec5SDimitry Andric case 4: 4098*0b57cec5SDimitry Andric _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); 4099*0b57cec5SDimitry Andric return; 4100*0b57cec5SDimitry Andric case 5: 4101*0b57cec5SDimitry Andric _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); 4102*0b57cec5SDimitry Andric return; 4103*0b57cec5SDimitry Andric } 4104*0b57cec5SDimitry Andric if (__len <= __limit) 4105*0b57cec5SDimitry Andric { 4106*0b57cec5SDimitry Andric _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp); 4107*0b57cec5SDimitry Andric return; 4108*0b57cec5SDimitry Andric } 4109*0b57cec5SDimitry Andric // __len > 5 4110*0b57cec5SDimitry Andric _RandomAccessIterator __m = __first; 4111*0b57cec5SDimitry Andric _RandomAccessIterator __lm1 = __last; 4112*0b57cec5SDimitry Andric --__lm1; 4113*0b57cec5SDimitry Andric unsigned __n_swaps; 4114*0b57cec5SDimitry Andric { 4115*0b57cec5SDimitry Andric difference_type __delta; 4116*0b57cec5SDimitry Andric if (__len >= 1000) 4117*0b57cec5SDimitry Andric { 4118*0b57cec5SDimitry Andric __delta = __len/2; 4119*0b57cec5SDimitry Andric __m += __delta; 4120*0b57cec5SDimitry Andric __delta /= 2; 4121*0b57cec5SDimitry Andric __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp); 4122*0b57cec5SDimitry Andric } 4123*0b57cec5SDimitry Andric else 4124*0b57cec5SDimitry Andric { 4125*0b57cec5SDimitry Andric __delta = __len/2; 4126*0b57cec5SDimitry Andric __m += __delta; 4127*0b57cec5SDimitry Andric __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp); 4128*0b57cec5SDimitry Andric } 4129*0b57cec5SDimitry Andric } 4130*0b57cec5SDimitry Andric // *__m is median 4131*0b57cec5SDimitry Andric // partition [__first, __m) < *__m and *__m <= [__m, __last) 4132*0b57cec5SDimitry Andric // (this inhibits tossing elements equivalent to __m around unnecessarily) 4133*0b57cec5SDimitry Andric _RandomAccessIterator __i = __first; 4134*0b57cec5SDimitry Andric _RandomAccessIterator __j = __lm1; 4135*0b57cec5SDimitry Andric // j points beyond range to be tested, *__m is known to be <= *__lm1 4136*0b57cec5SDimitry Andric // The search going up is known to be guarded but the search coming down isn't. 4137*0b57cec5SDimitry Andric // Prime the downward search with a guard. 4138*0b57cec5SDimitry Andric if (!__comp(*__i, *__m)) // if *__first == *__m 4139*0b57cec5SDimitry Andric { 4140*0b57cec5SDimitry Andric // *__first == *__m, *__first doesn't go in first part 4141*0b57cec5SDimitry Andric // manually guard downward moving __j against __i 4142*0b57cec5SDimitry Andric while (true) 4143*0b57cec5SDimitry Andric { 4144*0b57cec5SDimitry Andric if (__i == --__j) 4145*0b57cec5SDimitry Andric { 4146*0b57cec5SDimitry Andric // *__first == *__m, *__m <= all other elements 4147*0b57cec5SDimitry Andric // Parition instead into [__first, __i) == *__first and *__first < [__i, __last) 4148*0b57cec5SDimitry Andric ++__i; // __first + 1 4149*0b57cec5SDimitry Andric __j = __last; 4150*0b57cec5SDimitry Andric if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1) 4151*0b57cec5SDimitry Andric { 4152*0b57cec5SDimitry Andric while (true) 4153*0b57cec5SDimitry Andric { 4154*0b57cec5SDimitry Andric if (__i == __j) 4155*0b57cec5SDimitry Andric return; // [__first, __last) all equivalent elements 4156*0b57cec5SDimitry Andric if (__comp(*__first, *__i)) 4157*0b57cec5SDimitry Andric { 4158*0b57cec5SDimitry Andric swap(*__i, *__j); 4159*0b57cec5SDimitry Andric ++__n_swaps; 4160*0b57cec5SDimitry Andric ++__i; 4161*0b57cec5SDimitry Andric break; 4162*0b57cec5SDimitry Andric } 4163*0b57cec5SDimitry Andric ++__i; 4164*0b57cec5SDimitry Andric } 4165*0b57cec5SDimitry Andric } 4166*0b57cec5SDimitry Andric // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 4167*0b57cec5SDimitry Andric if (__i == __j) 4168*0b57cec5SDimitry Andric return; 4169*0b57cec5SDimitry Andric while (true) 4170*0b57cec5SDimitry Andric { 4171*0b57cec5SDimitry Andric while (!__comp(*__first, *__i)) 4172*0b57cec5SDimitry Andric ++__i; 4173*0b57cec5SDimitry Andric while (__comp(*__first, *--__j)) 4174*0b57cec5SDimitry Andric ; 4175*0b57cec5SDimitry Andric if (__i >= __j) 4176*0b57cec5SDimitry Andric break; 4177*0b57cec5SDimitry Andric swap(*__i, *__j); 4178*0b57cec5SDimitry Andric ++__n_swaps; 4179*0b57cec5SDimitry Andric ++__i; 4180*0b57cec5SDimitry Andric } 4181*0b57cec5SDimitry Andric // [__first, __i) == *__first and *__first < [__i, __last) 4182e8d8bef9SDimitry Andric // The first part is sorted, sort the second part 4183*0b57cec5SDimitry Andric // _VSTD::__sort<_Compare>(__i, __last, __comp); 4184*0b57cec5SDimitry Andric __first = __i; 4185*0b57cec5SDimitry Andric goto __restart; 4186*0b57cec5SDimitry Andric } 4187*0b57cec5SDimitry Andric if (__comp(*__j, *__m)) 4188*0b57cec5SDimitry Andric { 4189*0b57cec5SDimitry Andric swap(*__i, *__j); 4190*0b57cec5SDimitry Andric ++__n_swaps; 4191*0b57cec5SDimitry Andric break; // found guard for downward moving __j, now use unguarded partition 4192*0b57cec5SDimitry Andric } 4193*0b57cec5SDimitry Andric } 4194*0b57cec5SDimitry Andric } 4195*0b57cec5SDimitry Andric // It is known that *__i < *__m 4196*0b57cec5SDimitry Andric ++__i; 4197*0b57cec5SDimitry Andric // j points beyond range to be tested, *__m is known to be <= *__lm1 4198*0b57cec5SDimitry Andric // if not yet partitioned... 4199*0b57cec5SDimitry Andric if (__i < __j) 4200*0b57cec5SDimitry Andric { 4201*0b57cec5SDimitry Andric // known that *(__i - 1) < *__m 4202*0b57cec5SDimitry Andric // known that __i <= __m 4203*0b57cec5SDimitry Andric while (true) 4204*0b57cec5SDimitry Andric { 4205*0b57cec5SDimitry Andric // __m still guards upward moving __i 4206*0b57cec5SDimitry Andric while (__comp(*__i, *__m)) 4207*0b57cec5SDimitry Andric ++__i; 4208*0b57cec5SDimitry Andric // It is now known that a guard exists for downward moving __j 4209*0b57cec5SDimitry Andric while (!__comp(*--__j, *__m)) 4210*0b57cec5SDimitry Andric ; 4211*0b57cec5SDimitry Andric if (__i > __j) 4212*0b57cec5SDimitry Andric break; 4213*0b57cec5SDimitry Andric swap(*__i, *__j); 4214*0b57cec5SDimitry Andric ++__n_swaps; 4215*0b57cec5SDimitry Andric // It is known that __m != __j 4216*0b57cec5SDimitry Andric // If __m just moved, follow it 4217*0b57cec5SDimitry Andric if (__m == __i) 4218*0b57cec5SDimitry Andric __m = __j; 4219*0b57cec5SDimitry Andric ++__i; 4220*0b57cec5SDimitry Andric } 4221*0b57cec5SDimitry Andric } 4222*0b57cec5SDimitry Andric // [__first, __i) < *__m and *__m <= [__i, __last) 4223*0b57cec5SDimitry Andric if (__i != __m && __comp(*__m, *__i)) 4224*0b57cec5SDimitry Andric { 4225*0b57cec5SDimitry Andric swap(*__i, *__m); 4226*0b57cec5SDimitry Andric ++__n_swaps; 4227*0b57cec5SDimitry Andric } 4228*0b57cec5SDimitry Andric // [__first, __i) < *__i and *__i <= [__i+1, __last) 4229*0b57cec5SDimitry Andric // If we were given a perfect partition, see if insertion sort is quick... 4230*0b57cec5SDimitry Andric if (__n_swaps == 0) 4231*0b57cec5SDimitry Andric { 4232*0b57cec5SDimitry Andric bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp); 4233*0b57cec5SDimitry Andric if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp)) 4234*0b57cec5SDimitry Andric { 4235*0b57cec5SDimitry Andric if (__fs) 4236*0b57cec5SDimitry Andric return; 4237*0b57cec5SDimitry Andric __last = __i; 4238*0b57cec5SDimitry Andric continue; 4239*0b57cec5SDimitry Andric } 4240*0b57cec5SDimitry Andric else 4241*0b57cec5SDimitry Andric { 4242*0b57cec5SDimitry Andric if (__fs) 4243*0b57cec5SDimitry Andric { 4244*0b57cec5SDimitry Andric __first = ++__i; 4245*0b57cec5SDimitry Andric continue; 4246*0b57cec5SDimitry Andric } 4247*0b57cec5SDimitry Andric } 4248*0b57cec5SDimitry Andric } 4249*0b57cec5SDimitry Andric // sort smaller range with recursive call and larger with tail recursion elimination 4250*0b57cec5SDimitry Andric if (__i - __first < __last - __i) 4251*0b57cec5SDimitry Andric { 4252*0b57cec5SDimitry Andric _VSTD::__sort<_Compare>(__first, __i, __comp); 4253*0b57cec5SDimitry Andric // _VSTD::__sort<_Compare>(__i+1, __last, __comp); 4254*0b57cec5SDimitry Andric __first = ++__i; 4255*0b57cec5SDimitry Andric } 4256*0b57cec5SDimitry Andric else 4257*0b57cec5SDimitry Andric { 4258*0b57cec5SDimitry Andric _VSTD::__sort<_Compare>(__i+1, __last, __comp); 4259*0b57cec5SDimitry Andric // _VSTD::__sort<_Compare>(__first, __i, __comp); 4260*0b57cec5SDimitry Andric __last = __i; 4261*0b57cec5SDimitry Andric } 4262*0b57cec5SDimitry Andric } 4263*0b57cec5SDimitry Andric} 4264*0b57cec5SDimitry Andric 4265*0b57cec5SDimitry Andric// This forwarder keeps the top call and the recursive calls using the same instantiation, forcing a reference _Compare 4266*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 4267*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 4268*0b57cec5SDimitry Andricvoid 4269*0b57cec5SDimitry Andricsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 4270*0b57cec5SDimitry Andric{ 4271*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 4272*0b57cec5SDimitry Andric _VSTD::__sort<_Comp_ref>(__first, __last, _Comp_ref(__comp)); 4273*0b57cec5SDimitry Andric} 4274*0b57cec5SDimitry Andric 4275*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 4276*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 4277*0b57cec5SDimitry Andricvoid 4278*0b57cec5SDimitry Andricsort(_RandomAccessIterator __first, _RandomAccessIterator __last) 4279*0b57cec5SDimitry Andric{ 4280*0b57cec5SDimitry Andric _VSTD::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 4281*0b57cec5SDimitry Andric} 4282*0b57cec5SDimitry Andric 4283*0b57cec5SDimitry Andrictemplate <class _Tp> 4284*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 4285*0b57cec5SDimitry Andricvoid 4286*0b57cec5SDimitry Andricsort(_Tp** __first, _Tp** __last) 4287*0b57cec5SDimitry Andric{ 4288e8d8bef9SDimitry Andric _VSTD::sort((uintptr_t*)__first, (uintptr_t*)__last, __less<uintptr_t>()); 4289*0b57cec5SDimitry Andric} 4290*0b57cec5SDimitry Andric 4291*0b57cec5SDimitry Andrictemplate <class _Tp> 4292*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 4293*0b57cec5SDimitry Andricvoid 4294*0b57cec5SDimitry Andricsort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last) 4295*0b57cec5SDimitry Andric{ 4296*0b57cec5SDimitry Andric _VSTD::sort(__first.base(), __last.base()); 4297*0b57cec5SDimitry Andric} 4298*0b57cec5SDimitry Andric 4299*0b57cec5SDimitry Andrictemplate <class _Tp, class _Compare> 4300*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 4301*0b57cec5SDimitry Andricvoid 4302*0b57cec5SDimitry Andricsort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last, _Compare __comp) 4303*0b57cec5SDimitry Andric{ 4304*0b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 4305*0b57cec5SDimitry Andric _VSTD::sort<_Tp*, _Comp_ref>(__first.base(), __last.base(), __comp); 4306*0b57cec5SDimitry Andric} 4307*0b57cec5SDimitry Andric 4308*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&)) 4309*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&)) 4310*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&)) 4311*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&)) 4312*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&)) 4313*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&)) 4314*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&)) 4315*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&)) 4316*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&)) 4317*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&)) 4318*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&)) 4319*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&)) 4320*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&)) 4321*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&)) 4322*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&)) 4323*0b57cec5SDimitry Andric 4324*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&)) 4325*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&)) 4326*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&)) 4327*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&)) 4328*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&)) 4329*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&)) 4330*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&)) 4331*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&)) 4332*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&)) 4333*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&)) 4334*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&)) 4335*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&)) 4336*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&)) 4337*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&)) 4338*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&)) 4339*0b57cec5SDimitry Andric 4340*0b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&)) 4341*0b57cec5SDimitry Andric 4342*0b57cec5SDimitry Andric// lower_bound 4343*0b57cec5SDimitry Andric 4344*0b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator, class _Tp> 4345*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 4346*0b57cec5SDimitry Andric__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 4347*0b57cec5SDimitry Andric{ 4348*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 4349*0b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last); 4350*0b57cec5SDimitry Andric while (__len != 0) 4351*0b57cec5SDimitry Andric { 4352*0b57cec5SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 4353*0b57cec5SDimitry Andric _ForwardIterator __m = __first; 4354*0b57cec5SDimitry Andric _VSTD::advance(__m, __l2); 4355*0b57cec5SDimitry Andric if (__comp(*__m, __value_)) 4356*0b57cec5SDimitry Andric { 4357*0b57cec5SDimitry Andric __first = ++__m; 4358*0b57cec5SDimitry Andric __len -= __l2 + 1; 4359*0b57cec5SDimitry Andric } 4360*0b57cec5SDimitry Andric else 4361*0b57cec5SDimitry Andric __len = __l2; 4362*0b57cec5SDimitry Andric } 4363*0b57cec5SDimitry Andric return __first; 4364*0b57cec5SDimitry Andric} 4365*0b57cec5SDimitry Andric 4366*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp, class _Compare> 4367*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 4368*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4369*0b57cec5SDimitry Andric_ForwardIterator 4370*0b57cec5SDimitry Andriclower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 4371*0b57cec5SDimitry Andric{ 4372*0b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 4373e8d8bef9SDimitry Andric return _VSTD::__lower_bound<_Comp_ref>(__first, __last, __value_, __comp); 4374*0b57cec5SDimitry Andric} 4375*0b57cec5SDimitry Andric 4376*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 4377*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 4378*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4379*0b57cec5SDimitry Andric_ForwardIterator 4380*0b57cec5SDimitry Andriclower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 4381*0b57cec5SDimitry Andric{ 4382*0b57cec5SDimitry Andric return _VSTD::lower_bound(__first, __last, __value_, 4383*0b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); 4384*0b57cec5SDimitry Andric} 4385*0b57cec5SDimitry Andric 4386*0b57cec5SDimitry Andric// upper_bound 4387*0b57cec5SDimitry Andric 4388*0b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator, class _Tp> 4389*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 4390*0b57cec5SDimitry Andric__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 4391*0b57cec5SDimitry Andric{ 4392*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 4393*0b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last); 4394*0b57cec5SDimitry Andric while (__len != 0) 4395*0b57cec5SDimitry Andric { 4396*0b57cec5SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 4397*0b57cec5SDimitry Andric _ForwardIterator __m = __first; 4398*0b57cec5SDimitry Andric _VSTD::advance(__m, __l2); 4399*0b57cec5SDimitry Andric if (__comp(__value_, *__m)) 4400*0b57cec5SDimitry Andric __len = __l2; 4401*0b57cec5SDimitry Andric else 4402*0b57cec5SDimitry Andric { 4403*0b57cec5SDimitry Andric __first = ++__m; 4404*0b57cec5SDimitry Andric __len -= __l2 + 1; 4405*0b57cec5SDimitry Andric } 4406*0b57cec5SDimitry Andric } 4407*0b57cec5SDimitry Andric return __first; 4408*0b57cec5SDimitry Andric} 4409*0b57cec5SDimitry Andric 4410*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp, class _Compare> 4411*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 4412*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4413*0b57cec5SDimitry Andric_ForwardIterator 4414*0b57cec5SDimitry Andricupper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 4415*0b57cec5SDimitry Andric{ 4416*0b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 4417e8d8bef9SDimitry Andric return _VSTD::__upper_bound<_Comp_ref>(__first, __last, __value_, __comp); 4418*0b57cec5SDimitry Andric} 4419*0b57cec5SDimitry Andric 4420*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 4421*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 4422*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4423*0b57cec5SDimitry Andric_ForwardIterator 4424*0b57cec5SDimitry Andricupper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 4425*0b57cec5SDimitry Andric{ 4426*0b57cec5SDimitry Andric return _VSTD::upper_bound(__first, __last, __value_, 4427*0b57cec5SDimitry Andric __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); 4428*0b57cec5SDimitry Andric} 4429*0b57cec5SDimitry Andric 4430*0b57cec5SDimitry Andric// equal_range 4431*0b57cec5SDimitry Andric 4432*0b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator, class _Tp> 4433*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> 4434*0b57cec5SDimitry Andric__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 4435*0b57cec5SDimitry Andric{ 4436*0b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 4437*0b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last); 4438*0b57cec5SDimitry Andric while (__len != 0) 4439*0b57cec5SDimitry Andric { 4440*0b57cec5SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 4441*0b57cec5SDimitry Andric _ForwardIterator __m = __first; 4442*0b57cec5SDimitry Andric _VSTD::advance(__m, __l2); 4443*0b57cec5SDimitry Andric if (__comp(*__m, __value_)) 4444*0b57cec5SDimitry Andric { 4445*0b57cec5SDimitry Andric __first = ++__m; 4446*0b57cec5SDimitry Andric __len -= __l2 + 1; 4447*0b57cec5SDimitry Andric } 4448*0b57cec5SDimitry Andric else if (__comp(__value_, *__m)) 4449*0b57cec5SDimitry Andric { 4450*0b57cec5SDimitry Andric __last = __m; 4451*0b57cec5SDimitry Andric __len = __l2; 4452*0b57cec5SDimitry Andric } 4453*0b57cec5SDimitry Andric else 4454*0b57cec5SDimitry Andric { 4455*0b57cec5SDimitry Andric _ForwardIterator __mp1 = __m; 4456*0b57cec5SDimitry Andric return pair<_ForwardIterator, _ForwardIterator> 4457*0b57cec5SDimitry Andric ( 4458e8d8bef9SDimitry Andric _VSTD::__lower_bound<_Compare>(__first, __m, __value_, __comp), 4459e8d8bef9SDimitry Andric _VSTD::__upper_bound<_Compare>(++__mp1, __last, __value_, __comp) 4460*0b57cec5SDimitry Andric ); 4461*0b57cec5SDimitry Andric } 4462*0b57cec5SDimitry Andric } 4463*0b57cec5SDimitry Andric return pair<_ForwardIterator, _ForwardIterator>(__first, __first); 4464*0b57cec5SDimitry Andric} 4465*0b57cec5SDimitry Andric 4466*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp, class _Compare> 4467*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 4468*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4469*0b57cec5SDimitry Andricpair<_ForwardIterator, _ForwardIterator> 4470*0b57cec5SDimitry Andricequal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 4471*0b57cec5SDimitry Andric{ 4472*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 4473e8d8bef9SDimitry Andric return _VSTD::__equal_range<_Comp_ref>(__first, __last, __value_, __comp); 4474*0b57cec5SDimitry Andric} 4475*0b57cec5SDimitry Andric 4476*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 4477*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 4478*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4479*0b57cec5SDimitry Andricpair<_ForwardIterator, _ForwardIterator> 4480*0b57cec5SDimitry Andricequal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 4481*0b57cec5SDimitry Andric{ 4482*0b57cec5SDimitry Andric return _VSTD::equal_range(__first, __last, __value_, 4483*0b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); 4484*0b57cec5SDimitry Andric} 4485*0b57cec5SDimitry Andric 4486*0b57cec5SDimitry Andric// binary_search 4487*0b57cec5SDimitry Andric 4488*0b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator, class _Tp> 4489*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4490*0b57cec5SDimitry Andricbool 4491*0b57cec5SDimitry Andric__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 4492*0b57cec5SDimitry Andric{ 4493e8d8bef9SDimitry Andric __first = _VSTD::__lower_bound<_Compare>(__first, __last, __value_, __comp); 4494*0b57cec5SDimitry Andric return __first != __last && !__comp(__value_, *__first); 4495*0b57cec5SDimitry Andric} 4496*0b57cec5SDimitry Andric 4497*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp, class _Compare> 4498*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 4499*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4500*0b57cec5SDimitry Andricbool 4501*0b57cec5SDimitry Andricbinary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 4502*0b57cec5SDimitry Andric{ 4503*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 4504e8d8bef9SDimitry Andric return _VSTD::__binary_search<_Comp_ref>(__first, __last, __value_, __comp); 4505*0b57cec5SDimitry Andric} 4506*0b57cec5SDimitry Andric 4507*0b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 4508*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 4509*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4510*0b57cec5SDimitry Andricbool 4511*0b57cec5SDimitry Andricbinary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 4512*0b57cec5SDimitry Andric{ 4513*0b57cec5SDimitry Andric return _VSTD::binary_search(__first, __last, __value_, 4514*0b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); 4515*0b57cec5SDimitry Andric} 4516*0b57cec5SDimitry Andric 4517*0b57cec5SDimitry Andric// merge 4518*0b57cec5SDimitry Andric 4519*0b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 4520e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 4521*0b57cec5SDimitry Andric_OutputIterator 4522*0b57cec5SDimitry Andric__merge(_InputIterator1 __first1, _InputIterator1 __last1, 4523*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 4524*0b57cec5SDimitry Andric{ 4525*0b57cec5SDimitry Andric for (; __first1 != __last1; ++__result) 4526*0b57cec5SDimitry Andric { 4527*0b57cec5SDimitry Andric if (__first2 == __last2) 4528*0b57cec5SDimitry Andric return _VSTD::copy(__first1, __last1, __result); 4529*0b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 4530*0b57cec5SDimitry Andric { 4531*0b57cec5SDimitry Andric *__result = *__first2; 4532*0b57cec5SDimitry Andric ++__first2; 4533*0b57cec5SDimitry Andric } 4534*0b57cec5SDimitry Andric else 4535*0b57cec5SDimitry Andric { 4536*0b57cec5SDimitry Andric *__result = *__first1; 4537*0b57cec5SDimitry Andric ++__first1; 4538*0b57cec5SDimitry Andric } 4539*0b57cec5SDimitry Andric } 4540*0b57cec5SDimitry Andric return _VSTD::copy(__first2, __last2, __result); 4541*0b57cec5SDimitry Andric} 4542*0b57cec5SDimitry Andric 4543*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 4544e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4545*0b57cec5SDimitry Andric_OutputIterator 4546*0b57cec5SDimitry Andricmerge(_InputIterator1 __first1, _InputIterator1 __last1, 4547*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 4548*0b57cec5SDimitry Andric{ 4549*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 4550*0b57cec5SDimitry Andric return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 4551*0b57cec5SDimitry Andric} 4552*0b57cec5SDimitry Andric 4553*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 4554e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4555*0b57cec5SDimitry Andric_OutputIterator 4556*0b57cec5SDimitry Andricmerge(_InputIterator1 __first1, _InputIterator1 __last1, 4557*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 4558*0b57cec5SDimitry Andric{ 4559*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type __v1; 4560*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator2>::value_type __v2; 4561e40139ffSDimitry Andric return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>()); 4562*0b57cec5SDimitry Andric} 4563*0b57cec5SDimitry Andric 4564*0b57cec5SDimitry Andric// inplace_merge 4565*0b57cec5SDimitry Andric 4566*0b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, 4567*0b57cec5SDimitry Andric class _OutputIterator> 4568*0b57cec5SDimitry Andricvoid __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1, 4569*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, 4570*0b57cec5SDimitry Andric _OutputIterator __result, _Compare __comp) 4571*0b57cec5SDimitry Andric{ 4572*0b57cec5SDimitry Andric for (; __first1 != __last1; ++__result) 4573*0b57cec5SDimitry Andric { 4574*0b57cec5SDimitry Andric if (__first2 == __last2) 4575*0b57cec5SDimitry Andric { 4576*0b57cec5SDimitry Andric _VSTD::move(__first1, __last1, __result); 4577*0b57cec5SDimitry Andric return; 4578*0b57cec5SDimitry Andric } 4579*0b57cec5SDimitry Andric 4580*0b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 4581*0b57cec5SDimitry Andric { 4582*0b57cec5SDimitry Andric *__result = _VSTD::move(*__first2); 4583*0b57cec5SDimitry Andric ++__first2; 4584*0b57cec5SDimitry Andric } 4585*0b57cec5SDimitry Andric else 4586*0b57cec5SDimitry Andric { 4587*0b57cec5SDimitry Andric *__result = _VSTD::move(*__first1); 4588*0b57cec5SDimitry Andric ++__first1; 4589*0b57cec5SDimitry Andric } 4590*0b57cec5SDimitry Andric } 4591*0b57cec5SDimitry Andric // __first2 through __last2 are already in the right spot. 4592*0b57cec5SDimitry Andric} 4593*0b57cec5SDimitry Andric 4594*0b57cec5SDimitry Andrictemplate <class _Compare, class _BidirectionalIterator> 4595*0b57cec5SDimitry Andricvoid 4596*0b57cec5SDimitry Andric__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 4597*0b57cec5SDimitry Andric _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, 4598*0b57cec5SDimitry Andric typename iterator_traits<_BidirectionalIterator>::difference_type __len2, 4599*0b57cec5SDimitry Andric typename iterator_traits<_BidirectionalIterator>::value_type* __buff) 4600*0b57cec5SDimitry Andric{ 4601*0b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 4602*0b57cec5SDimitry Andric __destruct_n __d(0); 4603*0b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h2(__buff, __d); 4604*0b57cec5SDimitry Andric if (__len1 <= __len2) 4605*0b57cec5SDimitry Andric { 4606*0b57cec5SDimitry Andric value_type* __p = __buff; 4607e8d8bef9SDimitry Andric for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p) 4608e8d8bef9SDimitry Andric ::new ((void*)__p) value_type(_VSTD::move(*__i)); 4609e8d8bef9SDimitry Andric _VSTD::__half_inplace_merge<_Compare>(__buff, __p, __middle, __last, __first, __comp); 4610*0b57cec5SDimitry Andric } 4611*0b57cec5SDimitry Andric else 4612*0b57cec5SDimitry Andric { 4613*0b57cec5SDimitry Andric value_type* __p = __buff; 4614e8d8bef9SDimitry Andric for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p) 4615e8d8bef9SDimitry Andric ::new ((void*)__p) value_type(_VSTD::move(*__i)); 4616*0b57cec5SDimitry Andric typedef reverse_iterator<_BidirectionalIterator> _RBi; 4617*0b57cec5SDimitry Andric typedef reverse_iterator<value_type*> _Rv; 4618e8d8bef9SDimitry Andric typedef __invert<_Compare> _Inverted; 4619e8d8bef9SDimitry Andric _VSTD::__half_inplace_merge<_Inverted>(_Rv(__p), _Rv(__buff), 4620*0b57cec5SDimitry Andric _RBi(__middle), _RBi(__first), 4621e8d8bef9SDimitry Andric _RBi(__last), _Inverted(__comp)); 4622*0b57cec5SDimitry Andric } 4623*0b57cec5SDimitry Andric} 4624*0b57cec5SDimitry Andric 4625*0b57cec5SDimitry Andrictemplate <class _Compare, class _BidirectionalIterator> 4626*0b57cec5SDimitry Andricvoid 4627*0b57cec5SDimitry Andric__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 4628*0b57cec5SDimitry Andric _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, 4629*0b57cec5SDimitry Andric typename iterator_traits<_BidirectionalIterator>::difference_type __len2, 4630*0b57cec5SDimitry Andric typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size) 4631*0b57cec5SDimitry Andric{ 4632*0b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; 4633*0b57cec5SDimitry Andric while (true) 4634*0b57cec5SDimitry Andric { 4635*0b57cec5SDimitry Andric // if __middle == __last, we're done 4636*0b57cec5SDimitry Andric if (__len2 == 0) 4637*0b57cec5SDimitry Andric return; 4638*0b57cec5SDimitry Andric if (__len1 <= __buff_size || __len2 <= __buff_size) 4639e8d8bef9SDimitry Andric return _VSTD::__buffered_inplace_merge<_Compare> 4640*0b57cec5SDimitry Andric (__first, __middle, __last, __comp, __len1, __len2, __buff); 4641*0b57cec5SDimitry Andric // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 4642*0b57cec5SDimitry Andric for (; true; ++__first, (void) --__len1) 4643*0b57cec5SDimitry Andric { 4644*0b57cec5SDimitry Andric if (__len1 == 0) 4645*0b57cec5SDimitry Andric return; 4646*0b57cec5SDimitry Andric if (__comp(*__middle, *__first)) 4647*0b57cec5SDimitry Andric break; 4648*0b57cec5SDimitry Andric } 4649*0b57cec5SDimitry Andric // __first < __middle < __last 4650*0b57cec5SDimitry Andric // *__first > *__middle 4651*0b57cec5SDimitry Andric // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that 4652*0b57cec5SDimitry Andric // all elements in: 4653*0b57cec5SDimitry Andric // [__first, __m1) <= [__middle, __m2) 4654*0b57cec5SDimitry Andric // [__middle, __m2) < [__m1, __middle) 4655*0b57cec5SDimitry Andric // [__m1, __middle) <= [__m2, __last) 4656*0b57cec5SDimitry Andric // and __m1 or __m2 is in the middle of its range 4657*0b57cec5SDimitry Andric _BidirectionalIterator __m1; // "median" of [__first, __middle) 4658*0b57cec5SDimitry Andric _BidirectionalIterator __m2; // "median" of [__middle, __last) 4659*0b57cec5SDimitry Andric difference_type __len11; // distance(__first, __m1) 4660*0b57cec5SDimitry Andric difference_type __len21; // distance(__middle, __m2) 4661*0b57cec5SDimitry Andric // binary search smaller range 4662*0b57cec5SDimitry Andric if (__len1 < __len2) 4663*0b57cec5SDimitry Andric { // __len >= 1, __len2 >= 2 4664*0b57cec5SDimitry Andric __len21 = __len2 / 2; 4665*0b57cec5SDimitry Andric __m2 = __middle; 4666*0b57cec5SDimitry Andric _VSTD::advance(__m2, __len21); 4667e8d8bef9SDimitry Andric __m1 = _VSTD::__upper_bound<_Compare>(__first, __middle, *__m2, __comp); 4668*0b57cec5SDimitry Andric __len11 = _VSTD::distance(__first, __m1); 4669*0b57cec5SDimitry Andric } 4670*0b57cec5SDimitry Andric else 4671*0b57cec5SDimitry Andric { 4672*0b57cec5SDimitry Andric if (__len1 == 1) 4673*0b57cec5SDimitry Andric { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 4674*0b57cec5SDimitry Andric // It is known *__first > *__middle 4675*0b57cec5SDimitry Andric swap(*__first, *__middle); 4676*0b57cec5SDimitry Andric return; 4677*0b57cec5SDimitry Andric } 4678*0b57cec5SDimitry Andric // __len1 >= 2, __len2 >= 1 4679*0b57cec5SDimitry Andric __len11 = __len1 / 2; 4680*0b57cec5SDimitry Andric __m1 = __first; 4681*0b57cec5SDimitry Andric _VSTD::advance(__m1, __len11); 4682e8d8bef9SDimitry Andric __m2 = _VSTD::__lower_bound<_Compare>(__middle, __last, *__m1, __comp); 4683*0b57cec5SDimitry Andric __len21 = _VSTD::distance(__middle, __m2); 4684*0b57cec5SDimitry Andric } 4685*0b57cec5SDimitry Andric difference_type __len12 = __len1 - __len11; // distance(__m1, __middle) 4686*0b57cec5SDimitry Andric difference_type __len22 = __len2 - __len21; // distance(__m2, __last) 4687*0b57cec5SDimitry Andric // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) 4688*0b57cec5SDimitry Andric // swap middle two partitions 4689*0b57cec5SDimitry Andric __middle = _VSTD::rotate(__m1, __middle, __m2); 4690*0b57cec5SDimitry Andric // __len12 and __len21 now have swapped meanings 4691e8d8bef9SDimitry Andric // merge smaller range with recursive call and larger with tail recursion elimination 4692*0b57cec5SDimitry Andric if (__len11 + __len21 < __len12 + __len22) 4693*0b57cec5SDimitry Andric { 4694e8d8bef9SDimitry Andric _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); 4695e8d8bef9SDimitry Andric// _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); 4696*0b57cec5SDimitry Andric __first = __middle; 4697*0b57cec5SDimitry Andric __middle = __m2; 4698*0b57cec5SDimitry Andric __len1 = __len12; 4699*0b57cec5SDimitry Andric __len2 = __len22; 4700*0b57cec5SDimitry Andric } 4701*0b57cec5SDimitry Andric else 4702*0b57cec5SDimitry Andric { 4703e8d8bef9SDimitry Andric _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); 4704e8d8bef9SDimitry Andric// _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); 4705*0b57cec5SDimitry Andric __last = __middle; 4706*0b57cec5SDimitry Andric __middle = __m1; 4707*0b57cec5SDimitry Andric __len1 = __len11; 4708*0b57cec5SDimitry Andric __len2 = __len21; 4709*0b57cec5SDimitry Andric } 4710*0b57cec5SDimitry Andric } 4711*0b57cec5SDimitry Andric} 4712*0b57cec5SDimitry Andric 4713*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator, class _Compare> 4714*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 4715*0b57cec5SDimitry Andricvoid 4716*0b57cec5SDimitry Andricinplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 4717*0b57cec5SDimitry Andric _Compare __comp) 4718*0b57cec5SDimitry Andric{ 4719*0b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 4720*0b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; 4721*0b57cec5SDimitry Andric difference_type __len1 = _VSTD::distance(__first, __middle); 4722*0b57cec5SDimitry Andric difference_type __len2 = _VSTD::distance(__middle, __last); 4723*0b57cec5SDimitry Andric difference_type __buf_size = _VSTD::min(__len1, __len2); 4724*0b57cec5SDimitry Andric pair<value_type*, ptrdiff_t> __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size); 4725*0b57cec5SDimitry Andric unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first); 4726*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 4727*0b57cec5SDimitry Andric return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2, 4728*0b57cec5SDimitry Andric __buf.first, __buf.second); 4729*0b57cec5SDimitry Andric} 4730*0b57cec5SDimitry Andric 4731*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 4732*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 4733*0b57cec5SDimitry Andricvoid 4734*0b57cec5SDimitry Andricinplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) 4735*0b57cec5SDimitry Andric{ 4736*0b57cec5SDimitry Andric _VSTD::inplace_merge(__first, __middle, __last, 4737*0b57cec5SDimitry Andric __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); 4738*0b57cec5SDimitry Andric} 4739*0b57cec5SDimitry Andric 4740*0b57cec5SDimitry Andric// stable_sort 4741*0b57cec5SDimitry Andric 4742*0b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2> 4743*0b57cec5SDimitry Andricvoid 4744*0b57cec5SDimitry Andric__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, 4745*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, 4746*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp) 4747*0b57cec5SDimitry Andric{ 4748*0b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type value_type; 4749*0b57cec5SDimitry Andric __destruct_n __d(0); 4750*0b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h(__result, __d); 4751*0b57cec5SDimitry Andric for (; true; ++__result) 4752*0b57cec5SDimitry Andric { 4753*0b57cec5SDimitry Andric if (__first1 == __last1) 4754*0b57cec5SDimitry Andric { 4755e8d8bef9SDimitry Andric for (; __first2 != __last2; ++__first2, ++__result, (void)__d.template __incr<value_type>()) 4756e8d8bef9SDimitry Andric ::new ((void*)__result) value_type(_VSTD::move(*__first2)); 4757*0b57cec5SDimitry Andric __h.release(); 4758*0b57cec5SDimitry Andric return; 4759*0b57cec5SDimitry Andric } 4760*0b57cec5SDimitry Andric if (__first2 == __last2) 4761*0b57cec5SDimitry Andric { 4762e8d8bef9SDimitry Andric for (; __first1 != __last1; ++__first1, ++__result, (void)__d.template __incr<value_type>()) 4763e8d8bef9SDimitry Andric ::new ((void*)__result) value_type(_VSTD::move(*__first1)); 4764*0b57cec5SDimitry Andric __h.release(); 4765*0b57cec5SDimitry Andric return; 4766*0b57cec5SDimitry Andric } 4767*0b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 4768*0b57cec5SDimitry Andric { 4769e8d8bef9SDimitry Andric ::new ((void*)__result) value_type(_VSTD::move(*__first2)); 4770e8d8bef9SDimitry Andric __d.template __incr<value_type>(); 4771*0b57cec5SDimitry Andric ++__first2; 4772*0b57cec5SDimitry Andric } 4773*0b57cec5SDimitry Andric else 4774*0b57cec5SDimitry Andric { 4775e8d8bef9SDimitry Andric ::new ((void*)__result) value_type(_VSTD::move(*__first1)); 4776e8d8bef9SDimitry Andric __d.template __incr<value_type>(); 4777*0b57cec5SDimitry Andric ++__first1; 4778*0b57cec5SDimitry Andric } 4779*0b57cec5SDimitry Andric } 4780*0b57cec5SDimitry Andric} 4781*0b57cec5SDimitry Andric 4782*0b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 4783*0b57cec5SDimitry Andricvoid 4784*0b57cec5SDimitry Andric__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, 4785*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, 4786*0b57cec5SDimitry Andric _OutputIterator __result, _Compare __comp) 4787*0b57cec5SDimitry Andric{ 4788*0b57cec5SDimitry Andric for (; __first1 != __last1; ++__result) 4789*0b57cec5SDimitry Andric { 4790*0b57cec5SDimitry Andric if (__first2 == __last2) 4791*0b57cec5SDimitry Andric { 4792e40139ffSDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__result) 4793*0b57cec5SDimitry Andric *__result = _VSTD::move(*__first1); 4794*0b57cec5SDimitry Andric return; 4795*0b57cec5SDimitry Andric } 4796*0b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 4797*0b57cec5SDimitry Andric { 4798*0b57cec5SDimitry Andric *__result = _VSTD::move(*__first2); 4799*0b57cec5SDimitry Andric ++__first2; 4800*0b57cec5SDimitry Andric } 4801*0b57cec5SDimitry Andric else 4802*0b57cec5SDimitry Andric { 4803*0b57cec5SDimitry Andric *__result = _VSTD::move(*__first1); 4804*0b57cec5SDimitry Andric ++__first1; 4805*0b57cec5SDimitry Andric } 4806*0b57cec5SDimitry Andric } 4807e40139ffSDimitry Andric for (; __first2 != __last2; ++__first2, (void) ++__result) 4808*0b57cec5SDimitry Andric *__result = _VSTD::move(*__first2); 4809*0b57cec5SDimitry Andric} 4810*0b57cec5SDimitry Andric 4811*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 4812*0b57cec5SDimitry Andricvoid 4813*0b57cec5SDimitry Andric__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 4814*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len, 4815*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size); 4816*0b57cec5SDimitry Andric 4817*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 4818*0b57cec5SDimitry Andricvoid 4819*0b57cec5SDimitry Andric__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp, 4820*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len, 4821*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::value_type* __first2) 4822*0b57cec5SDimitry Andric{ 4823*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 4824*0b57cec5SDimitry Andric switch (__len) 4825*0b57cec5SDimitry Andric { 4826*0b57cec5SDimitry Andric case 0: 4827*0b57cec5SDimitry Andric return; 4828*0b57cec5SDimitry Andric case 1: 4829e8d8bef9SDimitry Andric ::new ((void*)__first2) value_type(_VSTD::move(*__first1)); 4830*0b57cec5SDimitry Andric return; 4831*0b57cec5SDimitry Andric case 2: 4832*0b57cec5SDimitry Andric __destruct_n __d(0); 4833*0b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h2(__first2, __d); 4834*0b57cec5SDimitry Andric if (__comp(*--__last1, *__first1)) 4835*0b57cec5SDimitry Andric { 4836e8d8bef9SDimitry Andric ::new ((void*)__first2) value_type(_VSTD::move(*__last1)); 4837e8d8bef9SDimitry Andric __d.template __incr<value_type>(); 4838*0b57cec5SDimitry Andric ++__first2; 4839e8d8bef9SDimitry Andric ::new ((void*)__first2) value_type(_VSTD::move(*__first1)); 4840*0b57cec5SDimitry Andric } 4841*0b57cec5SDimitry Andric else 4842*0b57cec5SDimitry Andric { 4843e8d8bef9SDimitry Andric ::new ((void*)__first2) value_type(_VSTD::move(*__first1)); 4844e8d8bef9SDimitry Andric __d.template __incr<value_type>(); 4845*0b57cec5SDimitry Andric ++__first2; 4846e8d8bef9SDimitry Andric ::new ((void*)__first2) value_type(_VSTD::move(*__last1)); 4847*0b57cec5SDimitry Andric } 4848*0b57cec5SDimitry Andric __h2.release(); 4849*0b57cec5SDimitry Andric return; 4850*0b57cec5SDimitry Andric } 4851*0b57cec5SDimitry Andric if (__len <= 8) 4852*0b57cec5SDimitry Andric { 4853e8d8bef9SDimitry Andric _VSTD::__insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp); 4854*0b57cec5SDimitry Andric return; 4855*0b57cec5SDimitry Andric } 4856*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; 4857*0b57cec5SDimitry Andric _RandomAccessIterator __m = __first1 + __l2; 4858e8d8bef9SDimitry Andric _VSTD::__stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2); 4859e8d8bef9SDimitry Andric _VSTD::__stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); 4860e8d8bef9SDimitry Andric _VSTD::__merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp); 4861*0b57cec5SDimitry Andric} 4862*0b57cec5SDimitry Andric 4863*0b57cec5SDimitry Andrictemplate <class _Tp> 4864*0b57cec5SDimitry Andricstruct __stable_sort_switch 4865*0b57cec5SDimitry Andric{ 4866*0b57cec5SDimitry Andric static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value; 4867*0b57cec5SDimitry Andric}; 4868*0b57cec5SDimitry Andric 4869*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 4870*0b57cec5SDimitry Andricvoid 4871*0b57cec5SDimitry Andric__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 4872*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len, 4873*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size) 4874*0b57cec5SDimitry Andric{ 4875*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 4876*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 4877*0b57cec5SDimitry Andric switch (__len) 4878*0b57cec5SDimitry Andric { 4879*0b57cec5SDimitry Andric case 0: 4880*0b57cec5SDimitry Andric case 1: 4881*0b57cec5SDimitry Andric return; 4882*0b57cec5SDimitry Andric case 2: 4883*0b57cec5SDimitry Andric if (__comp(*--__last, *__first)) 4884*0b57cec5SDimitry Andric swap(*__first, *__last); 4885*0b57cec5SDimitry Andric return; 4886*0b57cec5SDimitry Andric } 4887*0b57cec5SDimitry Andric if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value)) 4888*0b57cec5SDimitry Andric { 4889e8d8bef9SDimitry Andric _VSTD::__insertion_sort<_Compare>(__first, __last, __comp); 4890*0b57cec5SDimitry Andric return; 4891*0b57cec5SDimitry Andric } 4892*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; 4893*0b57cec5SDimitry Andric _RandomAccessIterator __m = __first + __l2; 4894*0b57cec5SDimitry Andric if (__len <= __buff_size) 4895*0b57cec5SDimitry Andric { 4896*0b57cec5SDimitry Andric __destruct_n __d(0); 4897*0b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h2(__buff, __d); 4898e8d8bef9SDimitry Andric _VSTD::__stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff); 4899e8d8bef9SDimitry Andric __d.__set(__l2, (value_type*)nullptr); 4900e8d8bef9SDimitry Andric _VSTD::__stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); 4901e8d8bef9SDimitry Andric __d.__set(__len, (value_type*)nullptr); 4902e8d8bef9SDimitry Andric _VSTD::__merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); 4903e8d8bef9SDimitry Andric// _VSTD::__merge<_Compare>(move_iterator<value_type*>(__buff), 4904*0b57cec5SDimitry Andric// move_iterator<value_type*>(__buff + __l2), 4905*0b57cec5SDimitry Andric// move_iterator<_RandomAccessIterator>(__buff + __l2), 4906*0b57cec5SDimitry Andric// move_iterator<_RandomAccessIterator>(__buff + __len), 4907*0b57cec5SDimitry Andric// __first, __comp); 4908*0b57cec5SDimitry Andric return; 4909*0b57cec5SDimitry Andric } 4910e8d8bef9SDimitry Andric _VSTD::__stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size); 4911e8d8bef9SDimitry Andric _VSTD::__stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); 4912e8d8bef9SDimitry Andric _VSTD::__inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); 4913*0b57cec5SDimitry Andric} 4914*0b57cec5SDimitry Andric 4915*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 4916*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 4917*0b57cec5SDimitry Andricvoid 4918*0b57cec5SDimitry Andricstable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 4919*0b57cec5SDimitry Andric{ 4920*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 4921*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 4922*0b57cec5SDimitry Andric difference_type __len = __last - __first; 4923*0b57cec5SDimitry Andric pair<value_type*, ptrdiff_t> __buf(0, 0); 4924*0b57cec5SDimitry Andric unique_ptr<value_type, __return_temporary_buffer> __h; 4925*0b57cec5SDimitry Andric if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) 4926*0b57cec5SDimitry Andric { 4927*0b57cec5SDimitry Andric __buf = _VSTD::get_temporary_buffer<value_type>(__len); 4928*0b57cec5SDimitry Andric __h.reset(__buf.first); 4929*0b57cec5SDimitry Andric } 4930*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 4931e8d8bef9SDimitry Andric _VSTD::__stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second); 4932*0b57cec5SDimitry Andric} 4933*0b57cec5SDimitry Andric 4934*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 4935*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 4936*0b57cec5SDimitry Andricvoid 4937*0b57cec5SDimitry Andricstable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) 4938*0b57cec5SDimitry Andric{ 4939*0b57cec5SDimitry Andric _VSTD::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 4940*0b57cec5SDimitry Andric} 4941*0b57cec5SDimitry Andric 4942*0b57cec5SDimitry Andric// is_heap_until 4943*0b57cec5SDimitry Andric 4944*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 4945*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator 4946*0b57cec5SDimitry Andricis_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 4947*0b57cec5SDimitry Andric{ 4948*0b57cec5SDimitry Andric typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::difference_type difference_type; 4949*0b57cec5SDimitry Andric difference_type __len = __last - __first; 4950*0b57cec5SDimitry Andric difference_type __p = 0; 4951*0b57cec5SDimitry Andric difference_type __c = 1; 4952*0b57cec5SDimitry Andric _RandomAccessIterator __pp = __first; 4953*0b57cec5SDimitry Andric while (__c < __len) 4954*0b57cec5SDimitry Andric { 4955*0b57cec5SDimitry Andric _RandomAccessIterator __cp = __first + __c; 4956*0b57cec5SDimitry Andric if (__comp(*__pp, *__cp)) 4957*0b57cec5SDimitry Andric return __cp; 4958*0b57cec5SDimitry Andric ++__c; 4959*0b57cec5SDimitry Andric ++__cp; 4960*0b57cec5SDimitry Andric if (__c == __len) 4961*0b57cec5SDimitry Andric return __last; 4962*0b57cec5SDimitry Andric if (__comp(*__pp, *__cp)) 4963*0b57cec5SDimitry Andric return __cp; 4964*0b57cec5SDimitry Andric ++__p; 4965*0b57cec5SDimitry Andric ++__pp; 4966*0b57cec5SDimitry Andric __c = 2 * __p + 1; 4967*0b57cec5SDimitry Andric } 4968*0b57cec5SDimitry Andric return __last; 4969*0b57cec5SDimitry Andric} 4970*0b57cec5SDimitry Andric 4971*0b57cec5SDimitry Andrictemplate<class _RandomAccessIterator> 4972*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 4973*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4974*0b57cec5SDimitry Andric_RandomAccessIterator 4975*0b57cec5SDimitry Andricis_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) 4976*0b57cec5SDimitry Andric{ 4977*0b57cec5SDimitry Andric return _VSTD::is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 4978*0b57cec5SDimitry Andric} 4979*0b57cec5SDimitry Andric 4980*0b57cec5SDimitry Andric// is_heap 4981*0b57cec5SDimitry Andric 4982*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 4983*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 4984*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4985*0b57cec5SDimitry Andricbool 4986*0b57cec5SDimitry Andricis_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 4987*0b57cec5SDimitry Andric{ 4988*0b57cec5SDimitry Andric return _VSTD::is_heap_until(__first, __last, __comp) == __last; 4989*0b57cec5SDimitry Andric} 4990*0b57cec5SDimitry Andric 4991*0b57cec5SDimitry Andrictemplate<class _RandomAccessIterator> 4992*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 4993*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 4994*0b57cec5SDimitry Andricbool 4995*0b57cec5SDimitry Andricis_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 4996*0b57cec5SDimitry Andric{ 4997*0b57cec5SDimitry Andric return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 4998*0b57cec5SDimitry Andric} 4999*0b57cec5SDimitry Andric 5000*0b57cec5SDimitry Andric// push_heap 5001*0b57cec5SDimitry Andric 5002*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 5003*0b57cec5SDimitry Andricvoid 5004*0b57cec5SDimitry Andric__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 5005*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len) 5006*0b57cec5SDimitry Andric{ 5007*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 5008*0b57cec5SDimitry Andric if (__len > 1) 5009*0b57cec5SDimitry Andric { 5010*0b57cec5SDimitry Andric __len = (__len - 2) / 2; 5011*0b57cec5SDimitry Andric _RandomAccessIterator __ptr = __first + __len; 5012*0b57cec5SDimitry Andric if (__comp(*__ptr, *--__last)) 5013*0b57cec5SDimitry Andric { 5014*0b57cec5SDimitry Andric value_type __t(_VSTD::move(*__last)); 5015*0b57cec5SDimitry Andric do 5016*0b57cec5SDimitry Andric { 5017*0b57cec5SDimitry Andric *__last = _VSTD::move(*__ptr); 5018*0b57cec5SDimitry Andric __last = __ptr; 5019*0b57cec5SDimitry Andric if (__len == 0) 5020*0b57cec5SDimitry Andric break; 5021*0b57cec5SDimitry Andric __len = (__len - 1) / 2; 5022*0b57cec5SDimitry Andric __ptr = __first + __len; 5023*0b57cec5SDimitry Andric } while (__comp(*__ptr, __t)); 5024*0b57cec5SDimitry Andric *__last = _VSTD::move(__t); 5025*0b57cec5SDimitry Andric } 5026*0b57cec5SDimitry Andric } 5027*0b57cec5SDimitry Andric} 5028*0b57cec5SDimitry Andric 5029*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 5030*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5031*0b57cec5SDimitry Andricvoid 5032*0b57cec5SDimitry Andricpush_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 5033*0b57cec5SDimitry Andric{ 5034*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5035e8d8bef9SDimitry Andric _VSTD::__sift_up<_Comp_ref>(__first, __last, __comp, __last - __first); 5036*0b57cec5SDimitry Andric} 5037*0b57cec5SDimitry Andric 5038*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 5039*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5040*0b57cec5SDimitry Andricvoid 5041*0b57cec5SDimitry Andricpush_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 5042*0b57cec5SDimitry Andric{ 5043*0b57cec5SDimitry Andric _VSTD::push_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 5044*0b57cec5SDimitry Andric} 5045*0b57cec5SDimitry Andric 5046*0b57cec5SDimitry Andric// pop_heap 5047*0b57cec5SDimitry Andric 5048*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 5049*0b57cec5SDimitry Andricvoid 5050*0b57cec5SDimitry Andric__sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, 5051*0b57cec5SDimitry Andric _Compare __comp, 5052*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len, 5053*0b57cec5SDimitry Andric _RandomAccessIterator __start) 5054*0b57cec5SDimitry Andric{ 5055*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 5056*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 5057*0b57cec5SDimitry Andric // left-child of __start is at 2 * __start + 1 5058*0b57cec5SDimitry Andric // right-child of __start is at 2 * __start + 2 5059*0b57cec5SDimitry Andric difference_type __child = __start - __first; 5060*0b57cec5SDimitry Andric 5061*0b57cec5SDimitry Andric if (__len < 2 || (__len - 2) / 2 < __child) 5062*0b57cec5SDimitry Andric return; 5063*0b57cec5SDimitry Andric 5064*0b57cec5SDimitry Andric __child = 2 * __child + 1; 5065*0b57cec5SDimitry Andric _RandomAccessIterator __child_i = __first + __child; 5066*0b57cec5SDimitry Andric 5067*0b57cec5SDimitry Andric if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { 5068*0b57cec5SDimitry Andric // right-child exists and is greater than left-child 5069*0b57cec5SDimitry Andric ++__child_i; 5070*0b57cec5SDimitry Andric ++__child; 5071*0b57cec5SDimitry Andric } 5072*0b57cec5SDimitry Andric 5073*0b57cec5SDimitry Andric // check if we are in heap-order 5074*0b57cec5SDimitry Andric if (__comp(*__child_i, *__start)) 5075*0b57cec5SDimitry Andric // we are, __start is larger than it's largest child 5076*0b57cec5SDimitry Andric return; 5077*0b57cec5SDimitry Andric 5078*0b57cec5SDimitry Andric value_type __top(_VSTD::move(*__start)); 5079*0b57cec5SDimitry Andric do 5080*0b57cec5SDimitry Andric { 5081*0b57cec5SDimitry Andric // we are not in heap-order, swap the parent with it's largest child 5082*0b57cec5SDimitry Andric *__start = _VSTD::move(*__child_i); 5083*0b57cec5SDimitry Andric __start = __child_i; 5084*0b57cec5SDimitry Andric 5085*0b57cec5SDimitry Andric if ((__len - 2) / 2 < __child) 5086*0b57cec5SDimitry Andric break; 5087*0b57cec5SDimitry Andric 5088*0b57cec5SDimitry Andric // recompute the child based off of the updated parent 5089*0b57cec5SDimitry Andric __child = 2 * __child + 1; 5090*0b57cec5SDimitry Andric __child_i = __first + __child; 5091*0b57cec5SDimitry Andric 5092*0b57cec5SDimitry Andric if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { 5093*0b57cec5SDimitry Andric // right-child exists and is greater than left-child 5094*0b57cec5SDimitry Andric ++__child_i; 5095*0b57cec5SDimitry Andric ++__child; 5096*0b57cec5SDimitry Andric } 5097*0b57cec5SDimitry Andric 5098*0b57cec5SDimitry Andric // check if we are in heap-order 5099*0b57cec5SDimitry Andric } while (!__comp(*__child_i, __top)); 5100*0b57cec5SDimitry Andric *__start = _VSTD::move(__top); 5101*0b57cec5SDimitry Andric} 5102*0b57cec5SDimitry Andric 5103*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 5104*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5105*0b57cec5SDimitry Andricvoid 5106*0b57cec5SDimitry Andric__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 5107*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len) 5108*0b57cec5SDimitry Andric{ 5109*0b57cec5SDimitry Andric if (__len > 1) 5110*0b57cec5SDimitry Andric { 5111*0b57cec5SDimitry Andric swap(*__first, *--__last); 5112e8d8bef9SDimitry Andric _VSTD::__sift_down<_Compare>(__first, __last, __comp, __len - 1, __first); 5113*0b57cec5SDimitry Andric } 5114*0b57cec5SDimitry Andric} 5115*0b57cec5SDimitry Andric 5116*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 5117*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5118*0b57cec5SDimitry Andricvoid 5119*0b57cec5SDimitry Andricpop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 5120*0b57cec5SDimitry Andric{ 5121*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5122e8d8bef9SDimitry Andric _VSTD::__pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first); 5123*0b57cec5SDimitry Andric} 5124*0b57cec5SDimitry Andric 5125*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 5126*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5127*0b57cec5SDimitry Andricvoid 5128*0b57cec5SDimitry Andricpop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 5129*0b57cec5SDimitry Andric{ 5130*0b57cec5SDimitry Andric _VSTD::pop_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 5131*0b57cec5SDimitry Andric} 5132*0b57cec5SDimitry Andric 5133*0b57cec5SDimitry Andric// make_heap 5134*0b57cec5SDimitry Andric 5135*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 5136*0b57cec5SDimitry Andricvoid 5137*0b57cec5SDimitry Andric__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 5138*0b57cec5SDimitry Andric{ 5139*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 5140*0b57cec5SDimitry Andric difference_type __n = __last - __first; 5141*0b57cec5SDimitry Andric if (__n > 1) 5142*0b57cec5SDimitry Andric { 5143*0b57cec5SDimitry Andric // start from the first parent, there is no need to consider children 5144*0b57cec5SDimitry Andric for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) 5145*0b57cec5SDimitry Andric { 5146e8d8bef9SDimitry Andric _VSTD::__sift_down<_Compare>(__first, __last, __comp, __n, __first + __start); 5147*0b57cec5SDimitry Andric } 5148*0b57cec5SDimitry Andric } 5149*0b57cec5SDimitry Andric} 5150*0b57cec5SDimitry Andric 5151*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 5152*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5153*0b57cec5SDimitry Andricvoid 5154*0b57cec5SDimitry Andricmake_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 5155*0b57cec5SDimitry Andric{ 5156*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5157e8d8bef9SDimitry Andric _VSTD::__make_heap<_Comp_ref>(__first, __last, __comp); 5158*0b57cec5SDimitry Andric} 5159*0b57cec5SDimitry Andric 5160*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 5161*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5162*0b57cec5SDimitry Andricvoid 5163*0b57cec5SDimitry Andricmake_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 5164*0b57cec5SDimitry Andric{ 5165*0b57cec5SDimitry Andric _VSTD::make_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 5166*0b57cec5SDimitry Andric} 5167*0b57cec5SDimitry Andric 5168*0b57cec5SDimitry Andric// sort_heap 5169*0b57cec5SDimitry Andric 5170*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 5171*0b57cec5SDimitry Andricvoid 5172*0b57cec5SDimitry Andric__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 5173*0b57cec5SDimitry Andric{ 5174*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 5175e40139ffSDimitry Andric for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) 5176e8d8bef9SDimitry Andric _VSTD::__pop_heap<_Compare>(__first, __last, __comp, __n); 5177*0b57cec5SDimitry Andric} 5178*0b57cec5SDimitry Andric 5179*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 5180*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5181*0b57cec5SDimitry Andricvoid 5182*0b57cec5SDimitry Andricsort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 5183*0b57cec5SDimitry Andric{ 5184*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5185e8d8bef9SDimitry Andric _VSTD::__sort_heap<_Comp_ref>(__first, __last, __comp); 5186*0b57cec5SDimitry Andric} 5187*0b57cec5SDimitry Andric 5188*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 5189*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5190*0b57cec5SDimitry Andricvoid 5191*0b57cec5SDimitry Andricsort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 5192*0b57cec5SDimitry Andric{ 5193*0b57cec5SDimitry Andric _VSTD::sort_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 5194*0b57cec5SDimitry Andric} 5195*0b57cec5SDimitry Andric 5196*0b57cec5SDimitry Andric// partial_sort 5197*0b57cec5SDimitry Andric 5198*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 5199*0b57cec5SDimitry Andricvoid 5200*0b57cec5SDimitry Andric__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, 5201*0b57cec5SDimitry Andric _Compare __comp) 5202*0b57cec5SDimitry Andric{ 5203e8d8bef9SDimitry Andric _VSTD::__make_heap<_Compare>(__first, __middle, __comp); 5204*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; 5205*0b57cec5SDimitry Andric for (_RandomAccessIterator __i = __middle; __i != __last; ++__i) 5206*0b57cec5SDimitry Andric { 5207*0b57cec5SDimitry Andric if (__comp(*__i, *__first)) 5208*0b57cec5SDimitry Andric { 5209*0b57cec5SDimitry Andric swap(*__i, *__first); 5210e8d8bef9SDimitry Andric _VSTD::__sift_down<_Compare>(__first, __middle, __comp, __len, __first); 5211*0b57cec5SDimitry Andric } 5212*0b57cec5SDimitry Andric } 5213e8d8bef9SDimitry Andric _VSTD::__sort_heap<_Compare>(__first, __middle, __comp); 5214*0b57cec5SDimitry Andric} 5215*0b57cec5SDimitry Andric 5216*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 5217*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5218*0b57cec5SDimitry Andricvoid 5219*0b57cec5SDimitry Andricpartial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, 5220*0b57cec5SDimitry Andric _Compare __comp) 5221*0b57cec5SDimitry Andric{ 5222*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5223e8d8bef9SDimitry Andric _VSTD::__partial_sort<_Comp_ref>(__first, __middle, __last, __comp); 5224*0b57cec5SDimitry Andric} 5225*0b57cec5SDimitry Andric 5226*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 5227*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5228*0b57cec5SDimitry Andricvoid 5229*0b57cec5SDimitry Andricpartial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) 5230*0b57cec5SDimitry Andric{ 5231*0b57cec5SDimitry Andric _VSTD::partial_sort(__first, __middle, __last, 5232*0b57cec5SDimitry Andric __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 5233*0b57cec5SDimitry Andric} 5234*0b57cec5SDimitry Andric 5235*0b57cec5SDimitry Andric// partial_sort_copy 5236*0b57cec5SDimitry Andric 5237*0b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator, class _RandomAccessIterator> 5238*0b57cec5SDimitry Andric_RandomAccessIterator 5239*0b57cec5SDimitry Andric__partial_sort_copy(_InputIterator __first, _InputIterator __last, 5240*0b57cec5SDimitry Andric _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) 5241*0b57cec5SDimitry Andric{ 5242*0b57cec5SDimitry Andric _RandomAccessIterator __r = __result_first; 5243*0b57cec5SDimitry Andric if (__r != __result_last) 5244*0b57cec5SDimitry Andric { 5245e40139ffSDimitry Andric for (; __first != __last && __r != __result_last; ++__first, (void) ++__r) 5246*0b57cec5SDimitry Andric *__r = *__first; 5247e8d8bef9SDimitry Andric _VSTD::__make_heap<_Compare>(__result_first, __r, __comp); 5248*0b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; 5249*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 5250*0b57cec5SDimitry Andric if (__comp(*__first, *__result_first)) 5251*0b57cec5SDimitry Andric { 5252*0b57cec5SDimitry Andric *__result_first = *__first; 5253e8d8bef9SDimitry Andric _VSTD::__sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first); 5254*0b57cec5SDimitry Andric } 5255e8d8bef9SDimitry Andric _VSTD::__sort_heap<_Compare>(__result_first, __r, __comp); 5256*0b57cec5SDimitry Andric } 5257*0b57cec5SDimitry Andric return __r; 5258*0b57cec5SDimitry Andric} 5259*0b57cec5SDimitry Andric 5260*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _RandomAccessIterator, class _Compare> 5261*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5262*0b57cec5SDimitry Andric_RandomAccessIterator 5263*0b57cec5SDimitry Andricpartial_sort_copy(_InputIterator __first, _InputIterator __last, 5264*0b57cec5SDimitry Andric _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) 5265*0b57cec5SDimitry Andric{ 5266*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5267e8d8bef9SDimitry Andric return _VSTD::__partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp); 5268*0b57cec5SDimitry Andric} 5269*0b57cec5SDimitry Andric 5270*0b57cec5SDimitry Andrictemplate <class _InputIterator, class _RandomAccessIterator> 5271*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5272*0b57cec5SDimitry Andric_RandomAccessIterator 5273*0b57cec5SDimitry Andricpartial_sort_copy(_InputIterator __first, _InputIterator __last, 5274*0b57cec5SDimitry Andric _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) 5275*0b57cec5SDimitry Andric{ 5276*0b57cec5SDimitry Andric return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, 5277*0b57cec5SDimitry Andric __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 5278*0b57cec5SDimitry Andric} 5279*0b57cec5SDimitry Andric 5280*0b57cec5SDimitry Andric// nth_element 5281*0b57cec5SDimitry Andric 5282*0b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 5283*0b57cec5SDimitry Andricvoid 5284*0b57cec5SDimitry Andric__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) 5285*0b57cec5SDimitry Andric{ 5286*0b57cec5SDimitry Andric // _Compare is known to be a reference type 5287*0b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 5288*0b57cec5SDimitry Andric const difference_type __limit = 7; 5289*0b57cec5SDimitry Andric while (true) 5290*0b57cec5SDimitry Andric { 5291*0b57cec5SDimitry Andric __restart: 5292*0b57cec5SDimitry Andric if (__nth == __last) 5293*0b57cec5SDimitry Andric return; 5294*0b57cec5SDimitry Andric difference_type __len = __last - __first; 5295*0b57cec5SDimitry Andric switch (__len) 5296*0b57cec5SDimitry Andric { 5297*0b57cec5SDimitry Andric case 0: 5298*0b57cec5SDimitry Andric case 1: 5299*0b57cec5SDimitry Andric return; 5300*0b57cec5SDimitry Andric case 2: 5301*0b57cec5SDimitry Andric if (__comp(*--__last, *__first)) 5302*0b57cec5SDimitry Andric swap(*__first, *__last); 5303*0b57cec5SDimitry Andric return; 5304*0b57cec5SDimitry Andric case 3: 5305*0b57cec5SDimitry Andric { 5306*0b57cec5SDimitry Andric _RandomAccessIterator __m = __first; 5307*0b57cec5SDimitry Andric _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp); 5308*0b57cec5SDimitry Andric return; 5309*0b57cec5SDimitry Andric } 5310*0b57cec5SDimitry Andric } 5311*0b57cec5SDimitry Andric if (__len <= __limit) 5312*0b57cec5SDimitry Andric { 5313e8d8bef9SDimitry Andric _VSTD::__selection_sort<_Compare>(__first, __last, __comp); 5314*0b57cec5SDimitry Andric return; 5315*0b57cec5SDimitry Andric } 5316*0b57cec5SDimitry Andric // __len > __limit >= 3 5317*0b57cec5SDimitry Andric _RandomAccessIterator __m = __first + __len/2; 5318*0b57cec5SDimitry Andric _RandomAccessIterator __lm1 = __last; 5319*0b57cec5SDimitry Andric unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp); 5320*0b57cec5SDimitry Andric // *__m is median 5321*0b57cec5SDimitry Andric // partition [__first, __m) < *__m and *__m <= [__m, __last) 5322*0b57cec5SDimitry Andric // (this inhibits tossing elements equivalent to __m around unnecessarily) 5323*0b57cec5SDimitry Andric _RandomAccessIterator __i = __first; 5324*0b57cec5SDimitry Andric _RandomAccessIterator __j = __lm1; 5325*0b57cec5SDimitry Andric // j points beyond range to be tested, *__lm1 is known to be <= *__m 5326*0b57cec5SDimitry Andric // The search going up is known to be guarded but the search coming down isn't. 5327*0b57cec5SDimitry Andric // Prime the downward search with a guard. 5328*0b57cec5SDimitry Andric if (!__comp(*__i, *__m)) // if *__first == *__m 5329*0b57cec5SDimitry Andric { 5330*0b57cec5SDimitry Andric // *__first == *__m, *__first doesn't go in first part 5331*0b57cec5SDimitry Andric // manually guard downward moving __j against __i 5332*0b57cec5SDimitry Andric while (true) 5333*0b57cec5SDimitry Andric { 5334*0b57cec5SDimitry Andric if (__i == --__j) 5335*0b57cec5SDimitry Andric { 5336*0b57cec5SDimitry Andric // *__first == *__m, *__m <= all other elements 5337e8d8bef9SDimitry Andric // Partition instead into [__first, __i) == *__first and *__first < [__i, __last) 5338*0b57cec5SDimitry Andric ++__i; // __first + 1 5339*0b57cec5SDimitry Andric __j = __last; 5340*0b57cec5SDimitry Andric if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1) 5341*0b57cec5SDimitry Andric { 5342*0b57cec5SDimitry Andric while (true) 5343*0b57cec5SDimitry Andric { 5344*0b57cec5SDimitry Andric if (__i == __j) 5345*0b57cec5SDimitry Andric return; // [__first, __last) all equivalent elements 5346*0b57cec5SDimitry Andric if (__comp(*__first, *__i)) 5347*0b57cec5SDimitry Andric { 5348*0b57cec5SDimitry Andric swap(*__i, *__j); 5349*0b57cec5SDimitry Andric ++__n_swaps; 5350*0b57cec5SDimitry Andric ++__i; 5351*0b57cec5SDimitry Andric break; 5352*0b57cec5SDimitry Andric } 5353*0b57cec5SDimitry Andric ++__i; 5354*0b57cec5SDimitry Andric } 5355*0b57cec5SDimitry Andric } 5356*0b57cec5SDimitry Andric // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 5357*0b57cec5SDimitry Andric if (__i == __j) 5358*0b57cec5SDimitry Andric return; 5359*0b57cec5SDimitry Andric while (true) 5360*0b57cec5SDimitry Andric { 5361*0b57cec5SDimitry Andric while (!__comp(*__first, *__i)) 5362*0b57cec5SDimitry Andric ++__i; 5363*0b57cec5SDimitry Andric while (__comp(*__first, *--__j)) 5364*0b57cec5SDimitry Andric ; 5365*0b57cec5SDimitry Andric if (__i >= __j) 5366*0b57cec5SDimitry Andric break; 5367*0b57cec5SDimitry Andric swap(*__i, *__j); 5368*0b57cec5SDimitry Andric ++__n_swaps; 5369*0b57cec5SDimitry Andric ++__i; 5370*0b57cec5SDimitry Andric } 5371*0b57cec5SDimitry Andric // [__first, __i) == *__first and *__first < [__i, __last) 5372*0b57cec5SDimitry Andric // The first part is sorted, 5373*0b57cec5SDimitry Andric if (__nth < __i) 5374*0b57cec5SDimitry Andric return; 5375e8d8bef9SDimitry Andric // __nth_element the second part 5376e8d8bef9SDimitry Andric // _VSTD::__nth_element<_Compare>(__i, __nth, __last, __comp); 5377*0b57cec5SDimitry Andric __first = __i; 5378*0b57cec5SDimitry Andric goto __restart; 5379*0b57cec5SDimitry Andric } 5380*0b57cec5SDimitry Andric if (__comp(*__j, *__m)) 5381*0b57cec5SDimitry Andric { 5382*0b57cec5SDimitry Andric swap(*__i, *__j); 5383*0b57cec5SDimitry Andric ++__n_swaps; 5384*0b57cec5SDimitry Andric break; // found guard for downward moving __j, now use unguarded partition 5385*0b57cec5SDimitry Andric } 5386*0b57cec5SDimitry Andric } 5387*0b57cec5SDimitry Andric } 5388*0b57cec5SDimitry Andric ++__i; 5389*0b57cec5SDimitry Andric // j points beyond range to be tested, *__lm1 is known to be <= *__m 5390*0b57cec5SDimitry Andric // if not yet partitioned... 5391*0b57cec5SDimitry Andric if (__i < __j) 5392*0b57cec5SDimitry Andric { 5393*0b57cec5SDimitry Andric // known that *(__i - 1) < *__m 5394*0b57cec5SDimitry Andric while (true) 5395*0b57cec5SDimitry Andric { 5396*0b57cec5SDimitry Andric // __m still guards upward moving __i 5397*0b57cec5SDimitry Andric while (__comp(*__i, *__m)) 5398*0b57cec5SDimitry Andric ++__i; 5399*0b57cec5SDimitry Andric // It is now known that a guard exists for downward moving __j 5400*0b57cec5SDimitry Andric while (!__comp(*--__j, *__m)) 5401*0b57cec5SDimitry Andric ; 5402*0b57cec5SDimitry Andric if (__i >= __j) 5403*0b57cec5SDimitry Andric break; 5404*0b57cec5SDimitry Andric swap(*__i, *__j); 5405*0b57cec5SDimitry Andric ++__n_swaps; 5406*0b57cec5SDimitry Andric // It is known that __m != __j 5407*0b57cec5SDimitry Andric // If __m just moved, follow it 5408*0b57cec5SDimitry Andric if (__m == __i) 5409*0b57cec5SDimitry Andric __m = __j; 5410*0b57cec5SDimitry Andric ++__i; 5411*0b57cec5SDimitry Andric } 5412*0b57cec5SDimitry Andric } 5413*0b57cec5SDimitry Andric // [__first, __i) < *__m and *__m <= [__i, __last) 5414*0b57cec5SDimitry Andric if (__i != __m && __comp(*__m, *__i)) 5415*0b57cec5SDimitry Andric { 5416*0b57cec5SDimitry Andric swap(*__i, *__m); 5417*0b57cec5SDimitry Andric ++__n_swaps; 5418*0b57cec5SDimitry Andric } 5419*0b57cec5SDimitry Andric // [__first, __i) < *__i and *__i <= [__i+1, __last) 5420*0b57cec5SDimitry Andric if (__nth == __i) 5421*0b57cec5SDimitry Andric return; 5422*0b57cec5SDimitry Andric if (__n_swaps == 0) 5423*0b57cec5SDimitry Andric { 5424*0b57cec5SDimitry Andric // We were given a perfectly partitioned sequence. Coincidence? 5425*0b57cec5SDimitry Andric if (__nth < __i) 5426*0b57cec5SDimitry Andric { 5427*0b57cec5SDimitry Andric // Check for [__first, __i) already sorted 5428*0b57cec5SDimitry Andric __j = __m = __first; 5429*0b57cec5SDimitry Andric while (++__j != __i) 5430*0b57cec5SDimitry Andric { 5431*0b57cec5SDimitry Andric if (__comp(*__j, *__m)) 5432*0b57cec5SDimitry Andric // not yet sorted, so sort 5433*0b57cec5SDimitry Andric goto not_sorted; 5434*0b57cec5SDimitry Andric __m = __j; 5435*0b57cec5SDimitry Andric } 5436*0b57cec5SDimitry Andric // [__first, __i) sorted 5437*0b57cec5SDimitry Andric return; 5438*0b57cec5SDimitry Andric } 5439*0b57cec5SDimitry Andric else 5440*0b57cec5SDimitry Andric { 5441*0b57cec5SDimitry Andric // Check for [__i, __last) already sorted 5442*0b57cec5SDimitry Andric __j = __m = __i; 5443*0b57cec5SDimitry Andric while (++__j != __last) 5444*0b57cec5SDimitry Andric { 5445*0b57cec5SDimitry Andric if (__comp(*__j, *__m)) 5446*0b57cec5SDimitry Andric // not yet sorted, so sort 5447*0b57cec5SDimitry Andric goto not_sorted; 5448*0b57cec5SDimitry Andric __m = __j; 5449*0b57cec5SDimitry Andric } 5450*0b57cec5SDimitry Andric // [__i, __last) sorted 5451*0b57cec5SDimitry Andric return; 5452*0b57cec5SDimitry Andric } 5453*0b57cec5SDimitry Andric } 5454*0b57cec5SDimitry Andricnot_sorted: 5455*0b57cec5SDimitry Andric // __nth_element on range containing __nth 5456*0b57cec5SDimitry Andric if (__nth < __i) 5457*0b57cec5SDimitry Andric { 5458e8d8bef9SDimitry Andric // _VSTD::__nth_element<_Compare>(__first, __nth, __i, __comp); 5459*0b57cec5SDimitry Andric __last = __i; 5460*0b57cec5SDimitry Andric } 5461*0b57cec5SDimitry Andric else 5462*0b57cec5SDimitry Andric { 5463e8d8bef9SDimitry Andric // _VSTD::__nth_element<_Compare>(__i+1, __nth, __last, __comp); 5464*0b57cec5SDimitry Andric __first = ++__i; 5465*0b57cec5SDimitry Andric } 5466*0b57cec5SDimitry Andric } 5467*0b57cec5SDimitry Andric} 5468*0b57cec5SDimitry Andric 5469*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 5470*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5471*0b57cec5SDimitry Andricvoid 5472*0b57cec5SDimitry Andricnth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) 5473*0b57cec5SDimitry Andric{ 5474*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5475e8d8bef9SDimitry Andric _VSTD::__nth_element<_Comp_ref>(__first, __nth, __last, __comp); 5476*0b57cec5SDimitry Andric} 5477*0b57cec5SDimitry Andric 5478*0b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 5479*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5480*0b57cec5SDimitry Andricvoid 5481*0b57cec5SDimitry Andricnth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) 5482*0b57cec5SDimitry Andric{ 5483*0b57cec5SDimitry Andric _VSTD::nth_element(__first, __nth, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 5484*0b57cec5SDimitry Andric} 5485*0b57cec5SDimitry Andric 5486*0b57cec5SDimitry Andric// includes 5487*0b57cec5SDimitry Andric 5488*0b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2> 5489*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 5490*0b57cec5SDimitry Andric__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, 5491*0b57cec5SDimitry Andric _Compare __comp) 5492*0b57cec5SDimitry Andric{ 5493*0b57cec5SDimitry Andric for (; __first2 != __last2; ++__first1) 5494*0b57cec5SDimitry Andric { 5495*0b57cec5SDimitry Andric if (__first1 == __last1 || __comp(*__first2, *__first1)) 5496*0b57cec5SDimitry Andric return false; 5497*0b57cec5SDimitry Andric if (!__comp(*__first1, *__first2)) 5498*0b57cec5SDimitry Andric ++__first2; 5499*0b57cec5SDimitry Andric } 5500*0b57cec5SDimitry Andric return true; 5501*0b57cec5SDimitry Andric} 5502*0b57cec5SDimitry Andric 5503*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _Compare> 5504*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 5505*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5506*0b57cec5SDimitry Andricbool 5507*0b57cec5SDimitry Andricincludes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, 5508*0b57cec5SDimitry Andric _Compare __comp) 5509*0b57cec5SDimitry Andric{ 5510*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5511e8d8bef9SDimitry Andric return _VSTD::__includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); 5512*0b57cec5SDimitry Andric} 5513*0b57cec5SDimitry Andric 5514*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 5515*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 5516*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5517*0b57cec5SDimitry Andricbool 5518*0b57cec5SDimitry Andricincludes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) 5519*0b57cec5SDimitry Andric{ 5520*0b57cec5SDimitry Andric return _VSTD::includes(__first1, __last1, __first2, __last2, 5521*0b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 5522*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 5523*0b57cec5SDimitry Andric} 5524*0b57cec5SDimitry Andric 5525*0b57cec5SDimitry Andric// set_union 5526*0b57cec5SDimitry Andric 5527*0b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 5528e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 5529*0b57cec5SDimitry Andric__set_union(_InputIterator1 __first1, _InputIterator1 __last1, 5530*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 5531*0b57cec5SDimitry Andric{ 5532*0b57cec5SDimitry Andric for (; __first1 != __last1; ++__result) 5533*0b57cec5SDimitry Andric { 5534*0b57cec5SDimitry Andric if (__first2 == __last2) 5535*0b57cec5SDimitry Andric return _VSTD::copy(__first1, __last1, __result); 5536*0b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 5537*0b57cec5SDimitry Andric { 5538*0b57cec5SDimitry Andric *__result = *__first2; 5539*0b57cec5SDimitry Andric ++__first2; 5540*0b57cec5SDimitry Andric } 5541*0b57cec5SDimitry Andric else 5542*0b57cec5SDimitry Andric { 5543*0b57cec5SDimitry Andric if (!__comp(*__first1, *__first2)) 5544*0b57cec5SDimitry Andric ++__first2; 5545*0b57cec5SDimitry Andric *__result = *__first1; 5546*0b57cec5SDimitry Andric ++__first1; 5547*0b57cec5SDimitry Andric } 5548*0b57cec5SDimitry Andric } 5549*0b57cec5SDimitry Andric return _VSTD::copy(__first2, __last2, __result); 5550*0b57cec5SDimitry Andric} 5551*0b57cec5SDimitry Andric 5552*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 5553e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5554*0b57cec5SDimitry Andric_OutputIterator 5555*0b57cec5SDimitry Andricset_union(_InputIterator1 __first1, _InputIterator1 __last1, 5556*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 5557*0b57cec5SDimitry Andric{ 5558*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5559e8d8bef9SDimitry Andric return _VSTD::__set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 5560*0b57cec5SDimitry Andric} 5561*0b57cec5SDimitry Andric 5562*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 5563e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5564*0b57cec5SDimitry Andric_OutputIterator 5565*0b57cec5SDimitry Andricset_union(_InputIterator1 __first1, _InputIterator1 __last1, 5566*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 5567*0b57cec5SDimitry Andric{ 5568*0b57cec5SDimitry Andric return _VSTD::set_union(__first1, __last1, __first2, __last2, __result, 5569*0b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 5570*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 5571*0b57cec5SDimitry Andric} 5572*0b57cec5SDimitry Andric 5573*0b57cec5SDimitry Andric// set_intersection 5574*0b57cec5SDimitry Andric 5575*0b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 5576*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 5577*0b57cec5SDimitry Andric__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 5578*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 5579*0b57cec5SDimitry Andric{ 5580*0b57cec5SDimitry Andric while (__first1 != __last1 && __first2 != __last2) 5581*0b57cec5SDimitry Andric { 5582*0b57cec5SDimitry Andric if (__comp(*__first1, *__first2)) 5583*0b57cec5SDimitry Andric ++__first1; 5584*0b57cec5SDimitry Andric else 5585*0b57cec5SDimitry Andric { 5586*0b57cec5SDimitry Andric if (!__comp(*__first2, *__first1)) 5587*0b57cec5SDimitry Andric { 5588*0b57cec5SDimitry Andric *__result = *__first1; 5589*0b57cec5SDimitry Andric ++__result; 5590*0b57cec5SDimitry Andric ++__first1; 5591*0b57cec5SDimitry Andric } 5592*0b57cec5SDimitry Andric ++__first2; 5593*0b57cec5SDimitry Andric } 5594*0b57cec5SDimitry Andric } 5595*0b57cec5SDimitry Andric return __result; 5596*0b57cec5SDimitry Andric} 5597*0b57cec5SDimitry Andric 5598*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 5599*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5600*0b57cec5SDimitry Andric_OutputIterator 5601*0b57cec5SDimitry Andricset_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 5602*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 5603*0b57cec5SDimitry Andric{ 5604*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5605e8d8bef9SDimitry Andric return _VSTD::__set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 5606*0b57cec5SDimitry Andric} 5607*0b57cec5SDimitry Andric 5608*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 5609*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5610*0b57cec5SDimitry Andric_OutputIterator 5611*0b57cec5SDimitry Andricset_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 5612*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 5613*0b57cec5SDimitry Andric{ 5614*0b57cec5SDimitry Andric return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result, 5615*0b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 5616*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 5617*0b57cec5SDimitry Andric} 5618*0b57cec5SDimitry Andric 5619*0b57cec5SDimitry Andric// set_difference 5620*0b57cec5SDimitry Andric 5621*0b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 5622e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 5623*0b57cec5SDimitry Andric__set_difference(_InputIterator1 __first1, _InputIterator1 __last1, 5624*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 5625*0b57cec5SDimitry Andric{ 5626*0b57cec5SDimitry Andric while (__first1 != __last1) 5627*0b57cec5SDimitry Andric { 5628*0b57cec5SDimitry Andric if (__first2 == __last2) 5629*0b57cec5SDimitry Andric return _VSTD::copy(__first1, __last1, __result); 5630*0b57cec5SDimitry Andric if (__comp(*__first1, *__first2)) 5631*0b57cec5SDimitry Andric { 5632*0b57cec5SDimitry Andric *__result = *__first1; 5633*0b57cec5SDimitry Andric ++__result; 5634*0b57cec5SDimitry Andric ++__first1; 5635*0b57cec5SDimitry Andric } 5636*0b57cec5SDimitry Andric else 5637*0b57cec5SDimitry Andric { 5638*0b57cec5SDimitry Andric if (!__comp(*__first2, *__first1)) 5639*0b57cec5SDimitry Andric ++__first1; 5640*0b57cec5SDimitry Andric ++__first2; 5641*0b57cec5SDimitry Andric } 5642*0b57cec5SDimitry Andric } 5643*0b57cec5SDimitry Andric return __result; 5644*0b57cec5SDimitry Andric} 5645*0b57cec5SDimitry Andric 5646*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 5647e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5648*0b57cec5SDimitry Andric_OutputIterator 5649*0b57cec5SDimitry Andricset_difference(_InputIterator1 __first1, _InputIterator1 __last1, 5650*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 5651*0b57cec5SDimitry Andric{ 5652*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5653e8d8bef9SDimitry Andric return _VSTD::__set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 5654*0b57cec5SDimitry Andric} 5655*0b57cec5SDimitry Andric 5656*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 5657e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5658*0b57cec5SDimitry Andric_OutputIterator 5659*0b57cec5SDimitry Andricset_difference(_InputIterator1 __first1, _InputIterator1 __last1, 5660*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 5661*0b57cec5SDimitry Andric{ 5662*0b57cec5SDimitry Andric return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result, 5663*0b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 5664*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 5665*0b57cec5SDimitry Andric} 5666*0b57cec5SDimitry Andric 5667*0b57cec5SDimitry Andric// set_symmetric_difference 5668*0b57cec5SDimitry Andric 5669*0b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 5670e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 5671*0b57cec5SDimitry Andric__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 5672*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 5673*0b57cec5SDimitry Andric{ 5674*0b57cec5SDimitry Andric while (__first1 != __last1) 5675*0b57cec5SDimitry Andric { 5676*0b57cec5SDimitry Andric if (__first2 == __last2) 5677*0b57cec5SDimitry Andric return _VSTD::copy(__first1, __last1, __result); 5678*0b57cec5SDimitry Andric if (__comp(*__first1, *__first2)) 5679*0b57cec5SDimitry Andric { 5680*0b57cec5SDimitry Andric *__result = *__first1; 5681*0b57cec5SDimitry Andric ++__result; 5682*0b57cec5SDimitry Andric ++__first1; 5683*0b57cec5SDimitry Andric } 5684*0b57cec5SDimitry Andric else 5685*0b57cec5SDimitry Andric { 5686*0b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 5687*0b57cec5SDimitry Andric { 5688*0b57cec5SDimitry Andric *__result = *__first2; 5689*0b57cec5SDimitry Andric ++__result; 5690*0b57cec5SDimitry Andric } 5691*0b57cec5SDimitry Andric else 5692*0b57cec5SDimitry Andric ++__first1; 5693*0b57cec5SDimitry Andric ++__first2; 5694*0b57cec5SDimitry Andric } 5695*0b57cec5SDimitry Andric } 5696*0b57cec5SDimitry Andric return _VSTD::copy(__first2, __last2, __result); 5697*0b57cec5SDimitry Andric} 5698*0b57cec5SDimitry Andric 5699*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 5700e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5701*0b57cec5SDimitry Andric_OutputIterator 5702*0b57cec5SDimitry Andricset_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 5703*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 5704*0b57cec5SDimitry Andric{ 5705*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5706e8d8bef9SDimitry Andric return _VSTD::__set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 5707*0b57cec5SDimitry Andric} 5708*0b57cec5SDimitry Andric 5709*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 5710e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5711*0b57cec5SDimitry Andric_OutputIterator 5712*0b57cec5SDimitry Andricset_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 5713*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 5714*0b57cec5SDimitry Andric{ 5715*0b57cec5SDimitry Andric return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, 5716*0b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 5717*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 5718*0b57cec5SDimitry Andric} 5719*0b57cec5SDimitry Andric 5720*0b57cec5SDimitry Andric// lexicographical_compare 5721*0b57cec5SDimitry Andric 5722*0b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2> 5723*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 5724*0b57cec5SDimitry Andric__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, 5725*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) 5726*0b57cec5SDimitry Andric{ 5727*0b57cec5SDimitry Andric for (; __first2 != __last2; ++__first1, (void) ++__first2) 5728*0b57cec5SDimitry Andric { 5729*0b57cec5SDimitry Andric if (__first1 == __last1 || __comp(*__first1, *__first2)) 5730*0b57cec5SDimitry Andric return true; 5731*0b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 5732*0b57cec5SDimitry Andric return false; 5733*0b57cec5SDimitry Andric } 5734*0b57cec5SDimitry Andric return false; 5735*0b57cec5SDimitry Andric} 5736*0b57cec5SDimitry Andric 5737*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _Compare> 5738*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 5739*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5740*0b57cec5SDimitry Andricbool 5741*0b57cec5SDimitry Andriclexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, 5742*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) 5743*0b57cec5SDimitry Andric{ 5744*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5745e8d8bef9SDimitry Andric return _VSTD::__lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); 5746*0b57cec5SDimitry Andric} 5747*0b57cec5SDimitry Andric 5748*0b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 5749*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 5750*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5751*0b57cec5SDimitry Andricbool 5752*0b57cec5SDimitry Andriclexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, 5753*0b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2) 5754*0b57cec5SDimitry Andric{ 5755*0b57cec5SDimitry Andric return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, 5756*0b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 5757*0b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 5758*0b57cec5SDimitry Andric} 5759*0b57cec5SDimitry Andric 5760*0b57cec5SDimitry Andric// next_permutation 5761*0b57cec5SDimitry Andric 5762*0b57cec5SDimitry Andrictemplate <class _Compare, class _BidirectionalIterator> 5763e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 5764*0b57cec5SDimitry Andric__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 5765*0b57cec5SDimitry Andric{ 5766*0b57cec5SDimitry Andric _BidirectionalIterator __i = __last; 5767*0b57cec5SDimitry Andric if (__first == __last || __first == --__i) 5768*0b57cec5SDimitry Andric return false; 5769*0b57cec5SDimitry Andric while (true) 5770*0b57cec5SDimitry Andric { 5771*0b57cec5SDimitry Andric _BidirectionalIterator __ip1 = __i; 5772*0b57cec5SDimitry Andric if (__comp(*--__i, *__ip1)) 5773*0b57cec5SDimitry Andric { 5774*0b57cec5SDimitry Andric _BidirectionalIterator __j = __last; 5775*0b57cec5SDimitry Andric while (!__comp(*__i, *--__j)) 5776*0b57cec5SDimitry Andric ; 5777*0b57cec5SDimitry Andric swap(*__i, *__j); 5778*0b57cec5SDimitry Andric _VSTD::reverse(__ip1, __last); 5779*0b57cec5SDimitry Andric return true; 5780*0b57cec5SDimitry Andric } 5781*0b57cec5SDimitry Andric if (__i == __first) 5782*0b57cec5SDimitry Andric { 5783*0b57cec5SDimitry Andric _VSTD::reverse(__first, __last); 5784*0b57cec5SDimitry Andric return false; 5785*0b57cec5SDimitry Andric } 5786*0b57cec5SDimitry Andric } 5787*0b57cec5SDimitry Andric} 5788*0b57cec5SDimitry Andric 5789*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator, class _Compare> 5790e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5791*0b57cec5SDimitry Andricbool 5792*0b57cec5SDimitry Andricnext_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 5793*0b57cec5SDimitry Andric{ 5794*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5795e8d8bef9SDimitry Andric return _VSTD::__next_permutation<_Comp_ref>(__first, __last, __comp); 5796*0b57cec5SDimitry Andric} 5797*0b57cec5SDimitry Andric 5798*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 5799e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5800*0b57cec5SDimitry Andricbool 5801*0b57cec5SDimitry Andricnext_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) 5802*0b57cec5SDimitry Andric{ 5803*0b57cec5SDimitry Andric return _VSTD::next_permutation(__first, __last, 5804*0b57cec5SDimitry Andric __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); 5805*0b57cec5SDimitry Andric} 5806*0b57cec5SDimitry Andric 5807*0b57cec5SDimitry Andric// prev_permutation 5808*0b57cec5SDimitry Andric 5809*0b57cec5SDimitry Andrictemplate <class _Compare, class _BidirectionalIterator> 5810e8d8bef9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 5811*0b57cec5SDimitry Andric__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 5812*0b57cec5SDimitry Andric{ 5813*0b57cec5SDimitry Andric _BidirectionalIterator __i = __last; 5814*0b57cec5SDimitry Andric if (__first == __last || __first == --__i) 5815*0b57cec5SDimitry Andric return false; 5816*0b57cec5SDimitry Andric while (true) 5817*0b57cec5SDimitry Andric { 5818*0b57cec5SDimitry Andric _BidirectionalIterator __ip1 = __i; 5819*0b57cec5SDimitry Andric if (__comp(*__ip1, *--__i)) 5820*0b57cec5SDimitry Andric { 5821*0b57cec5SDimitry Andric _BidirectionalIterator __j = __last; 5822*0b57cec5SDimitry Andric while (!__comp(*--__j, *__i)) 5823*0b57cec5SDimitry Andric ; 5824*0b57cec5SDimitry Andric swap(*__i, *__j); 5825*0b57cec5SDimitry Andric _VSTD::reverse(__ip1, __last); 5826*0b57cec5SDimitry Andric return true; 5827*0b57cec5SDimitry Andric } 5828*0b57cec5SDimitry Andric if (__i == __first) 5829*0b57cec5SDimitry Andric { 5830*0b57cec5SDimitry Andric _VSTD::reverse(__first, __last); 5831*0b57cec5SDimitry Andric return false; 5832*0b57cec5SDimitry Andric } 5833*0b57cec5SDimitry Andric } 5834*0b57cec5SDimitry Andric} 5835*0b57cec5SDimitry Andric 5836*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator, class _Compare> 5837e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5838*0b57cec5SDimitry Andricbool 5839*0b57cec5SDimitry Andricprev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 5840*0b57cec5SDimitry Andric{ 5841*0b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 5842e8d8bef9SDimitry Andric return _VSTD::__prev_permutation<_Comp_ref>(__first, __last, __comp); 5843*0b57cec5SDimitry Andric} 5844*0b57cec5SDimitry Andric 5845*0b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 5846e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 5847*0b57cec5SDimitry Andricbool 5848*0b57cec5SDimitry Andricprev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) 5849*0b57cec5SDimitry Andric{ 5850*0b57cec5SDimitry Andric return _VSTD::prev_permutation(__first, __last, 5851*0b57cec5SDimitry Andric __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); 5852*0b57cec5SDimitry Andric} 5853*0b57cec5SDimitry Andric 5854*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 5855*0b57cec5SDimitry Andric 5856*0b57cec5SDimitry Andric_LIBCPP_POP_MACROS 5857*0b57cec5SDimitry Andric 5858e40139ffSDimitry Andric#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 5859e40139ffSDimitry Andric# include <__pstl_algorithm> 5860e40139ffSDimitry Andric#endif 5861e40139ffSDimitry Andric 5862*0b57cec5SDimitry Andric#endif // _LIBCPP_ALGORITHM 5863