10b57cec5SDimitry Andric// -*- C++ -*- 20b57cec5SDimitry Andric//===-------------------------- algorithm ---------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_ALGORITHM 110b57cec5SDimitry Andric#define _LIBCPP_ALGORITHM 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andric algorithm synopsis 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric#include <initializer_list> 170b57cec5SDimitry Andric 180b57cec5SDimitry Andricnamespace std 190b57cec5SDimitry Andric{ 200b57cec5SDimitry Andric 210b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 220b57cec5SDimitry Andric constexpr bool // constexpr in C++20 230b57cec5SDimitry Andric all_of(InputIterator first, InputIterator last, Predicate pred); 240b57cec5SDimitry Andric 250b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 260b57cec5SDimitry Andric constexpr bool // constexpr in C++20 270b57cec5SDimitry Andric any_of(InputIterator first, InputIterator last, Predicate pred); 280b57cec5SDimitry Andric 290b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 300b57cec5SDimitry Andric constexpr bool // constexpr in C++20 310b57cec5SDimitry Andric none_of(InputIterator first, InputIterator last, Predicate pred); 320b57cec5SDimitry Andric 330b57cec5SDimitry Andrictemplate <class InputIterator, class Function> 340b57cec5SDimitry Andric constexpr Function // constexpr in C++20 350b57cec5SDimitry Andric for_each(InputIterator first, InputIterator last, Function f); 360b57cec5SDimitry Andric 370b57cec5SDimitry Andrictemplate<class InputIterator, class Size, class Function> 380b57cec5SDimitry Andric constexpr InputIterator // constexpr in C++20 390b57cec5SDimitry Andric for_each_n(InputIterator first, Size n, Function f); // C++17 400b57cec5SDimitry Andric 410b57cec5SDimitry Andrictemplate <class InputIterator, class T> 420b57cec5SDimitry Andric constexpr InputIterator // constexpr in C++20 430b57cec5SDimitry Andric find(InputIterator first, InputIterator last, const T& value); 440b57cec5SDimitry Andric 450b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 460b57cec5SDimitry Andric constexpr InputIterator // constexpr in C++20 470b57cec5SDimitry Andric find_if(InputIterator first, InputIterator last, Predicate pred); 480b57cec5SDimitry Andric 490b57cec5SDimitry Andrictemplate<class InputIterator, class Predicate> 500b57cec5SDimitry Andric InputIterator // constexpr in C++20 510b57cec5SDimitry Andric find_if_not(InputIterator first, InputIterator last, Predicate pred); 520b57cec5SDimitry Andric 530b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2> 540b57cec5SDimitry Andric ForwardIterator1 // constexpr in C++20 550b57cec5SDimitry Andric find_end(ForwardIterator1 first1, ForwardIterator1 last1, 560b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2); 570b57cec5SDimitry Andric 580b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 590b57cec5SDimitry Andric ForwardIterator1 // constexpr in C++20 600b57cec5SDimitry Andric find_end(ForwardIterator1 first1, ForwardIterator1 last1, 610b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); 620b57cec5SDimitry Andric 630b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2> 640b57cec5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 650b57cec5SDimitry Andric find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, 660b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 690b57cec5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 700b57cec5SDimitry Andric find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, 710b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); 720b57cec5SDimitry Andric 730b57cec5SDimitry Andrictemplate <class ForwardIterator> 740b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 750b57cec5SDimitry Andric adjacent_find(ForwardIterator first, ForwardIterator last); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andrictemplate <class ForwardIterator, class BinaryPredicate> 780b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 790b57cec5SDimitry Andric adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); 800b57cec5SDimitry Andric 810b57cec5SDimitry Andrictemplate <class InputIterator, class T> 820b57cec5SDimitry Andric constexpr typename iterator_traits<InputIterator>::difference_type // constexpr in C++20 830b57cec5SDimitry Andric count(InputIterator first, InputIterator last, const T& value); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 860b57cec5SDimitry Andric constexpr typename iterator_traits<InputIterator>::difference_type // constexpr in C++20 870b57cec5SDimitry Andric count_if(InputIterator first, InputIterator last, Predicate pred); 880b57cec5SDimitry Andric 890b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 900b57cec5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 910b57cec5SDimitry Andric mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); 920b57cec5SDimitry Andric 930b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 940b57cec5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 950b57cec5SDimitry Andric mismatch(InputIterator1 first1, InputIterator1 last1, 960b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2); // **C++14** 970b57cec5SDimitry Andric 980b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 990b57cec5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 1000b57cec5SDimitry Andric mismatch(InputIterator1 first1, InputIterator1 last1, 1010b57cec5SDimitry Andric InputIterator2 first2, BinaryPredicate pred); 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 1040b57cec5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 1050b57cec5SDimitry Andric mismatch(InputIterator1 first1, InputIterator1 last1, 1060b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, 1070b57cec5SDimitry Andric BinaryPredicate pred); // **C++14** 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 1100b57cec5SDimitry Andric constexpr bool // constexpr in C++20 1110b57cec5SDimitry Andric equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 1140b57cec5SDimitry Andric constexpr bool // constexpr in C++20 1150b57cec5SDimitry Andric equal(InputIterator1 first1, InputIterator1 last1, 1160b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2); // **C++14** 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 1190b57cec5SDimitry Andric constexpr bool // constexpr in C++20 1200b57cec5SDimitry Andric equal(InputIterator1 first1, InputIterator1 last1, 1210b57cec5SDimitry Andric InputIterator2 first2, BinaryPredicate pred); 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 1240b57cec5SDimitry Andric constexpr bool // constexpr in C++20 1250b57cec5SDimitry Andric equal(InputIterator1 first1, InputIterator1 last1, 1260b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, 1270b57cec5SDimitry Andric BinaryPredicate pred); // **C++14** 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andrictemplate<class ForwardIterator1, class ForwardIterator2> 1300b57cec5SDimitry Andric constexpr bool // constexpr in C++20 1310b57cec5SDimitry Andric is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 1320b57cec5SDimitry Andric ForwardIterator2 first2); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andrictemplate<class ForwardIterator1, class ForwardIterator2> 1350b57cec5SDimitry Andric constexpr bool // constexpr in C++20 1360b57cec5SDimitry Andric is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 1370b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2); // **C++14** 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andrictemplate<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 1400b57cec5SDimitry Andric constexpr bool // constexpr in C++20 1410b57cec5SDimitry Andric is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 1420b57cec5SDimitry Andric ForwardIterator2 first2, BinaryPredicate pred); 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andrictemplate<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 1450b57cec5SDimitry Andric constexpr bool // constexpr in C++20 1460b57cec5SDimitry Andric is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 1470b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2, 1480b57cec5SDimitry Andric BinaryPredicate pred); // **C++14** 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2> 1510b57cec5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 1520b57cec5SDimitry Andric search(ForwardIterator1 first1, ForwardIterator1 last1, 1530b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2); 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 1560b57cec5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 1570b57cec5SDimitry Andric search(ForwardIterator1 first1, ForwardIterator1 last1, 1580b57cec5SDimitry Andric ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size, class T> 1610b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 1620b57cec5SDimitry Andric search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value); 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size, class T, class BinaryPredicate> 1650b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 1660b57cec5SDimitry Andric search_n(ForwardIterator first, ForwardIterator last, 1670b57cec5SDimitry Andric Size count, const T& value, BinaryPredicate pred); 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator> 170*480093f4SDimitry Andric constexpr OutputIterator // constexpr in C++20 1710b57cec5SDimitry Andric copy(InputIterator first, InputIterator last, OutputIterator result); 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andrictemplate<class InputIterator, class OutputIterator, class Predicate> 174*480093f4SDimitry Andric constexpr OutputIterator // constexpr in C++20 1750b57cec5SDimitry Andric copy_if(InputIterator first, InputIterator last, 1760b57cec5SDimitry Andric OutputIterator result, Predicate pred); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andrictemplate<class InputIterator, class Size, class OutputIterator> 179*480093f4SDimitry Andric constexpr OutputIterator // constexpr in C++20 1800b57cec5SDimitry Andric copy_n(InputIterator first, Size n, OutputIterator result); 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andrictemplate <class BidirectionalIterator1, class BidirectionalIterator2> 183*480093f4SDimitry Andric constexpr BidirectionalIterator2 // constexpr in C++20 1840b57cec5SDimitry Andric copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, 1850b57cec5SDimitry Andric BidirectionalIterator2 result); 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2> 1880b57cec5SDimitry Andric ForwardIterator2 1890b57cec5SDimitry Andric swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andrictemplate <class ForwardIterator1, class ForwardIterator2> 1920b57cec5SDimitry Andric void 1930b57cec5SDimitry Andric iter_swap(ForwardIterator1 a, ForwardIterator2 b); 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class UnaryOperation> 1960b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 1970b57cec5SDimitry Andric transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op); 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation> 2000b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2010b57cec5SDimitry Andric transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, 2020b57cec5SDimitry Andric OutputIterator result, BinaryOperation binary_op); 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 2050b57cec5SDimitry Andric constexpr void // constexpr in C++20 2060b57cec5SDimitry Andric replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andrictemplate <class ForwardIterator, class Predicate, class T> 2090b57cec5SDimitry Andric constexpr void // constexpr in C++20 2100b57cec5SDimitry Andric replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value); 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class T> 2130b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2140b57cec5SDimitry Andric replace_copy(InputIterator first, InputIterator last, OutputIterator result, 2150b57cec5SDimitry Andric const T& old_value, const T& new_value); 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class Predicate, class T> 2180b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2190b57cec5SDimitry Andric replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value); 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 2220b57cec5SDimitry Andric constexpr void // constexpr in C++20 2230b57cec5SDimitry Andric fill(ForwardIterator first, ForwardIterator last, const T& value); 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andrictemplate <class OutputIterator, class Size, class T> 2260b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2270b57cec5SDimitry Andric fill_n(OutputIterator first, Size n, const T& value); 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andrictemplate <class ForwardIterator, class Generator> 2300b57cec5SDimitry Andric constexpr void // constexpr in C++20 2310b57cec5SDimitry Andric generate(ForwardIterator first, ForwardIterator last, Generator gen); 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andrictemplate <class OutputIterator, class Size, class Generator> 2340b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2350b57cec5SDimitry Andric generate_n(OutputIterator first, Size n, Generator gen); 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 2380b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 2390b57cec5SDimitry Andric remove(ForwardIterator first, ForwardIterator last, const T& value); 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andrictemplate <class ForwardIterator, class Predicate> 2420b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 2430b57cec5SDimitry Andric remove_if(ForwardIterator first, ForwardIterator last, Predicate pred); 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class T> 2460b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2470b57cec5SDimitry Andric remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value); 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class Predicate> 2500b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2510b57cec5SDimitry Andric remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andrictemplate <class ForwardIterator> 2540b57cec5SDimitry Andric ForwardIterator 2550b57cec5SDimitry Andric unique(ForwardIterator first, ForwardIterator last); 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andrictemplate <class ForwardIterator, class BinaryPredicate> 2580b57cec5SDimitry Andric ForwardIterator 2590b57cec5SDimitry Andric unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator> 2620b57cec5SDimitry Andric OutputIterator 2630b57cec5SDimitry Andric unique_copy(InputIterator first, InputIterator last, OutputIterator result); 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator, class BinaryPredicate> 2660b57cec5SDimitry Andric OutputIterator 2670b57cec5SDimitry Andric unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andrictemplate <class BidirectionalIterator> 2700b57cec5SDimitry Andric void 2710b57cec5SDimitry Andric reverse(BidirectionalIterator first, BidirectionalIterator last); 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andrictemplate <class BidirectionalIterator, class OutputIterator> 2740b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2750b57cec5SDimitry Andric reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result); 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andrictemplate <class ForwardIterator> 2780b57cec5SDimitry Andric ForwardIterator 2790b57cec5SDimitry Andric rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last); 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andrictemplate <class ForwardIterator, class OutputIterator> 2820b57cec5SDimitry Andric OutputIterator 2830b57cec5SDimitry Andric rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result); 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 2860b57cec5SDimitry Andric void 2870b57cec5SDimitry Andric random_shuffle(RandomAccessIterator first, RandomAccessIterator last); // deprecated in C++14, removed in C++17 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class RandomNumberGenerator> 2900b57cec5SDimitry Andric void 2910b57cec5SDimitry Andric random_shuffle(RandomAccessIterator first, RandomAccessIterator last, 2920b57cec5SDimitry Andric RandomNumberGenerator& rand); // deprecated in C++14, removed in C++17 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andrictemplate<class PopulationIterator, class SampleIterator, 2950b57cec5SDimitry Andric class Distance, class UniformRandomBitGenerator> 2960b57cec5SDimitry Andric SampleIterator sample(PopulationIterator first, PopulationIterator last, 2970b57cec5SDimitry Andric SampleIterator out, Distance n, 2980b57cec5SDimitry Andric UniformRandomBitGenerator&& g); // C++17 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andrictemplate<class RandomAccessIterator, class UniformRandomNumberGenerator> 3010b57cec5SDimitry Andric void shuffle(RandomAccessIterator first, RandomAccessIterator last, 3020b57cec5SDimitry Andric UniformRandomNumberGenerator&& g); 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andrictemplate <class InputIterator, class Predicate> 3050b57cec5SDimitry Andric constexpr bool // constexpr in C++20 3060b57cec5SDimitry Andric is_partitioned(InputIterator first, InputIterator last, Predicate pred); 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andrictemplate <class ForwardIterator, class Predicate> 3090b57cec5SDimitry Andric ForwardIterator 3100b57cec5SDimitry Andric partition(ForwardIterator first, ForwardIterator last, Predicate pred); 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andrictemplate <class InputIterator, class OutputIterator1, 3130b57cec5SDimitry Andric class OutputIterator2, class Predicate> 3140b57cec5SDimitry Andric constexpr pair<OutputIterator1, OutputIterator2> // constexpr in C++20 3150b57cec5SDimitry Andric partition_copy(InputIterator first, InputIterator last, 3160b57cec5SDimitry Andric OutputIterator1 out_true, OutputIterator2 out_false, 3170b57cec5SDimitry Andric Predicate pred); 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andrictemplate <class ForwardIterator, class Predicate> 3200b57cec5SDimitry Andric ForwardIterator 3210b57cec5SDimitry Andric stable_partition(ForwardIterator first, ForwardIterator last, Predicate pred); 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andrictemplate<class ForwardIterator, class Predicate> 3240b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3250b57cec5SDimitry Andric partition_point(ForwardIterator first, ForwardIterator last, Predicate pred); 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andrictemplate <class ForwardIterator> 3280b57cec5SDimitry Andric constexpr bool // constexpr in C++20 3290b57cec5SDimitry Andric is_sorted(ForwardIterator first, ForwardIterator last); 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andrictemplate <class ForwardIterator, class Compare> 3320b57cec5SDimitry Andric bool 3330b57cec5SDimitry Andric is_sorted(ForwardIterator first, ForwardIterator last, Compare comp); 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andrictemplate<class ForwardIterator> 3360b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3370b57cec5SDimitry Andric is_sorted_until(ForwardIterator first, ForwardIterator last); 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andrictemplate <class ForwardIterator, class Compare> 3400b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3410b57cec5SDimitry Andric is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp); 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 3440b57cec5SDimitry Andric void 3450b57cec5SDimitry Andric sort(RandomAccessIterator first, RandomAccessIterator last); 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 3480b57cec5SDimitry Andric void 3490b57cec5SDimitry Andric sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 3520b57cec5SDimitry Andric void 3530b57cec5SDimitry Andric stable_sort(RandomAccessIterator first, RandomAccessIterator last); 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 3560b57cec5SDimitry Andric void 3570b57cec5SDimitry Andric stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 3600b57cec5SDimitry Andric void 3610b57cec5SDimitry Andric partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 3640b57cec5SDimitry Andric void 3650b57cec5SDimitry Andric partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andrictemplate <class InputIterator, class RandomAccessIterator> 3680b57cec5SDimitry Andric RandomAccessIterator 3690b57cec5SDimitry Andric partial_sort_copy(InputIterator first, InputIterator last, 3700b57cec5SDimitry Andric RandomAccessIterator result_first, RandomAccessIterator result_last); 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andrictemplate <class InputIterator, class RandomAccessIterator, class Compare> 3730b57cec5SDimitry Andric RandomAccessIterator 3740b57cec5SDimitry Andric partial_sort_copy(InputIterator first, InputIterator last, 3750b57cec5SDimitry Andric RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp); 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 3780b57cec5SDimitry Andric void 3790b57cec5SDimitry Andric nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 3820b57cec5SDimitry Andric void 3830b57cec5SDimitry Andric nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 3860b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3870b57cec5SDimitry Andric lower_bound(ForwardIterator first, ForwardIterator last, const T& value); 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andrictemplate <class ForwardIterator, class T, class Compare> 3900b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3910b57cec5SDimitry Andric lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 3940b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3950b57cec5SDimitry Andric upper_bound(ForwardIterator first, ForwardIterator last, const T& value); 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andrictemplate <class ForwardIterator, class T, class Compare> 3980b57cec5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3990b57cec5SDimitry Andric upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 4020b57cec5SDimitry Andric constexpr pair<ForwardIterator, ForwardIterator> // constexpr in C++20 4030b57cec5SDimitry Andric equal_range(ForwardIterator first, ForwardIterator last, const T& value); 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andrictemplate <class ForwardIterator, class T, class Compare> 4060b57cec5SDimitry Andric constexpr pair<ForwardIterator, ForwardIterator> // constexpr in C++20 4070b57cec5SDimitry Andric equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andrictemplate <class ForwardIterator, class T> 4100b57cec5SDimitry Andric constexpr bool // constexpr in C++20 4110b57cec5SDimitry Andric binary_search(ForwardIterator first, ForwardIterator last, const T& value); 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andrictemplate <class ForwardIterator, class T, class Compare> 4140b57cec5SDimitry Andric constexpr bool // constexpr in C++20 4150b57cec5SDimitry Andric binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator> 4180b57cec5SDimitry Andric OutputIterator 4190b57cec5SDimitry Andric merge(InputIterator1 first1, InputIterator1 last1, 4200b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result); 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 4230b57cec5SDimitry Andric OutputIterator 4240b57cec5SDimitry Andric merge(InputIterator1 first1, InputIterator1 last1, 4250b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andrictemplate <class BidirectionalIterator> 4280b57cec5SDimitry Andric void 4290b57cec5SDimitry Andric inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andrictemplate <class BidirectionalIterator, class Compare> 4320b57cec5SDimitry Andric void 4330b57cec5SDimitry Andric inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 4360b57cec5SDimitry Andric constexpr bool // constexpr in C++20 4370b57cec5SDimitry Andric includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class Compare> 4400b57cec5SDimitry Andric constexpr bool // constexpr in C++20 4410b57cec5SDimitry Andric includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator> 4440b57cec5SDimitry Andric OutputIterator 4450b57cec5SDimitry Andric set_union(InputIterator1 first1, InputIterator1 last1, 4460b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result); 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 4490b57cec5SDimitry Andric OutputIterator 4500b57cec5SDimitry Andric set_union(InputIterator1 first1, InputIterator1 last1, 4510b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator> 4540b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 4550b57cec5SDimitry Andric set_intersection(InputIterator1 first1, InputIterator1 last1, 4560b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result); 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 4590b57cec5SDimitry Andric constexpr OutputIterator // constexpr in C++20 4600b57cec5SDimitry Andric set_intersection(InputIterator1 first1, InputIterator1 last1, 4610b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator> 4640b57cec5SDimitry Andric OutputIterator 4650b57cec5SDimitry Andric set_difference(InputIterator1 first1, InputIterator1 last1, 4660b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result); 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 4690b57cec5SDimitry Andric OutputIterator 4700b57cec5SDimitry Andric set_difference(InputIterator1 first1, InputIterator1 last1, 4710b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator> 4740b57cec5SDimitry Andric OutputIterator 4750b57cec5SDimitry Andric set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, 4760b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result); 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 4790b57cec5SDimitry Andric OutputIterator 4800b57cec5SDimitry Andric set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, 4810b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 4840b57cec5SDimitry Andric void 4850b57cec5SDimitry Andric push_heap(RandomAccessIterator first, RandomAccessIterator last); 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 4880b57cec5SDimitry Andric void 4890b57cec5SDimitry Andric push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 4920b57cec5SDimitry Andric void 4930b57cec5SDimitry Andric pop_heap(RandomAccessIterator first, RandomAccessIterator last); 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 4960b57cec5SDimitry Andric void 4970b57cec5SDimitry Andric pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 5000b57cec5SDimitry Andric void 5010b57cec5SDimitry Andric make_heap(RandomAccessIterator first, RandomAccessIterator last); 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 5040b57cec5SDimitry Andric void 5050b57cec5SDimitry Andric make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 5080b57cec5SDimitry Andric void 5090b57cec5SDimitry Andric sort_heap(RandomAccessIterator first, RandomAccessIterator last); 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 5120b57cec5SDimitry Andric void 5130b57cec5SDimitry Andric sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 5160b57cec5SDimitry Andric constexpr bool // constexpr in C++20 5170b57cec5SDimitry Andric is_heap(RandomAccessIterator first, RandomAccessiterator last); 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 5200b57cec5SDimitry Andric constexpr bool // constexpr in C++20 5210b57cec5SDimitry Andric is_heap(RandomAccessIterator first, RandomAccessiterator last, Compare comp); 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andrictemplate <class RandomAccessIterator> 5240b57cec5SDimitry Andric constexpr RandomAccessIterator // constexpr in C++20 5250b57cec5SDimitry Andric is_heap_until(RandomAccessIterator first, RandomAccessiterator last); 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andrictemplate <class RandomAccessIterator, class Compare> 5280b57cec5SDimitry Andric constexpr RandomAccessIterator // constexpr in C++20 5290b57cec5SDimitry Andric is_heap_until(RandomAccessIterator first, RandomAccessiterator last, Compare comp); 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andrictemplate <class ForwardIterator> 5320b57cec5SDimitry Andric ForwardIterator 5330b57cec5SDimitry Andric min_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andrictemplate <class ForwardIterator, class Compare> 5360b57cec5SDimitry Andric ForwardIterator 5370b57cec5SDimitry Andric min_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andrictemplate <class T> 5400b57cec5SDimitry Andric const T& 5410b57cec5SDimitry Andric min(const T& a, const T& b); // constexpr in C++14 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andrictemplate <class T, class Compare> 5440b57cec5SDimitry Andric const T& 5450b57cec5SDimitry Andric min(const T& a, const T& b, Compare comp); // constexpr in C++14 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andrictemplate<class T> 5480b57cec5SDimitry Andric T 5490b57cec5SDimitry Andric min(initializer_list<T> t); // constexpr in C++14 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andrictemplate<class T, class Compare> 5520b57cec5SDimitry Andric T 5530b57cec5SDimitry Andric min(initializer_list<T> t, Compare comp); // constexpr in C++14 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andrictemplate<class T> 5560b57cec5SDimitry Andric constexpr const T& clamp( const T& v, const T& lo, const T& hi ); // C++17 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andrictemplate<class T, class Compare> 5590b57cec5SDimitry Andric constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp ); // C++17 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andrictemplate <class ForwardIterator> 5620b57cec5SDimitry Andric ForwardIterator 5630b57cec5SDimitry Andric max_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andrictemplate <class ForwardIterator, class Compare> 5660b57cec5SDimitry Andric ForwardIterator 5670b57cec5SDimitry Andric max_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andrictemplate <class T> 5700b57cec5SDimitry Andric const T& 5710b57cec5SDimitry Andric max(const T& a, const T& b); // constexpr in C++14 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andrictemplate <class T, class Compare> 5740b57cec5SDimitry Andric const T& 5750b57cec5SDimitry Andric max(const T& a, const T& b, Compare comp); // constexpr in C++14 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andrictemplate<class T> 5780b57cec5SDimitry Andric T 5790b57cec5SDimitry Andric max(initializer_list<T> t); // constexpr in C++14 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andrictemplate<class T, class Compare> 5820b57cec5SDimitry Andric T 5830b57cec5SDimitry Andric max(initializer_list<T> t, Compare comp); // constexpr in C++14 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andrictemplate<class ForwardIterator> 5860b57cec5SDimitry Andric pair<ForwardIterator, ForwardIterator> 5870b57cec5SDimitry Andric minmax_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andrictemplate<class ForwardIterator, class Compare> 5900b57cec5SDimitry Andric pair<ForwardIterator, ForwardIterator> 5910b57cec5SDimitry Andric minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andrictemplate<class T> 5940b57cec5SDimitry Andric pair<const T&, const T&> 5950b57cec5SDimitry Andric minmax(const T& a, const T& b); // constexpr in C++14 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andrictemplate<class T, class Compare> 5980b57cec5SDimitry Andric pair<const T&, const T&> 5990b57cec5SDimitry Andric minmax(const T& a, const T& b, Compare comp); // constexpr in C++14 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andrictemplate<class T> 6020b57cec5SDimitry Andric pair<T, T> 6030b57cec5SDimitry Andric minmax(initializer_list<T> t); // constexpr in C++14 6040b57cec5SDimitry Andric 6050b57cec5SDimitry Andrictemplate<class T, class Compare> 6060b57cec5SDimitry Andric pair<T, T> 6070b57cec5SDimitry Andric minmax(initializer_list<T> t, Compare comp); // constexpr in C++14 6080b57cec5SDimitry Andric 6090b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2> 6100b57cec5SDimitry Andric constexpr bool // constexpr in C++20 6110b57cec5SDimitry Andric lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andrictemplate <class InputIterator1, class InputIterator2, class Compare> 6140b57cec5SDimitry Andric constexpr bool // constexpr in C++20 6150b57cec5SDimitry Andric lexicographical_compare(InputIterator1 first1, InputIterator1 last1, 6160b57cec5SDimitry Andric InputIterator2 first2, InputIterator2 last2, Compare comp); 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andrictemplate <class BidirectionalIterator> 6190b57cec5SDimitry Andric bool 6200b57cec5SDimitry Andric next_permutation(BidirectionalIterator first, BidirectionalIterator last); 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andrictemplate <class BidirectionalIterator, class Compare> 6230b57cec5SDimitry Andric bool 6240b57cec5SDimitry Andric next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); 6250b57cec5SDimitry Andric 6260b57cec5SDimitry Andrictemplate <class BidirectionalIterator> 6270b57cec5SDimitry Andric bool 6280b57cec5SDimitry Andric prev_permutation(BidirectionalIterator first, BidirectionalIterator last); 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andrictemplate <class BidirectionalIterator, class Compare> 6310b57cec5SDimitry Andric bool 6320b57cec5SDimitry Andric prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); 6330b57cec5SDimitry Andric 6340b57cec5SDimitry Andric} // std 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric*/ 6370b57cec5SDimitry Andric 6380b57cec5SDimitry Andric#include <__config> 6390b57cec5SDimitry Andric#include <initializer_list> 6400b57cec5SDimitry Andric#include <type_traits> 6410b57cec5SDimitry Andric#include <cstring> 6420b57cec5SDimitry Andric#include <utility> // needed to provide swap_ranges. 6430b57cec5SDimitry Andric#include <memory> 6440b57cec5SDimitry Andric#include <functional> 6450b57cec5SDimitry Andric#include <iterator> 6460b57cec5SDimitry Andric#include <cstddef> 6470b57cec5SDimitry Andric#include <bit> 6480b57cec5SDimitry Andric#include <version> 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric#include <__debug> 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 6530b57cec5SDimitry Andric#pragma GCC system_header 6540b57cec5SDimitry Andric#endif 6550b57cec5SDimitry Andric 6560b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 6570b57cec5SDimitry Andric#include <__undef_macros> 6580b57cec5SDimitry Andric 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric// I'd like to replace these with _VSTD::equal_to<void>, but can't because: 6630b57cec5SDimitry Andric// * That only works with C++14 and later, and 6640b57cec5SDimitry Andric// * We haven't included <functional> here. 6650b57cec5SDimitry Andrictemplate <class _T1, class _T2 = _T1> 6660b57cec5SDimitry Andricstruct __equal_to 6670b57cec5SDimitry Andric{ 6680b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 6690b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;} 6700b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;} 6710b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;} 6720b57cec5SDimitry Andric}; 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andrictemplate <class _T1> 6750b57cec5SDimitry Andricstruct __equal_to<_T1, _T1> 6760b57cec5SDimitry Andric{ 6770b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 6780b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 6790b57cec5SDimitry Andric}; 6800b57cec5SDimitry Andric 6810b57cec5SDimitry Andrictemplate <class _T1> 6820b57cec5SDimitry Andricstruct __equal_to<const _T1, _T1> 6830b57cec5SDimitry Andric{ 6840b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 6850b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 6860b57cec5SDimitry Andric}; 6870b57cec5SDimitry Andric 6880b57cec5SDimitry Andrictemplate <class _T1> 6890b57cec5SDimitry Andricstruct __equal_to<_T1, const _T1> 6900b57cec5SDimitry Andric{ 6910b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 6920b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 6930b57cec5SDimitry Andric}; 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andrictemplate <class _T1, class _T2 = _T1> 6960b57cec5SDimitry Andricstruct __less 6970b57cec5SDimitry Andric{ 6980b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 6990b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 7000b57cec5SDimitry Andric 7010b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7020b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;} 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7050b57cec5SDimitry Andric bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;} 7060b57cec5SDimitry Andric 7070b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7080b57cec5SDimitry Andric bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;} 7090b57cec5SDimitry Andric}; 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andrictemplate <class _T1> 7120b57cec5SDimitry Andricstruct __less<_T1, _T1> 7130b57cec5SDimitry Andric{ 7140b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7150b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 7160b57cec5SDimitry Andric}; 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andrictemplate <class _T1> 7190b57cec5SDimitry Andricstruct __less<const _T1, _T1> 7200b57cec5SDimitry Andric{ 7210b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7220b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 7230b57cec5SDimitry Andric}; 7240b57cec5SDimitry Andric 7250b57cec5SDimitry Andrictemplate <class _T1> 7260b57cec5SDimitry Andricstruct __less<_T1, const _T1> 7270b57cec5SDimitry Andric{ 7280b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7290b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 7300b57cec5SDimitry Andric}; 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andrictemplate <class _Predicate> 7330b57cec5SDimitry Andricclass __invert // invert the sense of a comparison 7340b57cec5SDimitry Andric{ 7350b57cec5SDimitry Andricprivate: 7360b57cec5SDimitry Andric _Predicate __p_; 7370b57cec5SDimitry Andricpublic: 7380b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __invert() {} 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 7410b57cec5SDimitry Andric explicit __invert(_Predicate __p) : __p_(__p) {} 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andric template <class _T1> 7440b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 7450b57cec5SDimitry Andric bool operator()(const _T1& __x) {return !__p_(__x);} 7460b57cec5SDimitry Andric 7470b57cec5SDimitry Andric template <class _T1, class _T2> 7480b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 7490b57cec5SDimitry Andric bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} 7500b57cec5SDimitry Andric}; 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric// Perform division by two quickly for positive integers (llvm.org/PR39129) 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andrictemplate <typename _Integral> 7550b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 7560b57cec5SDimitry Andrictypename enable_if 7570b57cec5SDimitry Andric< 7580b57cec5SDimitry Andric is_integral<_Integral>::value, 7590b57cec5SDimitry Andric _Integral 7600b57cec5SDimitry Andric>::type 7610b57cec5SDimitry Andric__half_positive(_Integral __value) 7620b57cec5SDimitry Andric{ 7630b57cec5SDimitry Andric return static_cast<_Integral>(static_cast<typename make_unsigned<_Integral>::type>(__value) / 2); 7640b57cec5SDimitry Andric} 7650b57cec5SDimitry Andric 7660b57cec5SDimitry Andrictemplate <typename _Tp> 7670b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 7680b57cec5SDimitry Andrictypename enable_if 7690b57cec5SDimitry Andric< 7700b57cec5SDimitry Andric !is_integral<_Tp>::value, 7710b57cec5SDimitry Andric _Tp 7720b57cec5SDimitry Andric>::type 7730b57cec5SDimitry Andric__half_positive(_Tp __value) 7740b57cec5SDimitry Andric{ 7750b57cec5SDimitry Andric return __value / 2; 7760b57cec5SDimitry Andric} 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric#ifdef _LIBCPP_DEBUG 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andrictemplate <class _Compare> 7810b57cec5SDimitry Andricstruct __debug_less 7820b57cec5SDimitry Andric{ 7830b57cec5SDimitry Andric _Compare &__comp_; 7840b57cec5SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 7850b57cec5SDimitry Andric __debug_less(_Compare& __c) : __comp_(__c) {} 7860b57cec5SDimitry Andric 7870b57cec5SDimitry Andric template <class _Tp, class _Up> 7880b57cec5SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 7890b57cec5SDimitry Andric bool operator()(const _Tp& __x, const _Up& __y) 7900b57cec5SDimitry Andric { 7910b57cec5SDimitry Andric bool __r = __comp_(__x, __y); 7920b57cec5SDimitry Andric if (__r) 7930b57cec5SDimitry Andric __do_compare_assert(0, __y, __x); 7940b57cec5SDimitry Andric return __r; 7950b57cec5SDimitry Andric } 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric template <class _Tp, class _Up> 7980b57cec5SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 7990b57cec5SDimitry Andric bool operator()(_Tp& __x, _Up& __y) 8000b57cec5SDimitry Andric { 8010b57cec5SDimitry Andric bool __r = __comp_(__x, __y); 8020b57cec5SDimitry Andric if (__r) 8030b57cec5SDimitry Andric __do_compare_assert(0, __y, __x); 8040b57cec5SDimitry Andric return __r; 8050b57cec5SDimitry Andric } 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric template <class _LHS, class _RHS> 8080b57cec5SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 8090b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 8100b57cec5SDimitry Andric decltype((void)_VSTD::declval<_Compare&>()( 8110b57cec5SDimitry Andric _VSTD::declval<_LHS &>(), _VSTD::declval<_RHS &>())) 8120b57cec5SDimitry Andric __do_compare_assert(int, _LHS & __l, _RHS & __r) { 8130b57cec5SDimitry Andric _LIBCPP_ASSERT(!__comp_(__l, __r), 8140b57cec5SDimitry Andric "Comparator does not induce a strict weak ordering"); 8150b57cec5SDimitry Andric } 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andric template <class _LHS, class _RHS> 8180b57cec5SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 8190b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 8200b57cec5SDimitry Andric void __do_compare_assert(long, _LHS &, _RHS &) {} 8210b57cec5SDimitry Andric}; 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric#endif // _LIBCPP_DEBUG 8240b57cec5SDimitry Andric 8250b57cec5SDimitry Andrictemplate <class _Comp> 8260b57cec5SDimitry Andricstruct __comp_ref_type { 8270b57cec5SDimitry Andric // Pass the comparator by lvalue reference. Or in debug mode, using a 8280b57cec5SDimitry Andric // debugging wrapper that stores a reference. 8290b57cec5SDimitry Andric#ifndef _LIBCPP_DEBUG 8300b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Comp>::type type; 8310b57cec5SDimitry Andric#else 8320b57cec5SDimitry Andric typedef __debug_less<_Comp> type; 8330b57cec5SDimitry Andric#endif 8340b57cec5SDimitry Andric}; 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric// all_of 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 8390b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 8400b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 8410b57cec5SDimitry Andricbool 8420b57cec5SDimitry Andricall_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 8430b57cec5SDimitry Andric{ 8440b57cec5SDimitry Andric for (; __first != __last; ++__first) 8450b57cec5SDimitry Andric if (!__pred(*__first)) 8460b57cec5SDimitry Andric return false; 8470b57cec5SDimitry Andric return true; 8480b57cec5SDimitry Andric} 8490b57cec5SDimitry Andric 8500b57cec5SDimitry Andric// any_of 8510b57cec5SDimitry Andric 8520b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 8530b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 8540b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 8550b57cec5SDimitry Andricbool 8560b57cec5SDimitry Andricany_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 8570b57cec5SDimitry Andric{ 8580b57cec5SDimitry Andric for (; __first != __last; ++__first) 8590b57cec5SDimitry Andric if (__pred(*__first)) 8600b57cec5SDimitry Andric return true; 8610b57cec5SDimitry Andric return false; 8620b57cec5SDimitry Andric} 8630b57cec5SDimitry Andric 8640b57cec5SDimitry Andric// none_of 8650b57cec5SDimitry Andric 8660b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 8670b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 8680b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 8690b57cec5SDimitry Andricbool 8700b57cec5SDimitry Andricnone_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 8710b57cec5SDimitry Andric{ 8720b57cec5SDimitry Andric for (; __first != __last; ++__first) 8730b57cec5SDimitry Andric if (__pred(*__first)) 8740b57cec5SDimitry Andric return false; 8750b57cec5SDimitry Andric return true; 8760b57cec5SDimitry Andric} 8770b57cec5SDimitry Andric 8780b57cec5SDimitry Andric// for_each 8790b57cec5SDimitry Andric 8800b57cec5SDimitry Andrictemplate <class _InputIterator, class _Function> 8810b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 8820b57cec5SDimitry Andric_Function 8830b57cec5SDimitry Andricfor_each(_InputIterator __first, _InputIterator __last, _Function __f) 8840b57cec5SDimitry Andric{ 8850b57cec5SDimitry Andric for (; __first != __last; ++__first) 8860b57cec5SDimitry Andric __f(*__first); 8870b57cec5SDimitry Andric return __f; 8880b57cec5SDimitry Andric} 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 8910b57cec5SDimitry Andric// for_each_n 8920b57cec5SDimitry Andric 8930b57cec5SDimitry Andrictemplate <class _InputIterator, class _Size, class _Function> 8940b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 8950b57cec5SDimitry Andric_InputIterator 8960b57cec5SDimitry Andricfor_each_n(_InputIterator __first, _Size __orig_n, _Function __f) 8970b57cec5SDimitry Andric{ 8980b57cec5SDimitry Andric typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; 8990b57cec5SDimitry Andric _IntegralSize __n = __orig_n; 9000b57cec5SDimitry Andric while (__n > 0) 9010b57cec5SDimitry Andric { 9020b57cec5SDimitry Andric __f(*__first); 9030b57cec5SDimitry Andric ++__first; 9040b57cec5SDimitry Andric --__n; 9050b57cec5SDimitry Andric } 9060b57cec5SDimitry Andric return __first; 9070b57cec5SDimitry Andric} 9080b57cec5SDimitry Andric#endif 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andric// find 9110b57cec5SDimitry Andric 9120b57cec5SDimitry Andrictemplate <class _InputIterator, class _Tp> 9130b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 9140b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 9150b57cec5SDimitry Andric_InputIterator 9160b57cec5SDimitry Andricfind(_InputIterator __first, _InputIterator __last, const _Tp& __value_) 9170b57cec5SDimitry Andric{ 9180b57cec5SDimitry Andric for (; __first != __last; ++__first) 9190b57cec5SDimitry Andric if (*__first == __value_) 9200b57cec5SDimitry Andric break; 9210b57cec5SDimitry Andric return __first; 9220b57cec5SDimitry Andric} 9230b57cec5SDimitry Andric 9240b57cec5SDimitry Andric// find_if 9250b57cec5SDimitry Andric 9260b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 9270b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 9280b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 9290b57cec5SDimitry Andric_InputIterator 9300b57cec5SDimitry Andricfind_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) 9310b57cec5SDimitry Andric{ 9320b57cec5SDimitry Andric for (; __first != __last; ++__first) 9330b57cec5SDimitry Andric if (__pred(*__first)) 9340b57cec5SDimitry Andric break; 9350b57cec5SDimitry Andric return __first; 9360b57cec5SDimitry Andric} 9370b57cec5SDimitry Andric 9380b57cec5SDimitry Andric// find_if_not 9390b57cec5SDimitry Andric 9400b57cec5SDimitry Andrictemplate<class _InputIterator, class _Predicate> 9410b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 9420b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 9430b57cec5SDimitry Andric_InputIterator 9440b57cec5SDimitry Andricfind_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) 9450b57cec5SDimitry Andric{ 9460b57cec5SDimitry Andric for (; __first != __last; ++__first) 9470b57cec5SDimitry Andric if (!__pred(*__first)) 9480b57cec5SDimitry Andric break; 9490b57cec5SDimitry Andric return __first; 9500b57cec5SDimitry Andric} 9510b57cec5SDimitry Andric 9520b57cec5SDimitry Andric// find_end 9530b57cec5SDimitry Andric 9540b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> 9550b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 9560b57cec5SDimitry Andric__find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 9570b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, 9580b57cec5SDimitry Andric forward_iterator_tag, forward_iterator_tag) 9590b57cec5SDimitry Andric{ 9600b57cec5SDimitry Andric // modeled after search algorithm 9610b57cec5SDimitry Andric _ForwardIterator1 __r = __last1; // __last1 is the "default" answer 9620b57cec5SDimitry Andric if (__first2 == __last2) 9630b57cec5SDimitry Andric return __r; 9640b57cec5SDimitry Andric while (true) 9650b57cec5SDimitry Andric { 9660b57cec5SDimitry Andric while (true) 9670b57cec5SDimitry Andric { 9680b57cec5SDimitry Andric if (__first1 == __last1) // if source exhausted return last correct answer 9690b57cec5SDimitry Andric return __r; // (or __last1 if never found) 9700b57cec5SDimitry Andric if (__pred(*__first1, *__first2)) 9710b57cec5SDimitry Andric break; 9720b57cec5SDimitry Andric ++__first1; 9730b57cec5SDimitry Andric } 9740b57cec5SDimitry Andric // *__first1 matches *__first2, now match elements after here 9750b57cec5SDimitry Andric _ForwardIterator1 __m1 = __first1; 9760b57cec5SDimitry Andric _ForwardIterator2 __m2 = __first2; 9770b57cec5SDimitry Andric while (true) 9780b57cec5SDimitry Andric { 9790b57cec5SDimitry Andric if (++__m2 == __last2) 9800b57cec5SDimitry Andric { // Pattern exhaused, record answer and search for another one 9810b57cec5SDimitry Andric __r = __first1; 9820b57cec5SDimitry Andric ++__first1; 9830b57cec5SDimitry Andric break; 9840b57cec5SDimitry Andric } 9850b57cec5SDimitry Andric if (++__m1 == __last1) // Source exhausted, return last answer 9860b57cec5SDimitry Andric return __r; 9870b57cec5SDimitry Andric if (!__pred(*__m1, *__m2)) // mismatch, restart with a new __first 9880b57cec5SDimitry Andric { 9890b57cec5SDimitry Andric ++__first1; 9900b57cec5SDimitry Andric break; 9910b57cec5SDimitry Andric } // else there is a match, check next elements 9920b57cec5SDimitry Andric } 9930b57cec5SDimitry Andric } 9940b57cec5SDimitry Andric} 9950b57cec5SDimitry Andric 9960b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2> 9970b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 9980b57cec5SDimitry Andric__find_end(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, 9990b57cec5SDimitry Andric _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, _BinaryPredicate __pred, 10000b57cec5SDimitry Andric bidirectional_iterator_tag, bidirectional_iterator_tag) 10010b57cec5SDimitry Andric{ 10020b57cec5SDimitry Andric // modeled after search algorithm (in reverse) 10030b57cec5SDimitry Andric if (__first2 == __last2) 10040b57cec5SDimitry Andric return __last1; // Everything matches an empty sequence 10050b57cec5SDimitry Andric _BidirectionalIterator1 __l1 = __last1; 10060b57cec5SDimitry Andric _BidirectionalIterator2 __l2 = __last2; 10070b57cec5SDimitry Andric --__l2; 10080b57cec5SDimitry Andric while (true) 10090b57cec5SDimitry Andric { 10100b57cec5SDimitry Andric // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks 10110b57cec5SDimitry Andric while (true) 10120b57cec5SDimitry Andric { 10130b57cec5SDimitry Andric if (__first1 == __l1) // return __last1 if no element matches *__first2 10140b57cec5SDimitry Andric return __last1; 10150b57cec5SDimitry Andric if (__pred(*--__l1, *__l2)) 10160b57cec5SDimitry Andric break; 10170b57cec5SDimitry Andric } 10180b57cec5SDimitry Andric // *__l1 matches *__l2, now match elements before here 10190b57cec5SDimitry Andric _BidirectionalIterator1 __m1 = __l1; 10200b57cec5SDimitry Andric _BidirectionalIterator2 __m2 = __l2; 10210b57cec5SDimitry Andric while (true) 10220b57cec5SDimitry Andric { 10230b57cec5SDimitry Andric if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern) 10240b57cec5SDimitry Andric return __m1; 10250b57cec5SDimitry Andric if (__m1 == __first1) // Otherwise if source exhaused, pattern not found 10260b57cec5SDimitry Andric return __last1; 10270b57cec5SDimitry Andric if (!__pred(*--__m1, *--__m2)) // if there is a mismatch, restart with a new __l1 10280b57cec5SDimitry Andric { 10290b57cec5SDimitry Andric break; 10300b57cec5SDimitry Andric } // else there is a match, check next elements 10310b57cec5SDimitry Andric } 10320b57cec5SDimitry Andric } 10330b57cec5SDimitry Andric} 10340b57cec5SDimitry Andric 10350b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> 10360b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 10370b57cec5SDimitry Andric__find_end(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, 10380b57cec5SDimitry Andric _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, 10390b57cec5SDimitry Andric random_access_iterator_tag, random_access_iterator_tag) 10400b57cec5SDimitry Andric{ 10410b57cec5SDimitry Andric // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern 10420b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2; 10430b57cec5SDimitry Andric if (__len2 == 0) 10440b57cec5SDimitry Andric return __last1; 10450b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1; 10460b57cec5SDimitry Andric if (__len1 < __len2) 10470b57cec5SDimitry Andric return __last1; 10480b57cec5SDimitry Andric const _RandomAccessIterator1 __s = __first1 + (__len2 - 1); // End of pattern match can't go before here 10490b57cec5SDimitry Andric _RandomAccessIterator1 __l1 = __last1; 10500b57cec5SDimitry Andric _RandomAccessIterator2 __l2 = __last2; 10510b57cec5SDimitry Andric --__l2; 10520b57cec5SDimitry Andric while (true) 10530b57cec5SDimitry Andric { 10540b57cec5SDimitry Andric while (true) 10550b57cec5SDimitry Andric { 10560b57cec5SDimitry Andric if (__s == __l1) 10570b57cec5SDimitry Andric return __last1; 10580b57cec5SDimitry Andric if (__pred(*--__l1, *__l2)) 10590b57cec5SDimitry Andric break; 10600b57cec5SDimitry Andric } 10610b57cec5SDimitry Andric _RandomAccessIterator1 __m1 = __l1; 10620b57cec5SDimitry Andric _RandomAccessIterator2 __m2 = __l2; 10630b57cec5SDimitry Andric while (true) 10640b57cec5SDimitry Andric { 10650b57cec5SDimitry Andric if (__m2 == __first2) 10660b57cec5SDimitry Andric return __m1; 10670b57cec5SDimitry Andric // no need to check range on __m1 because __s guarantees we have enough source 10680b57cec5SDimitry Andric if (!__pred(*--__m1, *--__m2)) 10690b57cec5SDimitry Andric { 10700b57cec5SDimitry Andric break; 10710b57cec5SDimitry Andric } 10720b57cec5SDimitry Andric } 10730b57cec5SDimitry Andric } 10740b57cec5SDimitry Andric} 10750b57cec5SDimitry Andric 10760b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 10770b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 10780b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 10790b57cec5SDimitry Andric_ForwardIterator1 10800b57cec5SDimitry Andricfind_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 10810b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 10820b57cec5SDimitry Andric{ 10830b57cec5SDimitry Andric return _VSTD::__find_end<typename add_lvalue_reference<_BinaryPredicate>::type> 10840b57cec5SDimitry Andric (__first1, __last1, __first2, __last2, __pred, 10850b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator1>::iterator_category(), 10860b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator2>::iterator_category()); 10870b57cec5SDimitry Andric} 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2> 10900b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 10910b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 10920b57cec5SDimitry Andric_ForwardIterator1 10930b57cec5SDimitry Andricfind_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 10940b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2) 10950b57cec5SDimitry Andric{ 10960b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 10970b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 10980b57cec5SDimitry Andric return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 10990b57cec5SDimitry Andric} 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andric// find_first_of 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 11040b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1 11050b57cec5SDimitry Andric__find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 11060b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 11070b57cec5SDimitry Andric{ 11080b57cec5SDimitry Andric for (; __first1 != __last1; ++__first1) 11090b57cec5SDimitry Andric for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) 11100b57cec5SDimitry Andric if (__pred(*__first1, *__j)) 11110b57cec5SDimitry Andric return __first1; 11120b57cec5SDimitry Andric return __last1; 11130b57cec5SDimitry Andric} 11140b57cec5SDimitry Andric 11150b57cec5SDimitry Andric 11160b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 11170b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 11180b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11190b57cec5SDimitry Andric_ForwardIterator1 11200b57cec5SDimitry Andricfind_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 11210b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 11220b57cec5SDimitry Andric{ 11230b57cec5SDimitry Andric return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); 11240b57cec5SDimitry Andric} 11250b57cec5SDimitry Andric 11260b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2> 11270b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 11280b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11290b57cec5SDimitry Andric_ForwardIterator1 11300b57cec5SDimitry Andricfind_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 11310b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2) 11320b57cec5SDimitry Andric{ 11330b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 11340b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 11350b57cec5SDimitry Andric return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 11360b57cec5SDimitry Andric} 11370b57cec5SDimitry Andric 11380b57cec5SDimitry Andric// adjacent_find 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _BinaryPredicate> 11410b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 11420b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11430b57cec5SDimitry Andric_ForwardIterator 11440b57cec5SDimitry Andricadjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) 11450b57cec5SDimitry Andric{ 11460b57cec5SDimitry Andric if (__first != __last) 11470b57cec5SDimitry Andric { 11480b57cec5SDimitry Andric _ForwardIterator __i = __first; 11490b57cec5SDimitry Andric while (++__i != __last) 11500b57cec5SDimitry Andric { 11510b57cec5SDimitry Andric if (__pred(*__first, *__i)) 11520b57cec5SDimitry Andric return __first; 11530b57cec5SDimitry Andric __first = __i; 11540b57cec5SDimitry Andric } 11550b57cec5SDimitry Andric } 11560b57cec5SDimitry Andric return __last; 11570b57cec5SDimitry Andric} 11580b57cec5SDimitry Andric 11590b57cec5SDimitry Andrictemplate <class _ForwardIterator> 11600b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 11610b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11620b57cec5SDimitry Andric_ForwardIterator 11630b57cec5SDimitry Andricadjacent_find(_ForwardIterator __first, _ForwardIterator __last) 11640b57cec5SDimitry Andric{ 11650b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type __v; 11660b57cec5SDimitry Andric return _VSTD::adjacent_find(__first, __last, __equal_to<__v>()); 11670b57cec5SDimitry Andric} 11680b57cec5SDimitry Andric 11690b57cec5SDimitry Andric// count 11700b57cec5SDimitry Andric 11710b57cec5SDimitry Andrictemplate <class _InputIterator, class _Tp> 11720b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 11730b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11740b57cec5SDimitry Andrictypename iterator_traits<_InputIterator>::difference_type 11750b57cec5SDimitry Andriccount(_InputIterator __first, _InputIterator __last, const _Tp& __value_) 11760b57cec5SDimitry Andric{ 11770b57cec5SDimitry Andric typename iterator_traits<_InputIterator>::difference_type __r(0); 11780b57cec5SDimitry Andric for (; __first != __last; ++__first) 11790b57cec5SDimitry Andric if (*__first == __value_) 11800b57cec5SDimitry Andric ++__r; 11810b57cec5SDimitry Andric return __r; 11820b57cec5SDimitry Andric} 11830b57cec5SDimitry Andric 11840b57cec5SDimitry Andric// count_if 11850b57cec5SDimitry Andric 11860b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 11870b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 11880b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11890b57cec5SDimitry Andrictypename iterator_traits<_InputIterator>::difference_type 11900b57cec5SDimitry Andriccount_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) 11910b57cec5SDimitry Andric{ 11920b57cec5SDimitry Andric typename iterator_traits<_InputIterator>::difference_type __r(0); 11930b57cec5SDimitry Andric for (; __first != __last; ++__first) 11940b57cec5SDimitry Andric if (__pred(*__first)) 11950b57cec5SDimitry Andric ++__r; 11960b57cec5SDimitry Andric return __r; 11970b57cec5SDimitry Andric} 11980b57cec5SDimitry Andric 11990b57cec5SDimitry Andric// mismatch 12000b57cec5SDimitry Andric 12010b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 12020b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 12030b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12040b57cec5SDimitry Andricpair<_InputIterator1, _InputIterator2> 12050b57cec5SDimitry Andricmismatch(_InputIterator1 __first1, _InputIterator1 __last1, 12060b57cec5SDimitry Andric _InputIterator2 __first2, _BinaryPredicate __pred) 12070b57cec5SDimitry Andric{ 12080b57cec5SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2) 12090b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 12100b57cec5SDimitry Andric break; 12110b57cec5SDimitry Andric return pair<_InputIterator1, _InputIterator2>(__first1, __first2); 12120b57cec5SDimitry Andric} 12130b57cec5SDimitry Andric 12140b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 12150b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 12160b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12170b57cec5SDimitry Andricpair<_InputIterator1, _InputIterator2> 12180b57cec5SDimitry Andricmismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) 12190b57cec5SDimitry Andric{ 12200b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type __v1; 12210b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator2>::value_type __v2; 12220b57cec5SDimitry Andric return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>()); 12230b57cec5SDimitry Andric} 12240b57cec5SDimitry Andric 12250b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11 12260b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 12270b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 12280b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12290b57cec5SDimitry Andricpair<_InputIterator1, _InputIterator2> 12300b57cec5SDimitry Andricmismatch(_InputIterator1 __first1, _InputIterator1 __last1, 12310b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, 12320b57cec5SDimitry Andric _BinaryPredicate __pred) 12330b57cec5SDimitry Andric{ 12340b57cec5SDimitry Andric for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) 12350b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 12360b57cec5SDimitry Andric break; 12370b57cec5SDimitry Andric return pair<_InputIterator1, _InputIterator2>(__first1, __first2); 12380b57cec5SDimitry Andric} 12390b57cec5SDimitry Andric 12400b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 12410b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 12420b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12430b57cec5SDimitry Andricpair<_InputIterator1, _InputIterator2> 12440b57cec5SDimitry Andricmismatch(_InputIterator1 __first1, _InputIterator1 __last1, 12450b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2) 12460b57cec5SDimitry Andric{ 12470b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type __v1; 12480b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator2>::value_type __v2; 12490b57cec5SDimitry Andric return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 12500b57cec5SDimitry Andric} 12510b57cec5SDimitry Andric#endif 12520b57cec5SDimitry Andric 12530b57cec5SDimitry Andric// equal 12540b57cec5SDimitry Andric 12550b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 12560b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 12570b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12580b57cec5SDimitry Andricbool 12590b57cec5SDimitry Andricequal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) 12600b57cec5SDimitry Andric{ 12610b57cec5SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2) 12620b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 12630b57cec5SDimitry Andric return false; 12640b57cec5SDimitry Andric return true; 12650b57cec5SDimitry Andric} 12660b57cec5SDimitry Andric 12670b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 12680b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 12690b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12700b57cec5SDimitry Andricbool 12710b57cec5SDimitry Andricequal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) 12720b57cec5SDimitry Andric{ 12730b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type __v1; 12740b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator2>::value_type __v2; 12750b57cec5SDimitry Andric return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>()); 12760b57cec5SDimitry Andric} 12770b57cec5SDimitry Andric 12780b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11 12790b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _InputIterator1, class _InputIterator2> 12800b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12810b57cec5SDimitry Andricbool 12820b57cec5SDimitry Andric__equal(_InputIterator1 __first1, _InputIterator1 __last1, 12830b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred, 12840b57cec5SDimitry Andric input_iterator_tag, input_iterator_tag ) 12850b57cec5SDimitry Andric{ 12860b57cec5SDimitry Andric for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) 12870b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 12880b57cec5SDimitry Andric return false; 12890b57cec5SDimitry Andric return __first1 == __last1 && __first2 == __last2; 12900b57cec5SDimitry Andric} 12910b57cec5SDimitry Andric 12920b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> 12930b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12940b57cec5SDimitry Andricbool 12950b57cec5SDimitry Andric__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, 12960b57cec5SDimitry Andric _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, 12970b57cec5SDimitry Andric random_access_iterator_tag, random_access_iterator_tag ) 12980b57cec5SDimitry Andric{ 12990b57cec5SDimitry Andric if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) 13000b57cec5SDimitry Andric return false; 13010b57cec5SDimitry Andric return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2, 13020b57cec5SDimitry Andric typename add_lvalue_reference<_BinaryPredicate>::type> 13030b57cec5SDimitry Andric (__first1, __last1, __first2, __pred ); 13040b57cec5SDimitry Andric} 13050b57cec5SDimitry Andric 13060b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 13070b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 13080b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 13090b57cec5SDimitry Andricbool 13100b57cec5SDimitry Andricequal(_InputIterator1 __first1, _InputIterator1 __last1, 13110b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred ) 13120b57cec5SDimitry Andric{ 13130b57cec5SDimitry Andric return _VSTD::__equal<typename add_lvalue_reference<_BinaryPredicate>::type> 13140b57cec5SDimitry Andric (__first1, __last1, __first2, __last2, __pred, 13150b57cec5SDimitry Andric typename iterator_traits<_InputIterator1>::iterator_category(), 13160b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::iterator_category()); 13170b57cec5SDimitry Andric} 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 13200b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 13210b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 13220b57cec5SDimitry Andricbool 13230b57cec5SDimitry Andricequal(_InputIterator1 __first1, _InputIterator1 __last1, 13240b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2) 13250b57cec5SDimitry Andric{ 13260b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type __v1; 13270b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator2>::value_type __v2; 13280b57cec5SDimitry Andric return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(), 13290b57cec5SDimitry Andric typename iterator_traits<_InputIterator1>::iterator_category(), 13300b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::iterator_category()); 13310b57cec5SDimitry Andric} 13320b57cec5SDimitry Andric#endif 13330b57cec5SDimitry Andric 13340b57cec5SDimitry Andric// is_permutation 13350b57cec5SDimitry Andric 13360b57cec5SDimitry Andrictemplate<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 13370b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool 13380b57cec5SDimitry Andricis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 13390b57cec5SDimitry Andric _ForwardIterator2 __first2, _BinaryPredicate __pred) 13400b57cec5SDimitry Andric{ 13410b57cec5SDimitry Andric// shorten sequences as much as possible by lopping of any equal prefix 13420b57cec5SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2) 13430b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 13440b57cec5SDimitry Andric break; 13450b57cec5SDimitry Andric if (__first1 == __last1) 13460b57cec5SDimitry Andric return true; 13470b57cec5SDimitry Andric 13480b57cec5SDimitry Andric// __first1 != __last1 && *__first1 != *__first2 13490b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; 13500b57cec5SDimitry Andric _D1 __l1 = _VSTD::distance(__first1, __last1); 13510b57cec5SDimitry Andric if (__l1 == _D1(1)) 13520b57cec5SDimitry Andric return false; 13530b57cec5SDimitry Andric _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1); 13540b57cec5SDimitry Andric // For each element in [f1, l1) see if there are the same number of 13550b57cec5SDimitry Andric // equal elements in [f2, l2) 13560b57cec5SDimitry Andric for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) 13570b57cec5SDimitry Andric { 13580b57cec5SDimitry Andric // Have we already counted the number of *__i in [f1, l1)? 13590b57cec5SDimitry Andric _ForwardIterator1 __match = __first1; 13600b57cec5SDimitry Andric for (; __match != __i; ++__match) 13610b57cec5SDimitry Andric if (__pred(*__match, *__i)) 13620b57cec5SDimitry Andric break; 13630b57cec5SDimitry Andric if (__match == __i) { 13640b57cec5SDimitry Andric // Count number of *__i in [f2, l2) 13650b57cec5SDimitry Andric _D1 __c2 = 0; 13660b57cec5SDimitry Andric for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) 13670b57cec5SDimitry Andric if (__pred(*__i, *__j)) 13680b57cec5SDimitry Andric ++__c2; 13690b57cec5SDimitry Andric if (__c2 == 0) 13700b57cec5SDimitry Andric return false; 13710b57cec5SDimitry Andric // Count number of *__i in [__i, l1) (we can start with 1) 13720b57cec5SDimitry Andric _D1 __c1 = 1; 13730b57cec5SDimitry Andric for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) 13740b57cec5SDimitry Andric if (__pred(*__i, *__j)) 13750b57cec5SDimitry Andric ++__c1; 13760b57cec5SDimitry Andric if (__c1 != __c2) 13770b57cec5SDimitry Andric return false; 13780b57cec5SDimitry Andric } 13790b57cec5SDimitry Andric } 13800b57cec5SDimitry Andric return true; 13810b57cec5SDimitry Andric} 13820b57cec5SDimitry Andric 13830b57cec5SDimitry Andrictemplate<class _ForwardIterator1, class _ForwardIterator2> 13840b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 13850b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 13860b57cec5SDimitry Andricbool 13870b57cec5SDimitry Andricis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 13880b57cec5SDimitry Andric _ForwardIterator2 __first2) 13890b57cec5SDimitry Andric{ 13900b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 13910b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 13920b57cec5SDimitry Andric return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>()); 13930b57cec5SDimitry Andric} 13940b57cec5SDimitry Andric 13950b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11 13960b57cec5SDimitry Andrictemplate<class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> 13970b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 13980b57cec5SDimitry Andric__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 13990b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, 14000b57cec5SDimitry Andric _BinaryPredicate __pred, 14010b57cec5SDimitry Andric forward_iterator_tag, forward_iterator_tag ) 14020b57cec5SDimitry Andric{ 14030b57cec5SDimitry Andric// shorten sequences as much as possible by lopping of any equal prefix 14040b57cec5SDimitry Andric for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) 14050b57cec5SDimitry Andric if (!__pred(*__first1, *__first2)) 14060b57cec5SDimitry Andric break; 14070b57cec5SDimitry Andric if (__first1 == __last1) 14080b57cec5SDimitry Andric return __first2 == __last2; 14090b57cec5SDimitry Andric else if (__first2 == __last2) 14100b57cec5SDimitry Andric return false; 14110b57cec5SDimitry Andric 14120b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; 14130b57cec5SDimitry Andric _D1 __l1 = _VSTD::distance(__first1, __last1); 14140b57cec5SDimitry Andric 14150b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2; 14160b57cec5SDimitry Andric _D2 __l2 = _VSTD::distance(__first2, __last2); 14170b57cec5SDimitry Andric if (__l1 != __l2) 14180b57cec5SDimitry Andric return false; 14190b57cec5SDimitry Andric 14200b57cec5SDimitry Andric // For each element in [f1, l1) see if there are the same number of 14210b57cec5SDimitry Andric // equal elements in [f2, l2) 14220b57cec5SDimitry Andric for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) 14230b57cec5SDimitry Andric { 14240b57cec5SDimitry Andric // Have we already counted the number of *__i in [f1, l1)? 14250b57cec5SDimitry Andric _ForwardIterator1 __match = __first1; 14260b57cec5SDimitry Andric for (; __match != __i; ++__match) 14270b57cec5SDimitry Andric if (__pred(*__match, *__i)) 14280b57cec5SDimitry Andric break; 14290b57cec5SDimitry Andric if (__match == __i) { 14300b57cec5SDimitry Andric // Count number of *__i in [f2, l2) 14310b57cec5SDimitry Andric _D1 __c2 = 0; 14320b57cec5SDimitry Andric for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) 14330b57cec5SDimitry Andric if (__pred(*__i, *__j)) 14340b57cec5SDimitry Andric ++__c2; 14350b57cec5SDimitry Andric if (__c2 == 0) 14360b57cec5SDimitry Andric return false; 14370b57cec5SDimitry Andric // Count number of *__i in [__i, l1) (we can start with 1) 14380b57cec5SDimitry Andric _D1 __c1 = 1; 14390b57cec5SDimitry Andric for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) 14400b57cec5SDimitry Andric if (__pred(*__i, *__j)) 14410b57cec5SDimitry Andric ++__c1; 14420b57cec5SDimitry Andric if (__c1 != __c2) 14430b57cec5SDimitry Andric return false; 14440b57cec5SDimitry Andric } 14450b57cec5SDimitry Andric } 14460b57cec5SDimitry Andric return true; 14470b57cec5SDimitry Andric} 14480b57cec5SDimitry Andric 14490b57cec5SDimitry Andrictemplate<class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> 14500b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 14510b57cec5SDimitry Andric__is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1, 14520b57cec5SDimitry Andric _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, 14530b57cec5SDimitry Andric _BinaryPredicate __pred, 14540b57cec5SDimitry Andric random_access_iterator_tag, random_access_iterator_tag ) 14550b57cec5SDimitry Andric{ 14560b57cec5SDimitry Andric if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) 14570b57cec5SDimitry Andric return false; 14580b57cec5SDimitry Andric return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2, 14590b57cec5SDimitry Andric typename add_lvalue_reference<_BinaryPredicate>::type> 14600b57cec5SDimitry Andric (__first1, __last1, __first2, __pred ); 14610b57cec5SDimitry Andric} 14620b57cec5SDimitry Andric 14630b57cec5SDimitry Andrictemplate<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 14640b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 14650b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 14660b57cec5SDimitry Andricbool 14670b57cec5SDimitry Andricis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 14680b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, 14690b57cec5SDimitry Andric _BinaryPredicate __pred ) 14700b57cec5SDimitry Andric{ 14710b57cec5SDimitry Andric return _VSTD::__is_permutation<typename add_lvalue_reference<_BinaryPredicate>::type> 14720b57cec5SDimitry Andric (__first1, __last1, __first2, __last2, __pred, 14730b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator1>::iterator_category(), 14740b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator2>::iterator_category()); 14750b57cec5SDimitry Andric} 14760b57cec5SDimitry Andric 14770b57cec5SDimitry Andrictemplate<class _ForwardIterator1, class _ForwardIterator2> 14780b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 14790b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 14800b57cec5SDimitry Andricbool 14810b57cec5SDimitry Andricis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 14820b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2) 14830b57cec5SDimitry Andric{ 14840b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 14850b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 14860b57cec5SDimitry Andric return _VSTD::__is_permutation(__first1, __last1, __first2, __last2, 14870b57cec5SDimitry Andric __equal_to<__v1, __v2>(), 14880b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator1>::iterator_category(), 14890b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator2>::iterator_category()); 14900b57cec5SDimitry Andric} 14910b57cec5SDimitry Andric#endif 14920b57cec5SDimitry Andric 14930b57cec5SDimitry Andric// search 14940b57cec5SDimitry Andric// __search is in <functional> 14950b57cec5SDimitry Andric 14960b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 14970b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 14980b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 14990b57cec5SDimitry Andric_ForwardIterator1 15000b57cec5SDimitry Andricsearch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 15010b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 15020b57cec5SDimitry Andric{ 15030b57cec5SDimitry Andric return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type> 15040b57cec5SDimitry Andric (__first1, __last1, __first2, __last2, __pred, 15050b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator1>::iterator_category(), 15060b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator2>::iterator_category()) 15070b57cec5SDimitry Andric .first; 15080b57cec5SDimitry Andric} 15090b57cec5SDimitry Andric 15100b57cec5SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2> 15110b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 15120b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 15130b57cec5SDimitry Andric_ForwardIterator1 15140b57cec5SDimitry Andricsearch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 15150b57cec5SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2) 15160b57cec5SDimitry Andric{ 15170b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 15180b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 15190b57cec5SDimitry Andric return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 15200b57cec5SDimitry Andric} 15210b57cec5SDimitry Andric 15220b57cec5SDimitry Andric 15230b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 15240b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Searcher> 15250b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 15260b57cec5SDimitry Andric_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s) 15270b57cec5SDimitry Andric{ return __s(__f, __l).first; } 15280b57cec5SDimitry Andric#endif 15290b57cec5SDimitry Andric 15300b57cec5SDimitry Andric// search_n 15310b57cec5SDimitry Andric 15320b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp> 15330b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 15340b57cec5SDimitry Andric__search_n(_ForwardIterator __first, _ForwardIterator __last, 15350b57cec5SDimitry Andric _Size __count, const _Tp& __value_, _BinaryPredicate __pred, forward_iterator_tag) 15360b57cec5SDimitry Andric{ 15370b57cec5SDimitry Andric if (__count <= 0) 15380b57cec5SDimitry Andric return __first; 15390b57cec5SDimitry Andric while (true) 15400b57cec5SDimitry Andric { 15410b57cec5SDimitry Andric // Find first element in sequence that matchs __value_, with a mininum of loop checks 15420b57cec5SDimitry Andric while (true) 15430b57cec5SDimitry Andric { 15440b57cec5SDimitry Andric if (__first == __last) // return __last if no element matches __value_ 15450b57cec5SDimitry Andric return __last; 15460b57cec5SDimitry Andric if (__pred(*__first, __value_)) 15470b57cec5SDimitry Andric break; 15480b57cec5SDimitry Andric ++__first; 15490b57cec5SDimitry Andric } 15500b57cec5SDimitry Andric // *__first matches __value_, now match elements after here 15510b57cec5SDimitry Andric _ForwardIterator __m = __first; 15520b57cec5SDimitry Andric _Size __c(0); 15530b57cec5SDimitry Andric while (true) 15540b57cec5SDimitry Andric { 15550b57cec5SDimitry Andric if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) 15560b57cec5SDimitry Andric return __first; 15570b57cec5SDimitry Andric if (++__m == __last) // Otherwise if source exhaused, pattern not found 15580b57cec5SDimitry Andric return __last; 15590b57cec5SDimitry Andric if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first 15600b57cec5SDimitry Andric { 15610b57cec5SDimitry Andric __first = __m; 15620b57cec5SDimitry Andric ++__first; 15630b57cec5SDimitry Andric break; 15640b57cec5SDimitry Andric } // else there is a match, check next elements 15650b57cec5SDimitry Andric } 15660b57cec5SDimitry Andric } 15670b57cec5SDimitry Andric} 15680b57cec5SDimitry Andric 15690b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp> 15700b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator 15710b57cec5SDimitry Andric__search_n(_RandomAccessIterator __first, _RandomAccessIterator __last, 15720b57cec5SDimitry Andric _Size __count, const _Tp& __value_, _BinaryPredicate __pred, random_access_iterator_tag) 15730b57cec5SDimitry Andric{ 15740b57cec5SDimitry Andric if (__count <= 0) 15750b57cec5SDimitry Andric return __first; 15760b57cec5SDimitry Andric _Size __len = static_cast<_Size>(__last - __first); 15770b57cec5SDimitry Andric if (__len < __count) 15780b57cec5SDimitry Andric return __last; 15790b57cec5SDimitry Andric const _RandomAccessIterator __s = __last - (__count - 1); // Start of pattern match can't go beyond here 15800b57cec5SDimitry Andric while (true) 15810b57cec5SDimitry Andric { 15820b57cec5SDimitry Andric // Find first element in sequence that matchs __value_, with a mininum of loop checks 15830b57cec5SDimitry Andric while (true) 15840b57cec5SDimitry Andric { 15850b57cec5SDimitry Andric if (__first >= __s) // return __last if no element matches __value_ 15860b57cec5SDimitry Andric return __last; 15870b57cec5SDimitry Andric if (__pred(*__first, __value_)) 15880b57cec5SDimitry Andric break; 15890b57cec5SDimitry Andric ++__first; 15900b57cec5SDimitry Andric } 15910b57cec5SDimitry Andric // *__first matches __value_, now match elements after here 15920b57cec5SDimitry Andric _RandomAccessIterator __m = __first; 15930b57cec5SDimitry Andric _Size __c(0); 15940b57cec5SDimitry Andric while (true) 15950b57cec5SDimitry Andric { 15960b57cec5SDimitry Andric if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) 15970b57cec5SDimitry Andric return __first; 15980b57cec5SDimitry Andric ++__m; // no need to check range on __m because __s guarantees we have enough source 15990b57cec5SDimitry Andric if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first 16000b57cec5SDimitry Andric { 16010b57cec5SDimitry Andric __first = __m; 16020b57cec5SDimitry Andric ++__first; 16030b57cec5SDimitry Andric break; 16040b57cec5SDimitry Andric } // else there is a match, check next elements 16050b57cec5SDimitry Andric } 16060b57cec5SDimitry Andric } 16070b57cec5SDimitry Andric} 16080b57cec5SDimitry Andric 16090b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> 16100b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 16110b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 16120b57cec5SDimitry Andric_ForwardIterator 16130b57cec5SDimitry Andricsearch_n(_ForwardIterator __first, _ForwardIterator __last, 16140b57cec5SDimitry Andric _Size __count, const _Tp& __value_, _BinaryPredicate __pred) 16150b57cec5SDimitry Andric{ 16160b57cec5SDimitry Andric return _VSTD::__search_n<typename add_lvalue_reference<_BinaryPredicate>::type> 16170b57cec5SDimitry Andric (__first, __last, __convert_to_integral(__count), __value_, __pred, 16180b57cec5SDimitry Andric typename iterator_traits<_ForwardIterator>::iterator_category()); 16190b57cec5SDimitry Andric} 16200b57cec5SDimitry Andric 16210b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size, class _Tp> 16220b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 16230b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 16240b57cec5SDimitry Andric_ForwardIterator 16250b57cec5SDimitry Andricsearch_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_) 16260b57cec5SDimitry Andric{ 16270b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type __v; 16280b57cec5SDimitry Andric return _VSTD::search_n(__first, __last, __convert_to_integral(__count), 16290b57cec5SDimitry Andric __value_, __equal_to<__v, _Tp>()); 16300b57cec5SDimitry Andric} 16310b57cec5SDimitry Andric 16320b57cec5SDimitry Andric// copy 16330b57cec5SDimitry Andrictemplate <class _Iter> 1634*480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 16350b57cec5SDimitry Andric_Iter 16360b57cec5SDimitry Andric__unwrap_iter(_Iter __i) 16370b57cec5SDimitry Andric{ 16380b57cec5SDimitry Andric return __i; 16390b57cec5SDimitry Andric} 16400b57cec5SDimitry Andric 16410b57cec5SDimitry Andrictemplate <class _Tp> 1642*480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 16430b57cec5SDimitry Andrictypename enable_if 16440b57cec5SDimitry Andric< 16450b57cec5SDimitry Andric is_trivially_copy_assignable<_Tp>::value, 16460b57cec5SDimitry Andric _Tp* 16470b57cec5SDimitry Andric>::type 16480b57cec5SDimitry Andric__unwrap_iter(move_iterator<_Tp*> __i) 16490b57cec5SDimitry Andric{ 16500b57cec5SDimitry Andric return __i.base(); 16510b57cec5SDimitry Andric} 16520b57cec5SDimitry Andric 16530b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL < 2 16540b57cec5SDimitry Andric 16550b57cec5SDimitry Andrictemplate <class _Tp> 16560b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 16570b57cec5SDimitry Andrictypename enable_if 16580b57cec5SDimitry Andric< 16590b57cec5SDimitry Andric is_trivially_copy_assignable<_Tp>::value, 16600b57cec5SDimitry Andric _Tp* 16610b57cec5SDimitry Andric>::type 16620b57cec5SDimitry Andric__unwrap_iter(__wrap_iter<_Tp*> __i) 16630b57cec5SDimitry Andric{ 16640b57cec5SDimitry Andric return __i.base(); 16650b57cec5SDimitry Andric} 16660b57cec5SDimitry Andric 16670b57cec5SDimitry Andrictemplate <class _Tp> 16680b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 16690b57cec5SDimitry Andrictypename enable_if 16700b57cec5SDimitry Andric< 16710b57cec5SDimitry Andric is_trivially_copy_assignable<_Tp>::value, 16720b57cec5SDimitry Andric const _Tp* 16730b57cec5SDimitry Andric>::type 16740b57cec5SDimitry Andric__unwrap_iter(__wrap_iter<const _Tp*> __i) 16750b57cec5SDimitry Andric{ 16760b57cec5SDimitry Andric return __i.base(); 16770b57cec5SDimitry Andric} 16780b57cec5SDimitry Andric 16790b57cec5SDimitry Andric#else 16800b57cec5SDimitry Andric 16810b57cec5SDimitry Andrictemplate <class _Tp> 16820b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 16830b57cec5SDimitry Andrictypename enable_if 16840b57cec5SDimitry Andric< 16850b57cec5SDimitry Andric is_trivially_copy_assignable<_Tp>::value, 16860b57cec5SDimitry Andric __wrap_iter<_Tp*> 16870b57cec5SDimitry Andric>::type 16880b57cec5SDimitry Andric__unwrap_iter(__wrap_iter<_Tp*> __i) 16890b57cec5SDimitry Andric{ 16900b57cec5SDimitry Andric return __i; 16910b57cec5SDimitry Andric} 16920b57cec5SDimitry Andric 16930b57cec5SDimitry Andric#endif // _LIBCPP_DEBUG_LEVEL < 2 16940b57cec5SDimitry Andric 16950b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 1696*480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 16970b57cec5SDimitry Andric_OutputIterator 1698*480093f4SDimitry Andric__copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 16990b57cec5SDimitry Andric{ 17000b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 17010b57cec5SDimitry Andric *__result = *__first; 17020b57cec5SDimitry Andric return __result; 17030b57cec5SDimitry Andric} 17040b57cec5SDimitry Andric 1705*480093f4SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 1706*480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 1707*480093f4SDimitry Andric_OutputIterator 1708*480093f4SDimitry Andric__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 1709*480093f4SDimitry Andric{ 1710*480093f4SDimitry Andric return __copy_constexpr(__first, __last, __result); 1711*480093f4SDimitry Andric} 1712*480093f4SDimitry Andric 17130b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 17140b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 17150b57cec5SDimitry Andrictypename enable_if 17160b57cec5SDimitry Andric< 17170b57cec5SDimitry Andric is_same<typename remove_const<_Tp>::type, _Up>::value && 17180b57cec5SDimitry Andric is_trivially_copy_assignable<_Up>::value, 17190b57cec5SDimitry Andric _Up* 17200b57cec5SDimitry Andric>::type 17210b57cec5SDimitry Andric__copy(_Tp* __first, _Tp* __last, _Up* __result) 17220b57cec5SDimitry Andric{ 17230b57cec5SDimitry Andric const size_t __n = static_cast<size_t>(__last - __first); 17240b57cec5SDimitry Andric if (__n > 0) 17250b57cec5SDimitry Andric _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 17260b57cec5SDimitry Andric return __result + __n; 17270b57cec5SDimitry Andric} 17280b57cec5SDimitry Andric 17290b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 1730*480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED 17310b57cec5SDimitry Andric_OutputIterator 17320b57cec5SDimitry Andriccopy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 17330b57cec5SDimitry Andric{ 1734*480093f4SDimitry Andric if (__libcpp_is_constant_evaluated()) { 1735*480093f4SDimitry Andric return _VSTD::__copy_constexpr( 1736*480093f4SDimitry Andric __unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); 1737*480093f4SDimitry Andric } else { 1738*480093f4SDimitry Andric return _VSTD::__copy( 1739*480093f4SDimitry Andric __unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); 1740*480093f4SDimitry Andric } 17410b57cec5SDimitry Andric} 17420b57cec5SDimitry Andric 17430b57cec5SDimitry Andric// copy_backward 17440b57cec5SDimitry Andric 17450b57cec5SDimitry Andrictemplate <class _BidirectionalIterator, class _OutputIterator> 1746*480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1747*480093f4SDimitry Andric_OutputIterator 1748*480093f4SDimitry Andric__copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 1749*480093f4SDimitry Andric{ 1750*480093f4SDimitry Andric while (__first != __last) 1751*480093f4SDimitry Andric *--__result = *--__last; 1752*480093f4SDimitry Andric return __result; 1753*480093f4SDimitry Andric} 1754*480093f4SDimitry Andric 1755*480093f4SDimitry Andrictemplate <class _BidirectionalIterator, class _OutputIterator> 17560b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 17570b57cec5SDimitry Andric_OutputIterator 17580b57cec5SDimitry Andric__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 17590b57cec5SDimitry Andric{ 1760*480093f4SDimitry Andric return __copy_backward_constexpr(__first, __last, __result); 17610b57cec5SDimitry Andric} 17620b57cec5SDimitry Andric 17630b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 17640b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 17650b57cec5SDimitry Andrictypename enable_if 17660b57cec5SDimitry Andric< 17670b57cec5SDimitry Andric is_same<typename remove_const<_Tp>::type, _Up>::value && 17680b57cec5SDimitry Andric is_trivially_copy_assignable<_Up>::value, 17690b57cec5SDimitry Andric _Up* 17700b57cec5SDimitry Andric>::type 17710b57cec5SDimitry Andric__copy_backward(_Tp* __first, _Tp* __last, _Up* __result) 17720b57cec5SDimitry Andric{ 17730b57cec5SDimitry Andric const size_t __n = static_cast<size_t>(__last - __first); 17740b57cec5SDimitry Andric if (__n > 0) 17750b57cec5SDimitry Andric { 17760b57cec5SDimitry Andric __result -= __n; 17770b57cec5SDimitry Andric _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 17780b57cec5SDimitry Andric } 17790b57cec5SDimitry Andric return __result; 17800b57cec5SDimitry Andric} 17810b57cec5SDimitry Andric 17820b57cec5SDimitry Andrictemplate <class _BidirectionalIterator1, class _BidirectionalIterator2> 1783*480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED 17840b57cec5SDimitry Andric_BidirectionalIterator2 17850b57cec5SDimitry Andriccopy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, 17860b57cec5SDimitry Andric _BidirectionalIterator2 __result) 17870b57cec5SDimitry Andric{ 1788*480093f4SDimitry Andric if (__libcpp_is_constant_evaluated()) { 1789*480093f4SDimitry Andric return _VSTD::__copy_backward_constexpr(__unwrap_iter(__first), 1790*480093f4SDimitry Andric __unwrap_iter(__last), 1791*480093f4SDimitry Andric __unwrap_iter(__result)); 1792*480093f4SDimitry Andric } else { 17930b57cec5SDimitry Andric return _VSTD::__copy_backward(__unwrap_iter(__first), 17940b57cec5SDimitry Andric __unwrap_iter(__last), 17950b57cec5SDimitry Andric __unwrap_iter(__result)); 17960b57cec5SDimitry Andric } 1797*480093f4SDimitry Andric} 17980b57cec5SDimitry Andric 17990b57cec5SDimitry Andric// copy_if 18000b57cec5SDimitry Andric 18010b57cec5SDimitry Andrictemplate<class _InputIterator, class _OutputIterator, class _Predicate> 1802*480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 18030b57cec5SDimitry Andric_OutputIterator 18040b57cec5SDimitry Andriccopy_if(_InputIterator __first, _InputIterator __last, 18050b57cec5SDimitry Andric _OutputIterator __result, _Predicate __pred) 18060b57cec5SDimitry Andric{ 18070b57cec5SDimitry Andric for (; __first != __last; ++__first) 18080b57cec5SDimitry Andric { 18090b57cec5SDimitry Andric if (__pred(*__first)) 18100b57cec5SDimitry Andric { 18110b57cec5SDimitry Andric *__result = *__first; 18120b57cec5SDimitry Andric ++__result; 18130b57cec5SDimitry Andric } 18140b57cec5SDimitry Andric } 18150b57cec5SDimitry Andric return __result; 18160b57cec5SDimitry Andric} 18170b57cec5SDimitry Andric 18180b57cec5SDimitry Andric// copy_n 18190b57cec5SDimitry Andric 18200b57cec5SDimitry Andrictemplate<class _InputIterator, class _Size, class _OutputIterator> 1821*480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED 18220b57cec5SDimitry Andrictypename enable_if 18230b57cec5SDimitry Andric< 1824*480093f4SDimitry Andric __is_cpp17_input_iterator<_InputIterator>::value && 1825*480093f4SDimitry Andric !__is_cpp17_random_access_iterator<_InputIterator>::value, 18260b57cec5SDimitry Andric _OutputIterator 18270b57cec5SDimitry Andric>::type 18280b57cec5SDimitry Andriccopy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) 18290b57cec5SDimitry Andric{ 18300b57cec5SDimitry Andric typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; 18310b57cec5SDimitry Andric _IntegralSize __n = __orig_n; 18320b57cec5SDimitry Andric if (__n > 0) 18330b57cec5SDimitry Andric { 18340b57cec5SDimitry Andric *__result = *__first; 18350b57cec5SDimitry Andric ++__result; 18360b57cec5SDimitry Andric for (--__n; __n > 0; --__n) 18370b57cec5SDimitry Andric { 18380b57cec5SDimitry Andric ++__first; 18390b57cec5SDimitry Andric *__result = *__first; 18400b57cec5SDimitry Andric ++__result; 18410b57cec5SDimitry Andric } 18420b57cec5SDimitry Andric } 18430b57cec5SDimitry Andric return __result; 18440b57cec5SDimitry Andric} 18450b57cec5SDimitry Andric 18460b57cec5SDimitry Andrictemplate<class _InputIterator, class _Size, class _OutputIterator> 1847*480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED 18480b57cec5SDimitry Andrictypename enable_if 18490b57cec5SDimitry Andric< 1850*480093f4SDimitry Andric __is_cpp17_random_access_iterator<_InputIterator>::value, 18510b57cec5SDimitry Andric _OutputIterator 18520b57cec5SDimitry Andric>::type 18530b57cec5SDimitry Andriccopy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) 18540b57cec5SDimitry Andric{ 18550b57cec5SDimitry Andric typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; 18560b57cec5SDimitry Andric _IntegralSize __n = __orig_n; 18570b57cec5SDimitry Andric return _VSTD::copy(__first, __first + __n, __result); 18580b57cec5SDimitry Andric} 18590b57cec5SDimitry Andric 18600b57cec5SDimitry Andric// move 18610b57cec5SDimitry Andric 18620b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 18630b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 18640b57cec5SDimitry Andric_OutputIterator 18650b57cec5SDimitry Andric__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 18660b57cec5SDimitry Andric{ 18670b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 18680b57cec5SDimitry Andric *__result = _VSTD::move(*__first); 18690b57cec5SDimitry Andric return __result; 18700b57cec5SDimitry Andric} 18710b57cec5SDimitry Andric 18720b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 18730b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 18740b57cec5SDimitry Andrictypename enable_if 18750b57cec5SDimitry Andric< 18760b57cec5SDimitry Andric is_same<typename remove_const<_Tp>::type, _Up>::value && 18770b57cec5SDimitry Andric is_trivially_copy_assignable<_Up>::value, 18780b57cec5SDimitry Andric _Up* 18790b57cec5SDimitry Andric>::type 18800b57cec5SDimitry Andric__move(_Tp* __first, _Tp* __last, _Up* __result) 18810b57cec5SDimitry Andric{ 18820b57cec5SDimitry Andric const size_t __n = static_cast<size_t>(__last - __first); 18830b57cec5SDimitry Andric if (__n > 0) 18840b57cec5SDimitry Andric _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 18850b57cec5SDimitry Andric return __result + __n; 18860b57cec5SDimitry Andric} 18870b57cec5SDimitry Andric 18880b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 18890b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 18900b57cec5SDimitry Andric_OutputIterator 18910b57cec5SDimitry Andricmove(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 18920b57cec5SDimitry Andric{ 18930b57cec5SDimitry Andric return _VSTD::__move(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); 18940b57cec5SDimitry Andric} 18950b57cec5SDimitry Andric 18960b57cec5SDimitry Andric// move_backward 18970b57cec5SDimitry Andric 18980b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 18990b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 19000b57cec5SDimitry Andric_OutputIterator 19010b57cec5SDimitry Andric__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 19020b57cec5SDimitry Andric{ 19030b57cec5SDimitry Andric while (__first != __last) 19040b57cec5SDimitry Andric *--__result = _VSTD::move(*--__last); 19050b57cec5SDimitry Andric return __result; 19060b57cec5SDimitry Andric} 19070b57cec5SDimitry Andric 19080b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 19090b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 19100b57cec5SDimitry Andrictypename enable_if 19110b57cec5SDimitry Andric< 19120b57cec5SDimitry Andric is_same<typename remove_const<_Tp>::type, _Up>::value && 19130b57cec5SDimitry Andric is_trivially_copy_assignable<_Up>::value, 19140b57cec5SDimitry Andric _Up* 19150b57cec5SDimitry Andric>::type 19160b57cec5SDimitry Andric__move_backward(_Tp* __first, _Tp* __last, _Up* __result) 19170b57cec5SDimitry Andric{ 19180b57cec5SDimitry Andric const size_t __n = static_cast<size_t>(__last - __first); 19190b57cec5SDimitry Andric if (__n > 0) 19200b57cec5SDimitry Andric { 19210b57cec5SDimitry Andric __result -= __n; 19220b57cec5SDimitry Andric _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 19230b57cec5SDimitry Andric } 19240b57cec5SDimitry Andric return __result; 19250b57cec5SDimitry Andric} 19260b57cec5SDimitry Andric 19270b57cec5SDimitry Andrictemplate <class _BidirectionalIterator1, class _BidirectionalIterator2> 19280b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 19290b57cec5SDimitry Andric_BidirectionalIterator2 19300b57cec5SDimitry Andricmove_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, 19310b57cec5SDimitry Andric _BidirectionalIterator2 __result) 19320b57cec5SDimitry Andric{ 19330b57cec5SDimitry Andric return _VSTD::__move_backward(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); 19340b57cec5SDimitry Andric} 19350b57cec5SDimitry Andric 19360b57cec5SDimitry Andric// iter_swap 19370b57cec5SDimitry Andric 19380b57cec5SDimitry Andric// moved to <type_traits> for better swap / noexcept support 19390b57cec5SDimitry Andric 19400b57cec5SDimitry Andric// transform 19410b57cec5SDimitry Andric 19420b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _UnaryOperation> 19430b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19440b57cec5SDimitry Andric_OutputIterator 19450b57cec5SDimitry Andrictransform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) 19460b57cec5SDimitry Andric{ 19470b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 19480b57cec5SDimitry Andric *__result = __op(*__first); 19490b57cec5SDimitry Andric return __result; 19500b57cec5SDimitry Andric} 19510b57cec5SDimitry Andric 19520b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation> 19530b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19540b57cec5SDimitry Andric_OutputIterator 19550b57cec5SDimitry Andrictransform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, 19560b57cec5SDimitry Andric _OutputIterator __result, _BinaryOperation __binary_op) 19570b57cec5SDimitry Andric{ 19580b57cec5SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result) 19590b57cec5SDimitry Andric *__result = __binary_op(*__first1, *__first2); 19600b57cec5SDimitry Andric return __result; 19610b57cec5SDimitry Andric} 19620b57cec5SDimitry Andric 19630b57cec5SDimitry Andric// replace 19640b57cec5SDimitry Andric 19650b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 19660b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19670b57cec5SDimitry Andricvoid 19680b57cec5SDimitry Andricreplace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) 19690b57cec5SDimitry Andric{ 19700b57cec5SDimitry Andric for (; __first != __last; ++__first) 19710b57cec5SDimitry Andric if (*__first == __old_value) 19720b57cec5SDimitry Andric *__first = __new_value; 19730b57cec5SDimitry Andric} 19740b57cec5SDimitry Andric 19750b57cec5SDimitry Andric// replace_if 19760b57cec5SDimitry Andric 19770b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Predicate, class _Tp> 19780b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19790b57cec5SDimitry Andricvoid 19800b57cec5SDimitry Andricreplace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) 19810b57cec5SDimitry Andric{ 19820b57cec5SDimitry Andric for (; __first != __last; ++__first) 19830b57cec5SDimitry Andric if (__pred(*__first)) 19840b57cec5SDimitry Andric *__first = __new_value; 19850b57cec5SDimitry Andric} 19860b57cec5SDimitry Andric 19870b57cec5SDimitry Andric// replace_copy 19880b57cec5SDimitry Andric 19890b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Tp> 19900b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19910b57cec5SDimitry Andric_OutputIterator 19920b57cec5SDimitry Andricreplace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, 19930b57cec5SDimitry Andric const _Tp& __old_value, const _Tp& __new_value) 19940b57cec5SDimitry Andric{ 19950b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 19960b57cec5SDimitry Andric if (*__first == __old_value) 19970b57cec5SDimitry Andric *__result = __new_value; 19980b57cec5SDimitry Andric else 19990b57cec5SDimitry Andric *__result = *__first; 20000b57cec5SDimitry Andric return __result; 20010b57cec5SDimitry Andric} 20020b57cec5SDimitry Andric 20030b57cec5SDimitry Andric// replace_copy_if 20040b57cec5SDimitry Andric 20050b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp> 20060b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 20070b57cec5SDimitry Andric_OutputIterator 20080b57cec5SDimitry Andricreplace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, 20090b57cec5SDimitry Andric _Predicate __pred, const _Tp& __new_value) 20100b57cec5SDimitry Andric{ 20110b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 20120b57cec5SDimitry Andric if (__pred(*__first)) 20130b57cec5SDimitry Andric *__result = __new_value; 20140b57cec5SDimitry Andric else 20150b57cec5SDimitry Andric *__result = *__first; 20160b57cec5SDimitry Andric return __result; 20170b57cec5SDimitry Andric} 20180b57cec5SDimitry Andric 20190b57cec5SDimitry Andric// fill_n 20200b57cec5SDimitry Andric 20210b57cec5SDimitry Andrictemplate <class _OutputIterator, class _Size, class _Tp> 20220b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 20230b57cec5SDimitry Andric_OutputIterator 20240b57cec5SDimitry Andric__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) 20250b57cec5SDimitry Andric{ 20260b57cec5SDimitry Andric for (; __n > 0; ++__first, (void) --__n) 20270b57cec5SDimitry Andric *__first = __value_; 20280b57cec5SDimitry Andric return __first; 20290b57cec5SDimitry Andric} 20300b57cec5SDimitry Andric 20310b57cec5SDimitry Andrictemplate <class _OutputIterator, class _Size, class _Tp> 20320b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 20330b57cec5SDimitry Andric_OutputIterator 20340b57cec5SDimitry Andricfill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) 20350b57cec5SDimitry Andric{ 20360b57cec5SDimitry Andric return _VSTD::__fill_n(__first, __convert_to_integral(__n), __value_); 20370b57cec5SDimitry Andric} 20380b57cec5SDimitry Andric 20390b57cec5SDimitry Andric// fill 20400b57cec5SDimitry Andric 20410b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 20420b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 20430b57cec5SDimitry Andricvoid 20440b57cec5SDimitry Andric__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag) 20450b57cec5SDimitry Andric{ 20460b57cec5SDimitry Andric for (; __first != __last; ++__first) 20470b57cec5SDimitry Andric *__first = __value_; 20480b57cec5SDimitry Andric} 20490b57cec5SDimitry Andric 20500b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Tp> 20510b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 20520b57cec5SDimitry Andricvoid 20530b57cec5SDimitry Andric__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag) 20540b57cec5SDimitry Andric{ 20550b57cec5SDimitry Andric _VSTD::fill_n(__first, __last - __first, __value_); 20560b57cec5SDimitry Andric} 20570b57cec5SDimitry Andric 20580b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 20590b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 20600b57cec5SDimitry Andricvoid 20610b57cec5SDimitry Andricfill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 20620b57cec5SDimitry Andric{ 20630b57cec5SDimitry Andric _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category()); 20640b57cec5SDimitry Andric} 20650b57cec5SDimitry Andric 20660b57cec5SDimitry Andric// generate 20670b57cec5SDimitry Andric 20680b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Generator> 20690b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 20700b57cec5SDimitry Andricvoid 20710b57cec5SDimitry Andricgenerate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) 20720b57cec5SDimitry Andric{ 20730b57cec5SDimitry Andric for (; __first != __last; ++__first) 20740b57cec5SDimitry Andric *__first = __gen(); 20750b57cec5SDimitry Andric} 20760b57cec5SDimitry Andric 20770b57cec5SDimitry Andric// generate_n 20780b57cec5SDimitry Andric 20790b57cec5SDimitry Andrictemplate <class _OutputIterator, class _Size, class _Generator> 20800b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 20810b57cec5SDimitry Andric_OutputIterator 20820b57cec5SDimitry Andricgenerate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) 20830b57cec5SDimitry Andric{ 20840b57cec5SDimitry Andric typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; 20850b57cec5SDimitry Andric _IntegralSize __n = __orig_n; 20860b57cec5SDimitry Andric for (; __n > 0; ++__first, (void) --__n) 20870b57cec5SDimitry Andric *__first = __gen(); 20880b57cec5SDimitry Andric return __first; 20890b57cec5SDimitry Andric} 20900b57cec5SDimitry Andric 20910b57cec5SDimitry Andric// remove 20920b57cec5SDimitry Andric 20930b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 20940b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 20950b57cec5SDimitry Andricremove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 20960b57cec5SDimitry Andric{ 20970b57cec5SDimitry Andric __first = _VSTD::find(__first, __last, __value_); 20980b57cec5SDimitry Andric if (__first != __last) 20990b57cec5SDimitry Andric { 21000b57cec5SDimitry Andric _ForwardIterator __i = __first; 21010b57cec5SDimitry Andric while (++__i != __last) 21020b57cec5SDimitry Andric { 21030b57cec5SDimitry Andric if (!(*__i == __value_)) 21040b57cec5SDimitry Andric { 21050b57cec5SDimitry Andric *__first = _VSTD::move(*__i); 21060b57cec5SDimitry Andric ++__first; 21070b57cec5SDimitry Andric } 21080b57cec5SDimitry Andric } 21090b57cec5SDimitry Andric } 21100b57cec5SDimitry Andric return __first; 21110b57cec5SDimitry Andric} 21120b57cec5SDimitry Andric 21130b57cec5SDimitry Andric// remove_if 21140b57cec5SDimitry Andric 21150b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Predicate> 21160b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 21170b57cec5SDimitry Andricremove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 21180b57cec5SDimitry Andric{ 21190b57cec5SDimitry Andric __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type> 21200b57cec5SDimitry Andric (__first, __last, __pred); 21210b57cec5SDimitry Andric if (__first != __last) 21220b57cec5SDimitry Andric { 21230b57cec5SDimitry Andric _ForwardIterator __i = __first; 21240b57cec5SDimitry Andric while (++__i != __last) 21250b57cec5SDimitry Andric { 21260b57cec5SDimitry Andric if (!__pred(*__i)) 21270b57cec5SDimitry Andric { 21280b57cec5SDimitry Andric *__first = _VSTD::move(*__i); 21290b57cec5SDimitry Andric ++__first; 21300b57cec5SDimitry Andric } 21310b57cec5SDimitry Andric } 21320b57cec5SDimitry Andric } 21330b57cec5SDimitry Andric return __first; 21340b57cec5SDimitry Andric} 21350b57cec5SDimitry Andric 21360b57cec5SDimitry Andric// remove_copy 21370b57cec5SDimitry Andric 21380b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Tp> 21390b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 21400b57cec5SDimitry Andric_OutputIterator 21410b57cec5SDimitry Andricremove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_) 21420b57cec5SDimitry Andric{ 21430b57cec5SDimitry Andric for (; __first != __last; ++__first) 21440b57cec5SDimitry Andric { 21450b57cec5SDimitry Andric if (!(*__first == __value_)) 21460b57cec5SDimitry Andric { 21470b57cec5SDimitry Andric *__result = *__first; 21480b57cec5SDimitry Andric ++__result; 21490b57cec5SDimitry Andric } 21500b57cec5SDimitry Andric } 21510b57cec5SDimitry Andric return __result; 21520b57cec5SDimitry Andric} 21530b57cec5SDimitry Andric 21540b57cec5SDimitry Andric// remove_copy_if 21550b57cec5SDimitry Andric 21560b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Predicate> 21570b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 21580b57cec5SDimitry Andric_OutputIterator 21590b57cec5SDimitry Andricremove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) 21600b57cec5SDimitry Andric{ 21610b57cec5SDimitry Andric for (; __first != __last; ++__first) 21620b57cec5SDimitry Andric { 21630b57cec5SDimitry Andric if (!__pred(*__first)) 21640b57cec5SDimitry Andric { 21650b57cec5SDimitry Andric *__result = *__first; 21660b57cec5SDimitry Andric ++__result; 21670b57cec5SDimitry Andric } 21680b57cec5SDimitry Andric } 21690b57cec5SDimitry Andric return __result; 21700b57cec5SDimitry Andric} 21710b57cec5SDimitry Andric 21720b57cec5SDimitry Andric// unique 21730b57cec5SDimitry Andric 21740b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _BinaryPredicate> 21750b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 21760b57cec5SDimitry Andricunique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) 21770b57cec5SDimitry Andric{ 21780b57cec5SDimitry Andric __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type> 21790b57cec5SDimitry Andric (__first, __last, __pred); 21800b57cec5SDimitry Andric if (__first != __last) 21810b57cec5SDimitry Andric { 21820b57cec5SDimitry Andric // ... a a ? ... 21830b57cec5SDimitry Andric // f i 21840b57cec5SDimitry Andric _ForwardIterator __i = __first; 21850b57cec5SDimitry Andric for (++__i; ++__i != __last;) 21860b57cec5SDimitry Andric if (!__pred(*__first, *__i)) 21870b57cec5SDimitry Andric *++__first = _VSTD::move(*__i); 21880b57cec5SDimitry Andric ++__first; 21890b57cec5SDimitry Andric } 21900b57cec5SDimitry Andric return __first; 21910b57cec5SDimitry Andric} 21920b57cec5SDimitry Andric 21930b57cec5SDimitry Andrictemplate <class _ForwardIterator> 21940b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 21950b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 21960b57cec5SDimitry Andric_ForwardIterator 21970b57cec5SDimitry Andricunique(_ForwardIterator __first, _ForwardIterator __last) 21980b57cec5SDimitry Andric{ 21990b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type __v; 22000b57cec5SDimitry Andric return _VSTD::unique(__first, __last, __equal_to<__v>()); 22010b57cec5SDimitry Andric} 22020b57cec5SDimitry Andric 22030b57cec5SDimitry Andric// unique_copy 22040b57cec5SDimitry Andric 22050b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _InputIterator, class _OutputIterator> 22060b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 22070b57cec5SDimitry Andric__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred, 22080b57cec5SDimitry Andric input_iterator_tag, output_iterator_tag) 22090b57cec5SDimitry Andric{ 22100b57cec5SDimitry Andric if (__first != __last) 22110b57cec5SDimitry Andric { 22120b57cec5SDimitry Andric typename iterator_traits<_InputIterator>::value_type __t(*__first); 22130b57cec5SDimitry Andric *__result = __t; 22140b57cec5SDimitry Andric ++__result; 22150b57cec5SDimitry Andric while (++__first != __last) 22160b57cec5SDimitry Andric { 22170b57cec5SDimitry Andric if (!__pred(__t, *__first)) 22180b57cec5SDimitry Andric { 22190b57cec5SDimitry Andric __t = *__first; 22200b57cec5SDimitry Andric *__result = __t; 22210b57cec5SDimitry Andric ++__result; 22220b57cec5SDimitry Andric } 22230b57cec5SDimitry Andric } 22240b57cec5SDimitry Andric } 22250b57cec5SDimitry Andric return __result; 22260b57cec5SDimitry Andric} 22270b57cec5SDimitry Andric 22280b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator> 22290b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 22300b57cec5SDimitry Andric__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred, 22310b57cec5SDimitry Andric forward_iterator_tag, output_iterator_tag) 22320b57cec5SDimitry Andric{ 22330b57cec5SDimitry Andric if (__first != __last) 22340b57cec5SDimitry Andric { 22350b57cec5SDimitry Andric _ForwardIterator __i = __first; 22360b57cec5SDimitry Andric *__result = *__i; 22370b57cec5SDimitry Andric ++__result; 22380b57cec5SDimitry Andric while (++__first != __last) 22390b57cec5SDimitry Andric { 22400b57cec5SDimitry Andric if (!__pred(*__i, *__first)) 22410b57cec5SDimitry Andric { 22420b57cec5SDimitry Andric *__result = *__first; 22430b57cec5SDimitry Andric ++__result; 22440b57cec5SDimitry Andric __i = __first; 22450b57cec5SDimitry Andric } 22460b57cec5SDimitry Andric } 22470b57cec5SDimitry Andric } 22480b57cec5SDimitry Andric return __result; 22490b57cec5SDimitry Andric} 22500b57cec5SDimitry Andric 22510b57cec5SDimitry Andrictemplate <class _BinaryPredicate, class _InputIterator, class _ForwardIterator> 22520b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 22530b57cec5SDimitry Andric__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred, 22540b57cec5SDimitry Andric input_iterator_tag, forward_iterator_tag) 22550b57cec5SDimitry Andric{ 22560b57cec5SDimitry Andric if (__first != __last) 22570b57cec5SDimitry Andric { 22580b57cec5SDimitry Andric *__result = *__first; 22590b57cec5SDimitry Andric while (++__first != __last) 22600b57cec5SDimitry Andric if (!__pred(*__result, *__first)) 22610b57cec5SDimitry Andric *++__result = *__first; 22620b57cec5SDimitry Andric ++__result; 22630b57cec5SDimitry Andric } 22640b57cec5SDimitry Andric return __result; 22650b57cec5SDimitry Andric} 22660b57cec5SDimitry Andric 22670b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _BinaryPredicate> 22680b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 22690b57cec5SDimitry Andric_OutputIterator 22700b57cec5SDimitry Andricunique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) 22710b57cec5SDimitry Andric{ 22720b57cec5SDimitry Andric return _VSTD::__unique_copy<typename add_lvalue_reference<_BinaryPredicate>::type> 22730b57cec5SDimitry Andric (__first, __last, __result, __pred, 22740b57cec5SDimitry Andric typename iterator_traits<_InputIterator>::iterator_category(), 22750b57cec5SDimitry Andric typename iterator_traits<_OutputIterator>::iterator_category()); 22760b57cec5SDimitry Andric} 22770b57cec5SDimitry Andric 22780b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator> 22790b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 22800b57cec5SDimitry Andric_OutputIterator 22810b57cec5SDimitry Andricunique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 22820b57cec5SDimitry Andric{ 22830b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator>::value_type __v; 22840b57cec5SDimitry Andric return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>()); 22850b57cec5SDimitry Andric} 22860b57cec5SDimitry Andric 22870b57cec5SDimitry Andric// reverse 22880b57cec5SDimitry Andric 22890b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 22900b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 22910b57cec5SDimitry Andricvoid 22920b57cec5SDimitry Andric__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) 22930b57cec5SDimitry Andric{ 22940b57cec5SDimitry Andric while (__first != __last) 22950b57cec5SDimitry Andric { 22960b57cec5SDimitry Andric if (__first == --__last) 22970b57cec5SDimitry Andric break; 22980b57cec5SDimitry Andric _VSTD::iter_swap(__first, __last); 22990b57cec5SDimitry Andric ++__first; 23000b57cec5SDimitry Andric } 23010b57cec5SDimitry Andric} 23020b57cec5SDimitry Andric 23030b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 23040b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 23050b57cec5SDimitry Andricvoid 23060b57cec5SDimitry Andric__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) 23070b57cec5SDimitry Andric{ 23080b57cec5SDimitry Andric if (__first != __last) 23090b57cec5SDimitry Andric for (; __first < --__last; ++__first) 23100b57cec5SDimitry Andric _VSTD::iter_swap(__first, __last); 23110b57cec5SDimitry Andric} 23120b57cec5SDimitry Andric 23130b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 23140b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 23150b57cec5SDimitry Andricvoid 23160b57cec5SDimitry Andricreverse(_BidirectionalIterator __first, _BidirectionalIterator __last) 23170b57cec5SDimitry Andric{ 23180b57cec5SDimitry Andric _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category()); 23190b57cec5SDimitry Andric} 23200b57cec5SDimitry Andric 23210b57cec5SDimitry Andric// reverse_copy 23220b57cec5SDimitry Andric 23230b57cec5SDimitry Andrictemplate <class _BidirectionalIterator, class _OutputIterator> 23240b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 23250b57cec5SDimitry Andric_OutputIterator 23260b57cec5SDimitry Andricreverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 23270b57cec5SDimitry Andric{ 23280b57cec5SDimitry Andric for (; __first != __last; ++__result) 23290b57cec5SDimitry Andric *__result = *--__last; 23300b57cec5SDimitry Andric return __result; 23310b57cec5SDimitry Andric} 23320b57cec5SDimitry Andric 23330b57cec5SDimitry Andric// rotate 23340b57cec5SDimitry Andric 23350b57cec5SDimitry Andrictemplate <class _ForwardIterator> 23360b57cec5SDimitry Andric_ForwardIterator 23370b57cec5SDimitry Andric__rotate_left(_ForwardIterator __first, _ForwardIterator __last) 23380b57cec5SDimitry Andric{ 23390b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type value_type; 23400b57cec5SDimitry Andric value_type __tmp = _VSTD::move(*__first); 23410b57cec5SDimitry Andric _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first); 23420b57cec5SDimitry Andric *__lm1 = _VSTD::move(__tmp); 23430b57cec5SDimitry Andric return __lm1; 23440b57cec5SDimitry Andric} 23450b57cec5SDimitry Andric 23460b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 23470b57cec5SDimitry Andric_BidirectionalIterator 23480b57cec5SDimitry Andric__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) 23490b57cec5SDimitry Andric{ 23500b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 23510b57cec5SDimitry Andric _BidirectionalIterator __lm1 = _VSTD::prev(__last); 23520b57cec5SDimitry Andric value_type __tmp = _VSTD::move(*__lm1); 23530b57cec5SDimitry Andric _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last); 23540b57cec5SDimitry Andric *__first = _VSTD::move(__tmp); 23550b57cec5SDimitry Andric return __fp1; 23560b57cec5SDimitry Andric} 23570b57cec5SDimitry Andric 23580b57cec5SDimitry Andrictemplate <class _ForwardIterator> 23590b57cec5SDimitry Andric_ForwardIterator 23600b57cec5SDimitry Andric__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) 23610b57cec5SDimitry Andric{ 23620b57cec5SDimitry Andric _ForwardIterator __i = __middle; 23630b57cec5SDimitry Andric while (true) 23640b57cec5SDimitry Andric { 23650b57cec5SDimitry Andric swap(*__first, *__i); 23660b57cec5SDimitry Andric ++__first; 23670b57cec5SDimitry Andric if (++__i == __last) 23680b57cec5SDimitry Andric break; 23690b57cec5SDimitry Andric if (__first == __middle) 23700b57cec5SDimitry Andric __middle = __i; 23710b57cec5SDimitry Andric } 23720b57cec5SDimitry Andric _ForwardIterator __r = __first; 23730b57cec5SDimitry Andric if (__first != __middle) 23740b57cec5SDimitry Andric { 23750b57cec5SDimitry Andric __i = __middle; 23760b57cec5SDimitry Andric while (true) 23770b57cec5SDimitry Andric { 23780b57cec5SDimitry Andric swap(*__first, *__i); 23790b57cec5SDimitry Andric ++__first; 23800b57cec5SDimitry Andric if (++__i == __last) 23810b57cec5SDimitry Andric { 23820b57cec5SDimitry Andric if (__first == __middle) 23830b57cec5SDimitry Andric break; 23840b57cec5SDimitry Andric __i = __middle; 23850b57cec5SDimitry Andric } 23860b57cec5SDimitry Andric else if (__first == __middle) 23870b57cec5SDimitry Andric __middle = __i; 23880b57cec5SDimitry Andric } 23890b57cec5SDimitry Andric } 23900b57cec5SDimitry Andric return __r; 23910b57cec5SDimitry Andric} 23920b57cec5SDimitry Andric 23930b57cec5SDimitry Andrictemplate<typename _Integral> 23940b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 23950b57cec5SDimitry Andric_Integral 23960b57cec5SDimitry Andric__algo_gcd(_Integral __x, _Integral __y) 23970b57cec5SDimitry Andric{ 23980b57cec5SDimitry Andric do 23990b57cec5SDimitry Andric { 24000b57cec5SDimitry Andric _Integral __t = __x % __y; 24010b57cec5SDimitry Andric __x = __y; 24020b57cec5SDimitry Andric __y = __t; 24030b57cec5SDimitry Andric } while (__y); 24040b57cec5SDimitry Andric return __x; 24050b57cec5SDimitry Andric} 24060b57cec5SDimitry Andric 24070b57cec5SDimitry Andrictemplate<typename _RandomAccessIterator> 24080b57cec5SDimitry Andric_RandomAccessIterator 24090b57cec5SDimitry Andric__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) 24100b57cec5SDimitry Andric{ 24110b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 24120b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 24130b57cec5SDimitry Andric 24140b57cec5SDimitry Andric const difference_type __m1 = __middle - __first; 24150b57cec5SDimitry Andric const difference_type __m2 = __last - __middle; 24160b57cec5SDimitry Andric if (__m1 == __m2) 24170b57cec5SDimitry Andric { 24180b57cec5SDimitry Andric _VSTD::swap_ranges(__first, __middle, __middle); 24190b57cec5SDimitry Andric return __middle; 24200b57cec5SDimitry Andric } 24210b57cec5SDimitry Andric const difference_type __g = _VSTD::__algo_gcd(__m1, __m2); 24220b57cec5SDimitry Andric for (_RandomAccessIterator __p = __first + __g; __p != __first;) 24230b57cec5SDimitry Andric { 24240b57cec5SDimitry Andric value_type __t(_VSTD::move(*--__p)); 24250b57cec5SDimitry Andric _RandomAccessIterator __p1 = __p; 24260b57cec5SDimitry Andric _RandomAccessIterator __p2 = __p1 + __m1; 24270b57cec5SDimitry Andric do 24280b57cec5SDimitry Andric { 24290b57cec5SDimitry Andric *__p1 = _VSTD::move(*__p2); 24300b57cec5SDimitry Andric __p1 = __p2; 24310b57cec5SDimitry Andric const difference_type __d = __last - __p2; 24320b57cec5SDimitry Andric if (__m1 < __d) 24330b57cec5SDimitry Andric __p2 += __m1; 24340b57cec5SDimitry Andric else 24350b57cec5SDimitry Andric __p2 = __first + (__m1 - __d); 24360b57cec5SDimitry Andric } while (__p2 != __p); 24370b57cec5SDimitry Andric *__p1 = _VSTD::move(__t); 24380b57cec5SDimitry Andric } 24390b57cec5SDimitry Andric return __first + __m2; 24400b57cec5SDimitry Andric} 24410b57cec5SDimitry Andric 24420b57cec5SDimitry Andrictemplate <class _ForwardIterator> 24430b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 24440b57cec5SDimitry Andric_ForwardIterator 24450b57cec5SDimitry Andric__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, 24460b57cec5SDimitry Andric _VSTD::forward_iterator_tag) 24470b57cec5SDimitry Andric{ 24480b57cec5SDimitry Andric typedef typename _VSTD::iterator_traits<_ForwardIterator>::value_type value_type; 24490b57cec5SDimitry Andric if (_VSTD::is_trivially_move_assignable<value_type>::value) 24500b57cec5SDimitry Andric { 24510b57cec5SDimitry Andric if (_VSTD::next(__first) == __middle) 24520b57cec5SDimitry Andric return _VSTD::__rotate_left(__first, __last); 24530b57cec5SDimitry Andric } 24540b57cec5SDimitry Andric return _VSTD::__rotate_forward(__first, __middle, __last); 24550b57cec5SDimitry Andric} 24560b57cec5SDimitry Andric 24570b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 24580b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 24590b57cec5SDimitry Andric_BidirectionalIterator 24600b57cec5SDimitry Andric__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 24610b57cec5SDimitry Andric _VSTD::bidirectional_iterator_tag) 24620b57cec5SDimitry Andric{ 24630b57cec5SDimitry Andric typedef typename _VSTD::iterator_traits<_BidirectionalIterator>::value_type value_type; 24640b57cec5SDimitry Andric if (_VSTD::is_trivially_move_assignable<value_type>::value) 24650b57cec5SDimitry Andric { 24660b57cec5SDimitry Andric if (_VSTD::next(__first) == __middle) 24670b57cec5SDimitry Andric return _VSTD::__rotate_left(__first, __last); 24680b57cec5SDimitry Andric if (_VSTD::next(__middle) == __last) 24690b57cec5SDimitry Andric return _VSTD::__rotate_right(__first, __last); 24700b57cec5SDimitry Andric } 24710b57cec5SDimitry Andric return _VSTD::__rotate_forward(__first, __middle, __last); 24720b57cec5SDimitry Andric} 24730b57cec5SDimitry Andric 24740b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 24750b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 24760b57cec5SDimitry Andric_RandomAccessIterator 24770b57cec5SDimitry Andric__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, 24780b57cec5SDimitry Andric _VSTD::random_access_iterator_tag) 24790b57cec5SDimitry Andric{ 24800b57cec5SDimitry Andric typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::value_type value_type; 24810b57cec5SDimitry Andric if (_VSTD::is_trivially_move_assignable<value_type>::value) 24820b57cec5SDimitry Andric { 24830b57cec5SDimitry Andric if (_VSTD::next(__first) == __middle) 24840b57cec5SDimitry Andric return _VSTD::__rotate_left(__first, __last); 24850b57cec5SDimitry Andric if (_VSTD::next(__middle) == __last) 24860b57cec5SDimitry Andric return _VSTD::__rotate_right(__first, __last); 24870b57cec5SDimitry Andric return _VSTD::__rotate_gcd(__first, __middle, __last); 24880b57cec5SDimitry Andric } 24890b57cec5SDimitry Andric return _VSTD::__rotate_forward(__first, __middle, __last); 24900b57cec5SDimitry Andric} 24910b57cec5SDimitry Andric 24920b57cec5SDimitry Andrictemplate <class _ForwardIterator> 24930b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 24940b57cec5SDimitry Andric_ForwardIterator 24950b57cec5SDimitry Andricrotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) 24960b57cec5SDimitry Andric{ 24970b57cec5SDimitry Andric if (__first == __middle) 24980b57cec5SDimitry Andric return __last; 24990b57cec5SDimitry Andric if (__middle == __last) 25000b57cec5SDimitry Andric return __first; 25010b57cec5SDimitry Andric return _VSTD::__rotate(__first, __middle, __last, 25020b57cec5SDimitry Andric typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category()); 25030b57cec5SDimitry Andric} 25040b57cec5SDimitry Andric 25050b57cec5SDimitry Andric// rotate_copy 25060b57cec5SDimitry Andric 25070b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _OutputIterator> 25080b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 25090b57cec5SDimitry Andric_OutputIterator 25100b57cec5SDimitry Andricrotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) 25110b57cec5SDimitry Andric{ 25120b57cec5SDimitry Andric return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result)); 25130b57cec5SDimitry Andric} 25140b57cec5SDimitry Andric 25150b57cec5SDimitry Andric// min_element 25160b57cec5SDimitry Andric 25170b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Compare> 25180b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 25190b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25200b57cec5SDimitry Andric_ForwardIterator 25210b57cec5SDimitry Andricmin_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 25220b57cec5SDimitry Andric{ 2523*480093f4SDimitry Andric static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, 25240b57cec5SDimitry Andric "std::min_element requires a ForwardIterator"); 25250b57cec5SDimitry Andric if (__first != __last) 25260b57cec5SDimitry Andric { 25270b57cec5SDimitry Andric _ForwardIterator __i = __first; 25280b57cec5SDimitry Andric while (++__i != __last) 25290b57cec5SDimitry Andric if (__comp(*__i, *__first)) 25300b57cec5SDimitry Andric __first = __i; 25310b57cec5SDimitry Andric } 25320b57cec5SDimitry Andric return __first; 25330b57cec5SDimitry Andric} 25340b57cec5SDimitry Andric 25350b57cec5SDimitry Andrictemplate <class _ForwardIterator> 25360b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 25370b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25380b57cec5SDimitry Andric_ForwardIterator 25390b57cec5SDimitry Andricmin_element(_ForwardIterator __first, _ForwardIterator __last) 25400b57cec5SDimitry Andric{ 25410b57cec5SDimitry Andric return _VSTD::min_element(__first, __last, 25420b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type>()); 25430b57cec5SDimitry Andric} 25440b57cec5SDimitry Andric 25450b57cec5SDimitry Andric// min 25460b57cec5SDimitry Andric 25470b57cec5SDimitry Andrictemplate <class _Tp, class _Compare> 25480b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 25490b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25500b57cec5SDimitry Andricconst _Tp& 25510b57cec5SDimitry Andricmin(const _Tp& __a, const _Tp& __b, _Compare __comp) 25520b57cec5SDimitry Andric{ 25530b57cec5SDimitry Andric return __comp(__b, __a) ? __b : __a; 25540b57cec5SDimitry Andric} 25550b57cec5SDimitry Andric 25560b57cec5SDimitry Andrictemplate <class _Tp> 25570b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 25580b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25590b57cec5SDimitry Andricconst _Tp& 25600b57cec5SDimitry Andricmin(const _Tp& __a, const _Tp& __b) 25610b57cec5SDimitry Andric{ 25620b57cec5SDimitry Andric return _VSTD::min(__a, __b, __less<_Tp>()); 25630b57cec5SDimitry Andric} 25640b57cec5SDimitry Andric 25650b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 25660b57cec5SDimitry Andric 25670b57cec5SDimitry Andrictemplate<class _Tp, class _Compare> 25680b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 25690b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25700b57cec5SDimitry Andric_Tp 25710b57cec5SDimitry Andricmin(initializer_list<_Tp> __t, _Compare __comp) 25720b57cec5SDimitry Andric{ 25730b57cec5SDimitry Andric return *_VSTD::min_element(__t.begin(), __t.end(), __comp); 25740b57cec5SDimitry Andric} 25750b57cec5SDimitry Andric 25760b57cec5SDimitry Andrictemplate<class _Tp> 25770b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 25780b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25790b57cec5SDimitry Andric_Tp 25800b57cec5SDimitry Andricmin(initializer_list<_Tp> __t) 25810b57cec5SDimitry Andric{ 25820b57cec5SDimitry Andric return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>()); 25830b57cec5SDimitry Andric} 25840b57cec5SDimitry Andric 25850b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 25860b57cec5SDimitry Andric 25870b57cec5SDimitry Andric// max_element 25880b57cec5SDimitry Andric 25890b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Compare> 25900b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 25910b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25920b57cec5SDimitry Andric_ForwardIterator 25930b57cec5SDimitry Andricmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 25940b57cec5SDimitry Andric{ 2595*480093f4SDimitry Andric static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, 25960b57cec5SDimitry Andric "std::max_element requires a ForwardIterator"); 25970b57cec5SDimitry Andric if (__first != __last) 25980b57cec5SDimitry Andric { 25990b57cec5SDimitry Andric _ForwardIterator __i = __first; 26000b57cec5SDimitry Andric while (++__i != __last) 26010b57cec5SDimitry Andric if (__comp(*__first, *__i)) 26020b57cec5SDimitry Andric __first = __i; 26030b57cec5SDimitry Andric } 26040b57cec5SDimitry Andric return __first; 26050b57cec5SDimitry Andric} 26060b57cec5SDimitry Andric 26070b57cec5SDimitry Andric 26080b57cec5SDimitry Andrictemplate <class _ForwardIterator> 26090b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 26100b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 26110b57cec5SDimitry Andric_ForwardIterator 26120b57cec5SDimitry Andricmax_element(_ForwardIterator __first, _ForwardIterator __last) 26130b57cec5SDimitry Andric{ 26140b57cec5SDimitry Andric return _VSTD::max_element(__first, __last, 26150b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type>()); 26160b57cec5SDimitry Andric} 26170b57cec5SDimitry Andric 26180b57cec5SDimitry Andric// max 26190b57cec5SDimitry Andric 26200b57cec5SDimitry Andrictemplate <class _Tp, class _Compare> 26210b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 26220b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 26230b57cec5SDimitry Andricconst _Tp& 26240b57cec5SDimitry Andricmax(const _Tp& __a, const _Tp& __b, _Compare __comp) 26250b57cec5SDimitry Andric{ 26260b57cec5SDimitry Andric return __comp(__a, __b) ? __b : __a; 26270b57cec5SDimitry Andric} 26280b57cec5SDimitry Andric 26290b57cec5SDimitry Andrictemplate <class _Tp> 26300b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 26310b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 26320b57cec5SDimitry Andricconst _Tp& 26330b57cec5SDimitry Andricmax(const _Tp& __a, const _Tp& __b) 26340b57cec5SDimitry Andric{ 26350b57cec5SDimitry Andric return _VSTD::max(__a, __b, __less<_Tp>()); 26360b57cec5SDimitry Andric} 26370b57cec5SDimitry Andric 26380b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 26390b57cec5SDimitry Andric 26400b57cec5SDimitry Andrictemplate<class _Tp, class _Compare> 26410b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 26420b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 26430b57cec5SDimitry Andric_Tp 26440b57cec5SDimitry Andricmax(initializer_list<_Tp> __t, _Compare __comp) 26450b57cec5SDimitry Andric{ 26460b57cec5SDimitry Andric return *_VSTD::max_element(__t.begin(), __t.end(), __comp); 26470b57cec5SDimitry Andric} 26480b57cec5SDimitry Andric 26490b57cec5SDimitry Andrictemplate<class _Tp> 26500b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 26510b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 26520b57cec5SDimitry Andric_Tp 26530b57cec5SDimitry Andricmax(initializer_list<_Tp> __t) 26540b57cec5SDimitry Andric{ 26550b57cec5SDimitry Andric return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>()); 26560b57cec5SDimitry Andric} 26570b57cec5SDimitry Andric 26580b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 26590b57cec5SDimitry Andric 26600b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 26610b57cec5SDimitry Andric// clamp 26620b57cec5SDimitry Andrictemplate<class _Tp, class _Compare> 26630b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 26640b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 26650b57cec5SDimitry Andricconst _Tp& 26660b57cec5SDimitry Andricclamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) 26670b57cec5SDimitry Andric{ 26680b57cec5SDimitry Andric _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp"); 26690b57cec5SDimitry Andric return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v; 26700b57cec5SDimitry Andric 26710b57cec5SDimitry Andric} 26720b57cec5SDimitry Andric 26730b57cec5SDimitry Andrictemplate<class _Tp> 26740b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 26750b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 26760b57cec5SDimitry Andricconst _Tp& 26770b57cec5SDimitry Andricclamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) 26780b57cec5SDimitry Andric{ 26790b57cec5SDimitry Andric return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>()); 26800b57cec5SDimitry Andric} 26810b57cec5SDimitry Andric#endif 26820b57cec5SDimitry Andric 26830b57cec5SDimitry Andric// minmax_element 26840b57cec5SDimitry Andric 26850b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Compare> 26860b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11 26870b57cec5SDimitry Andricstd::pair<_ForwardIterator, _ForwardIterator> 26880b57cec5SDimitry Andricminmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 26890b57cec5SDimitry Andric{ 2690*480093f4SDimitry Andric static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, 26910b57cec5SDimitry Andric "std::minmax_element requires a ForwardIterator"); 26920b57cec5SDimitry Andric std::pair<_ForwardIterator, _ForwardIterator> __result(__first, __first); 26930b57cec5SDimitry Andric if (__first != __last) 26940b57cec5SDimitry Andric { 26950b57cec5SDimitry Andric if (++__first != __last) 26960b57cec5SDimitry Andric { 26970b57cec5SDimitry Andric if (__comp(*__first, *__result.first)) 26980b57cec5SDimitry Andric __result.first = __first; 26990b57cec5SDimitry Andric else 27000b57cec5SDimitry Andric __result.second = __first; 27010b57cec5SDimitry Andric while (++__first != __last) 27020b57cec5SDimitry Andric { 27030b57cec5SDimitry Andric _ForwardIterator __i = __first; 27040b57cec5SDimitry Andric if (++__first == __last) 27050b57cec5SDimitry Andric { 27060b57cec5SDimitry Andric if (__comp(*__i, *__result.first)) 27070b57cec5SDimitry Andric __result.first = __i; 27080b57cec5SDimitry Andric else if (!__comp(*__i, *__result.second)) 27090b57cec5SDimitry Andric __result.second = __i; 27100b57cec5SDimitry Andric break; 27110b57cec5SDimitry Andric } 27120b57cec5SDimitry Andric else 27130b57cec5SDimitry Andric { 27140b57cec5SDimitry Andric if (__comp(*__first, *__i)) 27150b57cec5SDimitry Andric { 27160b57cec5SDimitry Andric if (__comp(*__first, *__result.first)) 27170b57cec5SDimitry Andric __result.first = __first; 27180b57cec5SDimitry Andric if (!__comp(*__i, *__result.second)) 27190b57cec5SDimitry Andric __result.second = __i; 27200b57cec5SDimitry Andric } 27210b57cec5SDimitry Andric else 27220b57cec5SDimitry Andric { 27230b57cec5SDimitry Andric if (__comp(*__i, *__result.first)) 27240b57cec5SDimitry Andric __result.first = __i; 27250b57cec5SDimitry Andric if (!__comp(*__first, *__result.second)) 27260b57cec5SDimitry Andric __result.second = __first; 27270b57cec5SDimitry Andric } 27280b57cec5SDimitry Andric } 27290b57cec5SDimitry Andric } 27300b57cec5SDimitry Andric } 27310b57cec5SDimitry Andric } 27320b57cec5SDimitry Andric return __result; 27330b57cec5SDimitry Andric} 27340b57cec5SDimitry Andric 27350b57cec5SDimitry Andrictemplate <class _ForwardIterator> 27360b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 27370b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 27380b57cec5SDimitry Andricstd::pair<_ForwardIterator, _ForwardIterator> 27390b57cec5SDimitry Andricminmax_element(_ForwardIterator __first, _ForwardIterator __last) 27400b57cec5SDimitry Andric{ 27410b57cec5SDimitry Andric return _VSTD::minmax_element(__first, __last, 27420b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type>()); 27430b57cec5SDimitry Andric} 27440b57cec5SDimitry Andric 27450b57cec5SDimitry Andric// minmax 27460b57cec5SDimitry Andric 27470b57cec5SDimitry Andrictemplate<class _Tp, class _Compare> 27480b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 27490b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 27500b57cec5SDimitry Andricpair<const _Tp&, const _Tp&> 27510b57cec5SDimitry Andricminmax(const _Tp& __a, const _Tp& __b, _Compare __comp) 27520b57cec5SDimitry Andric{ 27530b57cec5SDimitry Andric return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) : 27540b57cec5SDimitry Andric pair<const _Tp&, const _Tp&>(__a, __b); 27550b57cec5SDimitry Andric} 27560b57cec5SDimitry Andric 27570b57cec5SDimitry Andrictemplate<class _Tp> 27580b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 27590b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 27600b57cec5SDimitry Andricpair<const _Tp&, const _Tp&> 27610b57cec5SDimitry Andricminmax(const _Tp& __a, const _Tp& __b) 27620b57cec5SDimitry Andric{ 27630b57cec5SDimitry Andric return _VSTD::minmax(__a, __b, __less<_Tp>()); 27640b57cec5SDimitry Andric} 27650b57cec5SDimitry Andric 27660b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 27670b57cec5SDimitry Andric 27680b57cec5SDimitry Andrictemplate<class _Tp, class _Compare> 27690b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 27700b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 27710b57cec5SDimitry Andricpair<_Tp, _Tp> 27720b57cec5SDimitry Andricminmax(initializer_list<_Tp> __t, _Compare __comp) 27730b57cec5SDimitry Andric{ 27740b57cec5SDimitry Andric typedef typename initializer_list<_Tp>::const_iterator _Iter; 27750b57cec5SDimitry Andric _Iter __first = __t.begin(); 27760b57cec5SDimitry Andric _Iter __last = __t.end(); 27770b57cec5SDimitry Andric std::pair<_Tp, _Tp> __result(*__first, *__first); 27780b57cec5SDimitry Andric 27790b57cec5SDimitry Andric ++__first; 27800b57cec5SDimitry Andric if (__t.size() % 2 == 0) 27810b57cec5SDimitry Andric { 27820b57cec5SDimitry Andric if (__comp(*__first, __result.first)) 27830b57cec5SDimitry Andric __result.first = *__first; 27840b57cec5SDimitry Andric else 27850b57cec5SDimitry Andric __result.second = *__first; 27860b57cec5SDimitry Andric ++__first; 27870b57cec5SDimitry Andric } 27880b57cec5SDimitry Andric 27890b57cec5SDimitry Andric while (__first != __last) 27900b57cec5SDimitry Andric { 27910b57cec5SDimitry Andric _Tp __prev = *__first++; 27920b57cec5SDimitry Andric if (__comp(*__first, __prev)) { 27930b57cec5SDimitry Andric if ( __comp(*__first, __result.first)) __result.first = *__first; 27940b57cec5SDimitry Andric if (!__comp(__prev, __result.second)) __result.second = __prev; 27950b57cec5SDimitry Andric } 27960b57cec5SDimitry Andric else { 27970b57cec5SDimitry Andric if ( __comp(__prev, __result.first)) __result.first = __prev; 27980b57cec5SDimitry Andric if (!__comp(*__first, __result.second)) __result.second = *__first; 27990b57cec5SDimitry Andric } 28000b57cec5SDimitry Andric 28010b57cec5SDimitry Andric __first++; 28020b57cec5SDimitry Andric } 28030b57cec5SDimitry Andric return __result; 28040b57cec5SDimitry Andric} 28050b57cec5SDimitry Andric 28060b57cec5SDimitry Andrictemplate<class _Tp> 28070b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 28080b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 28090b57cec5SDimitry Andricpair<_Tp, _Tp> 28100b57cec5SDimitry Andricminmax(initializer_list<_Tp> __t) 28110b57cec5SDimitry Andric{ 28120b57cec5SDimitry Andric return _VSTD::minmax(__t, __less<_Tp>()); 28130b57cec5SDimitry Andric} 28140b57cec5SDimitry Andric 28150b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 28160b57cec5SDimitry Andric 28170b57cec5SDimitry Andric// random_shuffle 28180b57cec5SDimitry Andric 28190b57cec5SDimitry Andric// __independent_bits_engine 28200b57cec5SDimitry Andric 28210b57cec5SDimitry Andrictemplate <unsigned long long _Xp, size_t _Rp> 28220b57cec5SDimitry Andricstruct __log2_imp 28230b57cec5SDimitry Andric{ 28240b57cec5SDimitry Andric static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp 28250b57cec5SDimitry Andric : __log2_imp<_Xp, _Rp - 1>::value; 28260b57cec5SDimitry Andric}; 28270b57cec5SDimitry Andric 28280b57cec5SDimitry Andrictemplate <unsigned long long _Xp> 28290b57cec5SDimitry Andricstruct __log2_imp<_Xp, 0> 28300b57cec5SDimitry Andric{ 28310b57cec5SDimitry Andric static const size_t value = 0; 28320b57cec5SDimitry Andric}; 28330b57cec5SDimitry Andric 28340b57cec5SDimitry Andrictemplate <size_t _Rp> 28350b57cec5SDimitry Andricstruct __log2_imp<0, _Rp> 28360b57cec5SDimitry Andric{ 28370b57cec5SDimitry Andric static const size_t value = _Rp + 1; 28380b57cec5SDimitry Andric}; 28390b57cec5SDimitry Andric 28400b57cec5SDimitry Andrictemplate <class _UIntType, _UIntType _Xp> 28410b57cec5SDimitry Andricstruct __log2 28420b57cec5SDimitry Andric{ 28430b57cec5SDimitry Andric static const size_t value = __log2_imp<_Xp, 28440b57cec5SDimitry Andric sizeof(_UIntType) * __CHAR_BIT__ - 1>::value; 28450b57cec5SDimitry Andric}; 28460b57cec5SDimitry Andric 28470b57cec5SDimitry Andrictemplate<class _Engine, class _UIntType> 28480b57cec5SDimitry Andricclass __independent_bits_engine 28490b57cec5SDimitry Andric{ 28500b57cec5SDimitry Andricpublic: 28510b57cec5SDimitry Andric // types 28520b57cec5SDimitry Andric typedef _UIntType result_type; 28530b57cec5SDimitry Andric 28540b57cec5SDimitry Andricprivate: 28550b57cec5SDimitry Andric typedef typename _Engine::result_type _Engine_result_type; 28560b57cec5SDimitry Andric typedef typename conditional 28570b57cec5SDimitry Andric < 28580b57cec5SDimitry Andric sizeof(_Engine_result_type) <= sizeof(result_type), 28590b57cec5SDimitry Andric result_type, 28600b57cec5SDimitry Andric _Engine_result_type 28610b57cec5SDimitry Andric >::type _Working_result_type; 28620b57cec5SDimitry Andric 28630b57cec5SDimitry Andric _Engine& __e_; 28640b57cec5SDimitry Andric size_t __w_; 28650b57cec5SDimitry Andric size_t __w0_; 28660b57cec5SDimitry Andric size_t __n_; 28670b57cec5SDimitry Andric size_t __n0_; 28680b57cec5SDimitry Andric _Working_result_type __y0_; 28690b57cec5SDimitry Andric _Working_result_type __y1_; 28700b57cec5SDimitry Andric _Engine_result_type __mask0_; 28710b57cec5SDimitry Andric _Engine_result_type __mask1_; 28720b57cec5SDimitry Andric 28730b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG 28740b57cec5SDimitry Andric static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min 28750b57cec5SDimitry Andric + _Working_result_type(1); 28760b57cec5SDimitry Andric#else 28770b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min() 28780b57cec5SDimitry Andric + _Working_result_type(1); 28790b57cec5SDimitry Andric#endif 28800b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value; 28810b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits; 28820b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits; 28830b57cec5SDimitry Andric 28840b57cec5SDimitry Andricpublic: 28850b57cec5SDimitry Andric // constructors and seeding functions 28860b57cec5SDimitry Andric __independent_bits_engine(_Engine& __e, size_t __w); 28870b57cec5SDimitry Andric 28880b57cec5SDimitry Andric // generating functions 28890b57cec5SDimitry Andric result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());} 28900b57cec5SDimitry Andric 28910b57cec5SDimitry Andricprivate: 28920b57cec5SDimitry Andric result_type __eval(false_type); 28930b57cec5SDimitry Andric result_type __eval(true_type); 28940b57cec5SDimitry Andric}; 28950b57cec5SDimitry Andric 28960b57cec5SDimitry Andrictemplate<class _Engine, class _UIntType> 28970b57cec5SDimitry Andric__independent_bits_engine<_Engine, _UIntType> 28980b57cec5SDimitry Andric ::__independent_bits_engine(_Engine& __e, size_t __w) 28990b57cec5SDimitry Andric : __e_(__e), 29000b57cec5SDimitry Andric __w_(__w) 29010b57cec5SDimitry Andric{ 29020b57cec5SDimitry Andric __n_ = __w_ / __m + (__w_ % __m != 0); 29030b57cec5SDimitry Andric __w0_ = __w_ / __n_; 29040b57cec5SDimitry Andric if (_Rp == 0) 29050b57cec5SDimitry Andric __y0_ = _Rp; 29060b57cec5SDimitry Andric else if (__w0_ < _WDt) 29070b57cec5SDimitry Andric __y0_ = (_Rp >> __w0_) << __w0_; 29080b57cec5SDimitry Andric else 29090b57cec5SDimitry Andric __y0_ = 0; 29100b57cec5SDimitry Andric if (_Rp - __y0_ > __y0_ / __n_) 29110b57cec5SDimitry Andric { 29120b57cec5SDimitry Andric ++__n_; 29130b57cec5SDimitry Andric __w0_ = __w_ / __n_; 29140b57cec5SDimitry Andric if (__w0_ < _WDt) 29150b57cec5SDimitry Andric __y0_ = (_Rp >> __w0_) << __w0_; 29160b57cec5SDimitry Andric else 29170b57cec5SDimitry Andric __y0_ = 0; 29180b57cec5SDimitry Andric } 29190b57cec5SDimitry Andric __n0_ = __n_ - __w_ % __n_; 29200b57cec5SDimitry Andric if (__w0_ < _WDt - 1) 29210b57cec5SDimitry Andric __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1); 29220b57cec5SDimitry Andric else 29230b57cec5SDimitry Andric __y1_ = 0; 29240b57cec5SDimitry Andric __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) : 29250b57cec5SDimitry Andric _Engine_result_type(0); 29260b57cec5SDimitry Andric __mask1_ = __w0_ < _EDt - 1 ? 29270b57cec5SDimitry Andric _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) : 29280b57cec5SDimitry Andric _Engine_result_type(~0); 29290b57cec5SDimitry Andric} 29300b57cec5SDimitry Andric 29310b57cec5SDimitry Andrictemplate<class _Engine, class _UIntType> 29320b57cec5SDimitry Andricinline 29330b57cec5SDimitry Andric_UIntType 29340b57cec5SDimitry Andric__independent_bits_engine<_Engine, _UIntType>::__eval(false_type) 29350b57cec5SDimitry Andric{ 29360b57cec5SDimitry Andric return static_cast<result_type>(__e_() & __mask0_); 29370b57cec5SDimitry Andric} 29380b57cec5SDimitry Andric 29390b57cec5SDimitry Andrictemplate<class _Engine, class _UIntType> 29400b57cec5SDimitry Andric_UIntType 29410b57cec5SDimitry Andric__independent_bits_engine<_Engine, _UIntType>::__eval(true_type) 29420b57cec5SDimitry Andric{ 29430b57cec5SDimitry Andric const size_t _WRt = numeric_limits<result_type>::digits; 29440b57cec5SDimitry Andric result_type _Sp = 0; 29450b57cec5SDimitry Andric for (size_t __k = 0; __k < __n0_; ++__k) 29460b57cec5SDimitry Andric { 29470b57cec5SDimitry Andric _Engine_result_type __u; 29480b57cec5SDimitry Andric do 29490b57cec5SDimitry Andric { 29500b57cec5SDimitry Andric __u = __e_() - _Engine::min(); 29510b57cec5SDimitry Andric } while (__u >= __y0_); 29520b57cec5SDimitry Andric if (__w0_ < _WRt) 29530b57cec5SDimitry Andric _Sp <<= __w0_; 29540b57cec5SDimitry Andric else 29550b57cec5SDimitry Andric _Sp = 0; 29560b57cec5SDimitry Andric _Sp += __u & __mask0_; 29570b57cec5SDimitry Andric } 29580b57cec5SDimitry Andric for (size_t __k = __n0_; __k < __n_; ++__k) 29590b57cec5SDimitry Andric { 29600b57cec5SDimitry Andric _Engine_result_type __u; 29610b57cec5SDimitry Andric do 29620b57cec5SDimitry Andric { 29630b57cec5SDimitry Andric __u = __e_() - _Engine::min(); 29640b57cec5SDimitry Andric } while (__u >= __y1_); 29650b57cec5SDimitry Andric if (__w0_ < _WRt - 1) 29660b57cec5SDimitry Andric _Sp <<= __w0_ + 1; 29670b57cec5SDimitry Andric else 29680b57cec5SDimitry Andric _Sp = 0; 29690b57cec5SDimitry Andric _Sp += __u & __mask1_; 29700b57cec5SDimitry Andric } 29710b57cec5SDimitry Andric return _Sp; 29720b57cec5SDimitry Andric} 29730b57cec5SDimitry Andric 29740b57cec5SDimitry Andric// uniform_int_distribution 29750b57cec5SDimitry Andric 29760b57cec5SDimitry Andrictemplate<class _IntType = int> 29770b57cec5SDimitry Andricclass uniform_int_distribution 29780b57cec5SDimitry Andric{ 29790b57cec5SDimitry Andricpublic: 29800b57cec5SDimitry Andric // types 29810b57cec5SDimitry Andric typedef _IntType result_type; 29820b57cec5SDimitry Andric 29830b57cec5SDimitry Andric class param_type 29840b57cec5SDimitry Andric { 29850b57cec5SDimitry Andric result_type __a_; 29860b57cec5SDimitry Andric result_type __b_; 29870b57cec5SDimitry Andric public: 29880b57cec5SDimitry Andric typedef uniform_int_distribution distribution_type; 29890b57cec5SDimitry Andric 29900b57cec5SDimitry Andric explicit param_type(result_type __a = 0, 29910b57cec5SDimitry Andric result_type __b = numeric_limits<result_type>::max()) 29920b57cec5SDimitry Andric : __a_(__a), __b_(__b) {} 29930b57cec5SDimitry Andric 29940b57cec5SDimitry Andric result_type a() const {return __a_;} 29950b57cec5SDimitry Andric result_type b() const {return __b_;} 29960b57cec5SDimitry Andric 29970b57cec5SDimitry Andric friend bool operator==(const param_type& __x, const param_type& __y) 29980b57cec5SDimitry Andric {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} 29990b57cec5SDimitry Andric friend bool operator!=(const param_type& __x, const param_type& __y) 30000b57cec5SDimitry Andric {return !(__x == __y);} 30010b57cec5SDimitry Andric }; 30020b57cec5SDimitry Andric 30030b57cec5SDimitry Andricprivate: 30040b57cec5SDimitry Andric param_type __p_; 30050b57cec5SDimitry Andric 30060b57cec5SDimitry Andricpublic: 30070b57cec5SDimitry Andric // constructors and reset functions 30080b57cec5SDimitry Andric explicit uniform_int_distribution(result_type __a = 0, 30090b57cec5SDimitry Andric result_type __b = numeric_limits<result_type>::max()) 30100b57cec5SDimitry Andric : __p_(param_type(__a, __b)) {} 30110b57cec5SDimitry Andric explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {} 30120b57cec5SDimitry Andric void reset() {} 30130b57cec5SDimitry Andric 30140b57cec5SDimitry Andric // generating functions 30150b57cec5SDimitry Andric template<class _URNG> result_type operator()(_URNG& __g) 30160b57cec5SDimitry Andric {return (*this)(__g, __p_);} 30170b57cec5SDimitry Andric template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); 30180b57cec5SDimitry Andric 30190b57cec5SDimitry Andric // property functions 30200b57cec5SDimitry Andric result_type a() const {return __p_.a();} 30210b57cec5SDimitry Andric result_type b() const {return __p_.b();} 30220b57cec5SDimitry Andric 30230b57cec5SDimitry Andric param_type param() const {return __p_;} 30240b57cec5SDimitry Andric void param(const param_type& __p) {__p_ = __p;} 30250b57cec5SDimitry Andric 30260b57cec5SDimitry Andric result_type min() const {return a();} 30270b57cec5SDimitry Andric result_type max() const {return b();} 30280b57cec5SDimitry Andric 30290b57cec5SDimitry Andric friend bool operator==(const uniform_int_distribution& __x, 30300b57cec5SDimitry Andric const uniform_int_distribution& __y) 30310b57cec5SDimitry Andric {return __x.__p_ == __y.__p_;} 30320b57cec5SDimitry Andric friend bool operator!=(const uniform_int_distribution& __x, 30330b57cec5SDimitry Andric const uniform_int_distribution& __y) 30340b57cec5SDimitry Andric {return !(__x == __y);} 30350b57cec5SDimitry Andric}; 30360b57cec5SDimitry Andric 30370b57cec5SDimitry Andrictemplate<class _IntType> 30380b57cec5SDimitry Andrictemplate<class _URNG> 30390b57cec5SDimitry Andrictypename uniform_int_distribution<_IntType>::result_type 30400b57cec5SDimitry Andricuniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p) 30410b57cec5SDimitry Andric_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 30420b57cec5SDimitry Andric{ 30430b57cec5SDimitry Andric typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t), 30440b57cec5SDimitry Andric uint32_t, uint64_t>::type _UIntType; 30450b57cec5SDimitry Andric const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1); 30460b57cec5SDimitry Andric if (_Rp == 1) 30470b57cec5SDimitry Andric return __p.a(); 30480b57cec5SDimitry Andric const size_t _Dt = numeric_limits<_UIntType>::digits; 30490b57cec5SDimitry Andric typedef __independent_bits_engine<_URNG, _UIntType> _Eng; 30500b57cec5SDimitry Andric if (_Rp == 0) 30510b57cec5SDimitry Andric return static_cast<result_type>(_Eng(__g, _Dt)()); 30520b57cec5SDimitry Andric size_t __w = _Dt - __libcpp_clz(_Rp) - 1; 30530b57cec5SDimitry Andric if ((_Rp & (std::numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0) 30540b57cec5SDimitry Andric ++__w; 30550b57cec5SDimitry Andric _Eng __e(__g, __w); 30560b57cec5SDimitry Andric _UIntType __u; 30570b57cec5SDimitry Andric do 30580b57cec5SDimitry Andric { 30590b57cec5SDimitry Andric __u = __e(); 30600b57cec5SDimitry Andric } while (__u >= _Rp); 30610b57cec5SDimitry Andric return static_cast<result_type>(__u + __p.a()); 30620b57cec5SDimitry Andric} 30630b57cec5SDimitry Andric 30640b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \ 30650b57cec5SDimitry Andric || defined(_LIBCPP_BUILDING_LIBRARY) 30660b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __rs_default; 30670b57cec5SDimitry Andric 30680b57cec5SDimitry Andric_LIBCPP_FUNC_VIS __rs_default __rs_get(); 30690b57cec5SDimitry Andric 30700b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __rs_default 30710b57cec5SDimitry Andric{ 30720b57cec5SDimitry Andric static unsigned __c_; 30730b57cec5SDimitry Andric 30740b57cec5SDimitry Andric __rs_default(); 30750b57cec5SDimitry Andricpublic: 30760b57cec5SDimitry Andric typedef uint_fast32_t result_type; 30770b57cec5SDimitry Andric 30780b57cec5SDimitry Andric static const result_type _Min = 0; 30790b57cec5SDimitry Andric static const result_type _Max = 0xFFFFFFFF; 30800b57cec5SDimitry Andric 30810b57cec5SDimitry Andric __rs_default(const __rs_default&); 30820b57cec5SDimitry Andric ~__rs_default(); 30830b57cec5SDimitry Andric 30840b57cec5SDimitry Andric result_type operator()(); 30850b57cec5SDimitry Andric 30860b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR result_type min() {return _Min;} 30870b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR result_type max() {return _Max;} 30880b57cec5SDimitry Andric 30890b57cec5SDimitry Andric friend _LIBCPP_FUNC_VIS __rs_default __rs_get(); 30900b57cec5SDimitry Andric}; 30910b57cec5SDimitry Andric 30920b57cec5SDimitry Andric_LIBCPP_FUNC_VIS __rs_default __rs_get(); 30930b57cec5SDimitry Andric 30940b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 30950b57cec5SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX14 void 30960b57cec5SDimitry Andricrandom_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) 30970b57cec5SDimitry Andric{ 30980b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 30990b57cec5SDimitry Andric typedef uniform_int_distribution<ptrdiff_t> _Dp; 31000b57cec5SDimitry Andric typedef typename _Dp::param_type _Pp; 31010b57cec5SDimitry Andric difference_type __d = __last - __first; 31020b57cec5SDimitry Andric if (__d > 1) 31030b57cec5SDimitry Andric { 31040b57cec5SDimitry Andric _Dp __uid; 31050b57cec5SDimitry Andric __rs_default __g = __rs_get(); 31060b57cec5SDimitry Andric for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) 31070b57cec5SDimitry Andric { 31080b57cec5SDimitry Andric difference_type __i = __uid(__g, _Pp(0, __d)); 31090b57cec5SDimitry Andric if (__i != difference_type(0)) 31100b57cec5SDimitry Andric swap(*__first, *(__first + __i)); 31110b57cec5SDimitry Andric } 31120b57cec5SDimitry Andric } 31130b57cec5SDimitry Andric} 31140b57cec5SDimitry Andric 31150b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _RandomNumberGenerator> 31160b57cec5SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX14 void 31170b57cec5SDimitry Andricrandom_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, 31180b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 31190b57cec5SDimitry Andric _RandomNumberGenerator&& __rand) 31200b57cec5SDimitry Andric#else 31210b57cec5SDimitry Andric _RandomNumberGenerator& __rand) 31220b57cec5SDimitry Andric#endif 31230b57cec5SDimitry Andric{ 31240b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 31250b57cec5SDimitry Andric difference_type __d = __last - __first; 31260b57cec5SDimitry Andric if (__d > 1) 31270b57cec5SDimitry Andric { 31280b57cec5SDimitry Andric for (--__last; __first < __last; ++__first, (void) --__d) 31290b57cec5SDimitry Andric { 31300b57cec5SDimitry Andric difference_type __i = __rand(__d); 31310b57cec5SDimitry Andric if (__i != difference_type(0)) 31320b57cec5SDimitry Andric swap(*__first, *(__first + __i)); 31330b57cec5SDimitry Andric } 31340b57cec5SDimitry Andric } 31350b57cec5SDimitry Andric} 31360b57cec5SDimitry Andric#endif 31370b57cec5SDimitry Andric 31380b57cec5SDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 31390b57cec5SDimitry Andric class _UniformRandomNumberGenerator> 31400b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 31410b57cec5SDimitry Andric_SampleIterator __sample(_PopulationIterator __first, 31420b57cec5SDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 31430b57cec5SDimitry Andric _Distance __n, 31440b57cec5SDimitry Andric _UniformRandomNumberGenerator & __g, 31450b57cec5SDimitry Andric input_iterator_tag) { 31460b57cec5SDimitry Andric 31470b57cec5SDimitry Andric _Distance __k = 0; 31480b57cec5SDimitry Andric for (; __first != __last && __k < __n; ++__first, (void) ++__k) 31490b57cec5SDimitry Andric __output_iter[__k] = *__first; 31500b57cec5SDimitry Andric _Distance __sz = __k; 31510b57cec5SDimitry Andric for (; __first != __last; ++__first, (void) ++__k) { 31520b57cec5SDimitry Andric _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g); 31530b57cec5SDimitry Andric if (__r < __sz) 31540b57cec5SDimitry Andric __output_iter[__r] = *__first; 31550b57cec5SDimitry Andric } 31560b57cec5SDimitry Andric return __output_iter + _VSTD::min(__n, __k); 31570b57cec5SDimitry Andric} 31580b57cec5SDimitry Andric 31590b57cec5SDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 31600b57cec5SDimitry Andric class _UniformRandomNumberGenerator> 31610b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 31620b57cec5SDimitry Andric_SampleIterator __sample(_PopulationIterator __first, 31630b57cec5SDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 31640b57cec5SDimitry Andric _Distance __n, 31650b57cec5SDimitry Andric _UniformRandomNumberGenerator& __g, 31660b57cec5SDimitry Andric forward_iterator_tag) { 31670b57cec5SDimitry Andric _Distance __unsampled_sz = _VSTD::distance(__first, __last); 31680b57cec5SDimitry Andric for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { 31690b57cec5SDimitry Andric _Distance __r = 31700b57cec5SDimitry Andric _VSTD::uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); 31710b57cec5SDimitry Andric if (__r < __n) { 31720b57cec5SDimitry Andric *__output_iter++ = *__first; 31730b57cec5SDimitry Andric --__n; 31740b57cec5SDimitry Andric } 31750b57cec5SDimitry Andric } 31760b57cec5SDimitry Andric return __output_iter; 31770b57cec5SDimitry Andric} 31780b57cec5SDimitry Andric 31790b57cec5SDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 31800b57cec5SDimitry Andric class _UniformRandomNumberGenerator> 31810b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 31820b57cec5SDimitry Andric_SampleIterator __sample(_PopulationIterator __first, 31830b57cec5SDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 31840b57cec5SDimitry Andric _Distance __n, _UniformRandomNumberGenerator& __g) { 31850b57cec5SDimitry Andric typedef typename iterator_traits<_PopulationIterator>::iterator_category 31860b57cec5SDimitry Andric _PopCategory; 31870b57cec5SDimitry Andric typedef typename iterator_traits<_PopulationIterator>::difference_type 31880b57cec5SDimitry Andric _Difference; 3189*480093f4SDimitry Andric static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value || 3190*480093f4SDimitry Andric __is_cpp17_random_access_iterator<_SampleIterator>::value, 31910b57cec5SDimitry Andric "SampleIterator must meet the requirements of RandomAccessIterator"); 31920b57cec5SDimitry Andric typedef typename common_type<_Distance, _Difference>::type _CommonType; 31930b57cec5SDimitry Andric _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); 31940b57cec5SDimitry Andric return _VSTD::__sample( 31950b57cec5SDimitry Andric __first, __last, __output_iter, _CommonType(__n), 31960b57cec5SDimitry Andric __g, _PopCategory()); 31970b57cec5SDimitry Andric} 31980b57cec5SDimitry Andric 31990b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 32000b57cec5SDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 32010b57cec5SDimitry Andric class _UniformRandomNumberGenerator> 32020b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 32030b57cec5SDimitry Andric_SampleIterator sample(_PopulationIterator __first, 32040b57cec5SDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 32050b57cec5SDimitry Andric _Distance __n, _UniformRandomNumberGenerator&& __g) { 32060b57cec5SDimitry Andric return _VSTD::__sample(__first, __last, __output_iter, __n, __g); 32070b57cec5SDimitry Andric} 32080b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14 32090b57cec5SDimitry Andric 32100b57cec5SDimitry Andrictemplate<class _RandomAccessIterator, class _UniformRandomNumberGenerator> 32110b57cec5SDimitry Andric void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, 32120b57cec5SDimitry Andric _UniformRandomNumberGenerator&& __g) 32130b57cec5SDimitry Andric{ 32140b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 32150b57cec5SDimitry Andric typedef uniform_int_distribution<ptrdiff_t> _Dp; 32160b57cec5SDimitry Andric typedef typename _Dp::param_type _Pp; 32170b57cec5SDimitry Andric difference_type __d = __last - __first; 32180b57cec5SDimitry Andric if (__d > 1) 32190b57cec5SDimitry Andric { 32200b57cec5SDimitry Andric _Dp __uid; 3221e40139ffSDimitry Andric for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) 32220b57cec5SDimitry Andric { 32230b57cec5SDimitry Andric difference_type __i = __uid(__g, _Pp(0, __d)); 32240b57cec5SDimitry Andric if (__i != difference_type(0)) 32250b57cec5SDimitry Andric swap(*__first, *(__first + __i)); 32260b57cec5SDimitry Andric } 32270b57cec5SDimitry Andric } 32280b57cec5SDimitry Andric} 32290b57cec5SDimitry Andric 32300b57cec5SDimitry Andrictemplate <class _InputIterator, class _Predicate> 32310b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool 32320b57cec5SDimitry Andricis_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) 32330b57cec5SDimitry Andric{ 32340b57cec5SDimitry Andric for (; __first != __last; ++__first) 32350b57cec5SDimitry Andric if (!__pred(*__first)) 32360b57cec5SDimitry Andric break; 32370b57cec5SDimitry Andric if ( __first == __last ) 32380b57cec5SDimitry Andric return true; 32390b57cec5SDimitry Andric ++__first; 32400b57cec5SDimitry Andric for (; __first != __last; ++__first) 32410b57cec5SDimitry Andric if (__pred(*__first)) 32420b57cec5SDimitry Andric return false; 32430b57cec5SDimitry Andric return true; 32440b57cec5SDimitry Andric} 32450b57cec5SDimitry Andric 32460b57cec5SDimitry Andric// partition 32470b57cec5SDimitry Andric 32480b57cec5SDimitry Andrictemplate <class _Predicate, class _ForwardIterator> 32490b57cec5SDimitry Andric_ForwardIterator 32500b57cec5SDimitry Andric__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) 32510b57cec5SDimitry Andric{ 32520b57cec5SDimitry Andric while (true) 32530b57cec5SDimitry Andric { 32540b57cec5SDimitry Andric if (__first == __last) 32550b57cec5SDimitry Andric return __first; 32560b57cec5SDimitry Andric if (!__pred(*__first)) 32570b57cec5SDimitry Andric break; 32580b57cec5SDimitry Andric ++__first; 32590b57cec5SDimitry Andric } 32600b57cec5SDimitry Andric for (_ForwardIterator __p = __first; ++__p != __last;) 32610b57cec5SDimitry Andric { 32620b57cec5SDimitry Andric if (__pred(*__p)) 32630b57cec5SDimitry Andric { 32640b57cec5SDimitry Andric swap(*__first, *__p); 32650b57cec5SDimitry Andric ++__first; 32660b57cec5SDimitry Andric } 32670b57cec5SDimitry Andric } 32680b57cec5SDimitry Andric return __first; 32690b57cec5SDimitry Andric} 32700b57cec5SDimitry Andric 32710b57cec5SDimitry Andrictemplate <class _Predicate, class _BidirectionalIterator> 32720b57cec5SDimitry Andric_BidirectionalIterator 32730b57cec5SDimitry Andric__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, 32740b57cec5SDimitry Andric bidirectional_iterator_tag) 32750b57cec5SDimitry Andric{ 32760b57cec5SDimitry Andric while (true) 32770b57cec5SDimitry Andric { 32780b57cec5SDimitry Andric while (true) 32790b57cec5SDimitry Andric { 32800b57cec5SDimitry Andric if (__first == __last) 32810b57cec5SDimitry Andric return __first; 32820b57cec5SDimitry Andric if (!__pred(*__first)) 32830b57cec5SDimitry Andric break; 32840b57cec5SDimitry Andric ++__first; 32850b57cec5SDimitry Andric } 32860b57cec5SDimitry Andric do 32870b57cec5SDimitry Andric { 32880b57cec5SDimitry Andric if (__first == --__last) 32890b57cec5SDimitry Andric return __first; 32900b57cec5SDimitry Andric } while (!__pred(*__last)); 32910b57cec5SDimitry Andric swap(*__first, *__last); 32920b57cec5SDimitry Andric ++__first; 32930b57cec5SDimitry Andric } 32940b57cec5SDimitry Andric} 32950b57cec5SDimitry Andric 32960b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Predicate> 32970b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 32980b57cec5SDimitry Andric_ForwardIterator 32990b57cec5SDimitry Andricpartition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 33000b57cec5SDimitry Andric{ 33010b57cec5SDimitry Andric return _VSTD::__partition<typename add_lvalue_reference<_Predicate>::type> 33020b57cec5SDimitry Andric (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); 33030b57cec5SDimitry Andric} 33040b57cec5SDimitry Andric 33050b57cec5SDimitry Andric// partition_copy 33060b57cec5SDimitry Andric 33070b57cec5SDimitry Andrictemplate <class _InputIterator, class _OutputIterator1, 33080b57cec5SDimitry Andric class _OutputIterator2, class _Predicate> 33090b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_OutputIterator1, _OutputIterator2> 33100b57cec5SDimitry Andricpartition_copy(_InputIterator __first, _InputIterator __last, 33110b57cec5SDimitry Andric _OutputIterator1 __out_true, _OutputIterator2 __out_false, 33120b57cec5SDimitry Andric _Predicate __pred) 33130b57cec5SDimitry Andric{ 33140b57cec5SDimitry Andric for (; __first != __last; ++__first) 33150b57cec5SDimitry Andric { 33160b57cec5SDimitry Andric if (__pred(*__first)) 33170b57cec5SDimitry Andric { 33180b57cec5SDimitry Andric *__out_true = *__first; 33190b57cec5SDimitry Andric ++__out_true; 33200b57cec5SDimitry Andric } 33210b57cec5SDimitry Andric else 33220b57cec5SDimitry Andric { 33230b57cec5SDimitry Andric *__out_false = *__first; 33240b57cec5SDimitry Andric ++__out_false; 33250b57cec5SDimitry Andric } 33260b57cec5SDimitry Andric } 33270b57cec5SDimitry Andric return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); 33280b57cec5SDimitry Andric} 33290b57cec5SDimitry Andric 33300b57cec5SDimitry Andric// partition_point 33310b57cec5SDimitry Andric 33320b57cec5SDimitry Andrictemplate<class _ForwardIterator, class _Predicate> 33330b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 33340b57cec5SDimitry Andricpartition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 33350b57cec5SDimitry Andric{ 33360b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 33370b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last); 33380b57cec5SDimitry Andric while (__len != 0) 33390b57cec5SDimitry Andric { 33400b57cec5SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 33410b57cec5SDimitry Andric _ForwardIterator __m = __first; 33420b57cec5SDimitry Andric _VSTD::advance(__m, __l2); 33430b57cec5SDimitry Andric if (__pred(*__m)) 33440b57cec5SDimitry Andric { 33450b57cec5SDimitry Andric __first = ++__m; 33460b57cec5SDimitry Andric __len -= __l2 + 1; 33470b57cec5SDimitry Andric } 33480b57cec5SDimitry Andric else 33490b57cec5SDimitry Andric __len = __l2; 33500b57cec5SDimitry Andric } 33510b57cec5SDimitry Andric return __first; 33520b57cec5SDimitry Andric} 33530b57cec5SDimitry Andric 33540b57cec5SDimitry Andric// stable_partition 33550b57cec5SDimitry Andric 33560b57cec5SDimitry Andrictemplate <class _Predicate, class _ForwardIterator, class _Distance, class _Pair> 33570b57cec5SDimitry Andric_ForwardIterator 33580b57cec5SDimitry Andric__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, 33590b57cec5SDimitry Andric _Distance __len, _Pair __p, forward_iterator_tag __fit) 33600b57cec5SDimitry Andric{ 33610b57cec5SDimitry Andric // *__first is known to be false 33620b57cec5SDimitry Andric // __len >= 1 33630b57cec5SDimitry Andric if (__len == 1) 33640b57cec5SDimitry Andric return __first; 33650b57cec5SDimitry Andric if (__len == 2) 33660b57cec5SDimitry Andric { 33670b57cec5SDimitry Andric _ForwardIterator __m = __first; 33680b57cec5SDimitry Andric if (__pred(*++__m)) 33690b57cec5SDimitry Andric { 33700b57cec5SDimitry Andric swap(*__first, *__m); 33710b57cec5SDimitry Andric return __m; 33720b57cec5SDimitry Andric } 33730b57cec5SDimitry Andric return __first; 33740b57cec5SDimitry Andric } 33750b57cec5SDimitry Andric if (__len <= __p.second) 33760b57cec5SDimitry Andric { // The buffer is big enough to use 33770b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type value_type; 33780b57cec5SDimitry Andric __destruct_n __d(0); 33790b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h(__p.first, __d); 33800b57cec5SDimitry Andric // Move the falses into the temporary buffer, and the trues to the front of the line 33810b57cec5SDimitry Andric // Update __first to always point to the end of the trues 33820b57cec5SDimitry Andric value_type* __t = __p.first; 33830b57cec5SDimitry Andric ::new(__t) value_type(_VSTD::move(*__first)); 33840b57cec5SDimitry Andric __d.__incr((value_type*)0); 33850b57cec5SDimitry Andric ++__t; 33860b57cec5SDimitry Andric _ForwardIterator __i = __first; 33870b57cec5SDimitry Andric while (++__i != __last) 33880b57cec5SDimitry Andric { 33890b57cec5SDimitry Andric if (__pred(*__i)) 33900b57cec5SDimitry Andric { 33910b57cec5SDimitry Andric *__first = _VSTD::move(*__i); 33920b57cec5SDimitry Andric ++__first; 33930b57cec5SDimitry Andric } 33940b57cec5SDimitry Andric else 33950b57cec5SDimitry Andric { 33960b57cec5SDimitry Andric ::new(__t) value_type(_VSTD::move(*__i)); 33970b57cec5SDimitry Andric __d.__incr((value_type*)0); 33980b57cec5SDimitry Andric ++__t; 33990b57cec5SDimitry Andric } 34000b57cec5SDimitry Andric } 34010b57cec5SDimitry Andric // All trues now at start of range, all falses in buffer 34020b57cec5SDimitry Andric // Move falses back into range, but don't mess up __first which points to first false 34030b57cec5SDimitry Andric __i = __first; 3404e40139ffSDimitry Andric for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) 34050b57cec5SDimitry Andric *__i = _VSTD::move(*__t2); 34060b57cec5SDimitry Andric // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer 34070b57cec5SDimitry Andric return __first; 34080b57cec5SDimitry Andric } 34090b57cec5SDimitry Andric // Else not enough buffer, do in place 34100b57cec5SDimitry Andric // __len >= 3 34110b57cec5SDimitry Andric _ForwardIterator __m = __first; 34120b57cec5SDimitry Andric _Distance __len2 = __len / 2; // __len2 >= 2 34130b57cec5SDimitry Andric _VSTD::advance(__m, __len2); 34140b57cec5SDimitry Andric // recurse on [__first, __m), *__first know to be false 34150b57cec5SDimitry Andric // F????????????????? 34160b57cec5SDimitry Andric // f m l 34170b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Predicate>::type _PredRef; 34180b57cec5SDimitry Andric _ForwardIterator __first_false = __stable_partition<_PredRef>(__first, __m, __pred, __len2, __p, __fit); 34190b57cec5SDimitry Andric // TTTFFFFF?????????? 34200b57cec5SDimitry Andric // f ff m l 34210b57cec5SDimitry Andric // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true 34220b57cec5SDimitry Andric _ForwardIterator __m1 = __m; 34230b57cec5SDimitry Andric _ForwardIterator __second_false = __last; 34240b57cec5SDimitry Andric _Distance __len_half = __len - __len2; 34250b57cec5SDimitry Andric while (__pred(*__m1)) 34260b57cec5SDimitry Andric { 34270b57cec5SDimitry Andric if (++__m1 == __last) 34280b57cec5SDimitry Andric goto __second_half_done; 34290b57cec5SDimitry Andric --__len_half; 34300b57cec5SDimitry Andric } 34310b57cec5SDimitry Andric // TTTFFFFFTTTF?????? 34320b57cec5SDimitry Andric // f ff m m1 l 34330b57cec5SDimitry Andric __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __fit); 34340b57cec5SDimitry Andric__second_half_done: 34350b57cec5SDimitry Andric // TTTFFFFFTTTTTFFFFF 34360b57cec5SDimitry Andric // f ff m sf l 34370b57cec5SDimitry Andric return _VSTD::rotate(__first_false, __m, __second_false); 34380b57cec5SDimitry Andric // TTTTTTTTFFFFFFFFFF 34390b57cec5SDimitry Andric // | 34400b57cec5SDimitry Andric} 34410b57cec5SDimitry Andric 34420b57cec5SDimitry Andricstruct __return_temporary_buffer 34430b57cec5SDimitry Andric{ 34440b57cec5SDimitry Andric template <class _Tp> 34450b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);} 34460b57cec5SDimitry Andric}; 34470b57cec5SDimitry Andric 34480b57cec5SDimitry Andrictemplate <class _Predicate, class _ForwardIterator> 34490b57cec5SDimitry Andric_ForwardIterator 34500b57cec5SDimitry Andric__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, 34510b57cec5SDimitry Andric forward_iterator_tag) 34520b57cec5SDimitry Andric{ 34530b57cec5SDimitry Andric const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment 34540b57cec5SDimitry Andric // Either prove all true and return __first or point to first false 34550b57cec5SDimitry Andric while (true) 34560b57cec5SDimitry Andric { 34570b57cec5SDimitry Andric if (__first == __last) 34580b57cec5SDimitry Andric return __first; 34590b57cec5SDimitry Andric if (!__pred(*__first)) 34600b57cec5SDimitry Andric break; 34610b57cec5SDimitry Andric ++__first; 34620b57cec5SDimitry Andric } 34630b57cec5SDimitry Andric // We now have a reduced range [__first, __last) 34640b57cec5SDimitry Andric // *__first is known to be false 34650b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 34660b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type value_type; 34670b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last); 34680b57cec5SDimitry Andric pair<value_type*, ptrdiff_t> __p(0, 0); 34690b57cec5SDimitry Andric unique_ptr<value_type, __return_temporary_buffer> __h; 34700b57cec5SDimitry Andric if (__len >= __alloc_limit) 34710b57cec5SDimitry Andric { 34720b57cec5SDimitry Andric __p = _VSTD::get_temporary_buffer<value_type>(__len); 34730b57cec5SDimitry Andric __h.reset(__p.first); 34740b57cec5SDimitry Andric } 34750b57cec5SDimitry Andric return __stable_partition<typename add_lvalue_reference<_Predicate>::type> 34760b57cec5SDimitry Andric (__first, __last, __pred, __len, __p, forward_iterator_tag()); 34770b57cec5SDimitry Andric} 34780b57cec5SDimitry Andric 34790b57cec5SDimitry Andrictemplate <class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair> 34800b57cec5SDimitry Andric_BidirectionalIterator 34810b57cec5SDimitry Andric__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, 34820b57cec5SDimitry Andric _Distance __len, _Pair __p, bidirectional_iterator_tag __bit) 34830b57cec5SDimitry Andric{ 34840b57cec5SDimitry Andric // *__first is known to be false 34850b57cec5SDimitry Andric // *__last is known to be true 34860b57cec5SDimitry Andric // __len >= 2 34870b57cec5SDimitry Andric if (__len == 2) 34880b57cec5SDimitry Andric { 34890b57cec5SDimitry Andric swap(*__first, *__last); 34900b57cec5SDimitry Andric return __last; 34910b57cec5SDimitry Andric } 34920b57cec5SDimitry Andric if (__len == 3) 34930b57cec5SDimitry Andric { 34940b57cec5SDimitry Andric _BidirectionalIterator __m = __first; 34950b57cec5SDimitry Andric if (__pred(*++__m)) 34960b57cec5SDimitry Andric { 34970b57cec5SDimitry Andric swap(*__first, *__m); 34980b57cec5SDimitry Andric swap(*__m, *__last); 34990b57cec5SDimitry Andric return __last; 35000b57cec5SDimitry Andric } 35010b57cec5SDimitry Andric swap(*__m, *__last); 35020b57cec5SDimitry Andric swap(*__first, *__m); 35030b57cec5SDimitry Andric return __m; 35040b57cec5SDimitry Andric } 35050b57cec5SDimitry Andric if (__len <= __p.second) 35060b57cec5SDimitry Andric { // The buffer is big enough to use 35070b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 35080b57cec5SDimitry Andric __destruct_n __d(0); 35090b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h(__p.first, __d); 35100b57cec5SDimitry Andric // Move the falses into the temporary buffer, and the trues to the front of the line 35110b57cec5SDimitry Andric // Update __first to always point to the end of the trues 35120b57cec5SDimitry Andric value_type* __t = __p.first; 35130b57cec5SDimitry Andric ::new(__t) value_type(_VSTD::move(*__first)); 35140b57cec5SDimitry Andric __d.__incr((value_type*)0); 35150b57cec5SDimitry Andric ++__t; 35160b57cec5SDimitry Andric _BidirectionalIterator __i = __first; 35170b57cec5SDimitry Andric while (++__i != __last) 35180b57cec5SDimitry Andric { 35190b57cec5SDimitry Andric if (__pred(*__i)) 35200b57cec5SDimitry Andric { 35210b57cec5SDimitry Andric *__first = _VSTD::move(*__i); 35220b57cec5SDimitry Andric ++__first; 35230b57cec5SDimitry Andric } 35240b57cec5SDimitry Andric else 35250b57cec5SDimitry Andric { 35260b57cec5SDimitry Andric ::new(__t) value_type(_VSTD::move(*__i)); 35270b57cec5SDimitry Andric __d.__incr((value_type*)0); 35280b57cec5SDimitry Andric ++__t; 35290b57cec5SDimitry Andric } 35300b57cec5SDimitry Andric } 35310b57cec5SDimitry Andric // move *__last, known to be true 35320b57cec5SDimitry Andric *__first = _VSTD::move(*__i); 35330b57cec5SDimitry Andric __i = ++__first; 35340b57cec5SDimitry Andric // All trues now at start of range, all falses in buffer 35350b57cec5SDimitry Andric // Move falses back into range, but don't mess up __first which points to first false 3536e40139ffSDimitry Andric for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) 35370b57cec5SDimitry Andric *__i = _VSTD::move(*__t2); 35380b57cec5SDimitry Andric // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer 35390b57cec5SDimitry Andric return __first; 35400b57cec5SDimitry Andric } 35410b57cec5SDimitry Andric // Else not enough buffer, do in place 35420b57cec5SDimitry Andric // __len >= 4 35430b57cec5SDimitry Andric _BidirectionalIterator __m = __first; 35440b57cec5SDimitry Andric _Distance __len2 = __len / 2; // __len2 >= 2 35450b57cec5SDimitry Andric _VSTD::advance(__m, __len2); 35460b57cec5SDimitry Andric // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false 35470b57cec5SDimitry Andric // F????????????????T 35480b57cec5SDimitry Andric // f m l 35490b57cec5SDimitry Andric _BidirectionalIterator __m1 = __m; 35500b57cec5SDimitry Andric _BidirectionalIterator __first_false = __first; 35510b57cec5SDimitry Andric _Distance __len_half = __len2; 35520b57cec5SDimitry Andric while (!__pred(*--__m1)) 35530b57cec5SDimitry Andric { 35540b57cec5SDimitry Andric if (__m1 == __first) 35550b57cec5SDimitry Andric goto __first_half_done; 35560b57cec5SDimitry Andric --__len_half; 35570b57cec5SDimitry Andric } 35580b57cec5SDimitry Andric // F???TFFF?????????T 35590b57cec5SDimitry Andric // f m1 m l 35600b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Predicate>::type _PredRef; 35610b57cec5SDimitry Andric __first_false = __stable_partition<_PredRef>(__first, __m1, __pred, __len_half, __p, __bit); 35620b57cec5SDimitry Andric__first_half_done: 35630b57cec5SDimitry Andric // TTTFFFFF?????????T 35640b57cec5SDimitry Andric // f ff m l 35650b57cec5SDimitry Andric // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true 35660b57cec5SDimitry Andric __m1 = __m; 35670b57cec5SDimitry Andric _BidirectionalIterator __second_false = __last; 35680b57cec5SDimitry Andric ++__second_false; 35690b57cec5SDimitry Andric __len_half = __len - __len2; 35700b57cec5SDimitry Andric while (__pred(*__m1)) 35710b57cec5SDimitry Andric { 35720b57cec5SDimitry Andric if (++__m1 == __last) 35730b57cec5SDimitry Andric goto __second_half_done; 35740b57cec5SDimitry Andric --__len_half; 35750b57cec5SDimitry Andric } 35760b57cec5SDimitry Andric // TTTFFFFFTTTF?????T 35770b57cec5SDimitry Andric // f ff m m1 l 35780b57cec5SDimitry Andric __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __bit); 35790b57cec5SDimitry Andric__second_half_done: 35800b57cec5SDimitry Andric // TTTFFFFFTTTTTFFFFF 35810b57cec5SDimitry Andric // f ff m sf l 35820b57cec5SDimitry Andric return _VSTD::rotate(__first_false, __m, __second_false); 35830b57cec5SDimitry Andric // TTTTTTTTFFFFFFFFFF 35840b57cec5SDimitry Andric // | 35850b57cec5SDimitry Andric} 35860b57cec5SDimitry Andric 35870b57cec5SDimitry Andrictemplate <class _Predicate, class _BidirectionalIterator> 35880b57cec5SDimitry Andric_BidirectionalIterator 35890b57cec5SDimitry Andric__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, 35900b57cec5SDimitry Andric bidirectional_iterator_tag) 35910b57cec5SDimitry Andric{ 35920b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; 35930b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 35940b57cec5SDimitry Andric const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment 35950b57cec5SDimitry Andric // Either prove all true and return __first or point to first false 35960b57cec5SDimitry Andric while (true) 35970b57cec5SDimitry Andric { 35980b57cec5SDimitry Andric if (__first == __last) 35990b57cec5SDimitry Andric return __first; 36000b57cec5SDimitry Andric if (!__pred(*__first)) 36010b57cec5SDimitry Andric break; 36020b57cec5SDimitry Andric ++__first; 36030b57cec5SDimitry Andric } 36040b57cec5SDimitry Andric // __first points to first false, everything prior to __first is already set. 36050b57cec5SDimitry Andric // Either prove [__first, __last) is all false and return __first, or point __last to last true 36060b57cec5SDimitry Andric do 36070b57cec5SDimitry Andric { 36080b57cec5SDimitry Andric if (__first == --__last) 36090b57cec5SDimitry Andric return __first; 36100b57cec5SDimitry Andric } while (!__pred(*__last)); 36110b57cec5SDimitry Andric // We now have a reduced range [__first, __last] 36120b57cec5SDimitry Andric // *__first is known to be false 36130b57cec5SDimitry Andric // *__last is known to be true 36140b57cec5SDimitry Andric // __len >= 2 36150b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last) + 1; 36160b57cec5SDimitry Andric pair<value_type*, ptrdiff_t> __p(0, 0); 36170b57cec5SDimitry Andric unique_ptr<value_type, __return_temporary_buffer> __h; 36180b57cec5SDimitry Andric if (__len >= __alloc_limit) 36190b57cec5SDimitry Andric { 36200b57cec5SDimitry Andric __p = _VSTD::get_temporary_buffer<value_type>(__len); 36210b57cec5SDimitry Andric __h.reset(__p.first); 36220b57cec5SDimitry Andric } 36230b57cec5SDimitry Andric return __stable_partition<typename add_lvalue_reference<_Predicate>::type> 36240b57cec5SDimitry Andric (__first, __last, __pred, __len, __p, bidirectional_iterator_tag()); 36250b57cec5SDimitry Andric} 36260b57cec5SDimitry Andric 36270b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Predicate> 36280b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 36290b57cec5SDimitry Andric_ForwardIterator 36300b57cec5SDimitry Andricstable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 36310b57cec5SDimitry Andric{ 36320b57cec5SDimitry Andric return __stable_partition<typename add_lvalue_reference<_Predicate>::type> 36330b57cec5SDimitry Andric (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); 36340b57cec5SDimitry Andric} 36350b57cec5SDimitry Andric 36360b57cec5SDimitry Andric// is_sorted_until 36370b57cec5SDimitry Andric 36380b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Compare> 36390b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 36400b57cec5SDimitry Andricis_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 36410b57cec5SDimitry Andric{ 36420b57cec5SDimitry Andric if (__first != __last) 36430b57cec5SDimitry Andric { 36440b57cec5SDimitry Andric _ForwardIterator __i = __first; 36450b57cec5SDimitry Andric while (++__i != __last) 36460b57cec5SDimitry Andric { 36470b57cec5SDimitry Andric if (__comp(*__i, *__first)) 36480b57cec5SDimitry Andric return __i; 36490b57cec5SDimitry Andric __first = __i; 36500b57cec5SDimitry Andric } 36510b57cec5SDimitry Andric } 36520b57cec5SDimitry Andric return __last; 36530b57cec5SDimitry Andric} 36540b57cec5SDimitry Andric 36550b57cec5SDimitry Andrictemplate<class _ForwardIterator> 36560b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 36570b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 36580b57cec5SDimitry Andric_ForwardIterator 36590b57cec5SDimitry Andricis_sorted_until(_ForwardIterator __first, _ForwardIterator __last) 36600b57cec5SDimitry Andric{ 36610b57cec5SDimitry Andric return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>()); 36620b57cec5SDimitry Andric} 36630b57cec5SDimitry Andric 36640b57cec5SDimitry Andric// is_sorted 36650b57cec5SDimitry Andric 36660b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Compare> 36670b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 36680b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 36690b57cec5SDimitry Andricbool 36700b57cec5SDimitry Andricis_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 36710b57cec5SDimitry Andric{ 36720b57cec5SDimitry Andric return _VSTD::is_sorted_until(__first, __last, __comp) == __last; 36730b57cec5SDimitry Andric} 36740b57cec5SDimitry Andric 36750b57cec5SDimitry Andrictemplate<class _ForwardIterator> 36760b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 36770b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 36780b57cec5SDimitry Andricbool 36790b57cec5SDimitry Andricis_sorted(_ForwardIterator __first, _ForwardIterator __last) 36800b57cec5SDimitry Andric{ 36810b57cec5SDimitry Andric return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>()); 36820b57cec5SDimitry Andric} 36830b57cec5SDimitry Andric 36840b57cec5SDimitry Andric// sort 36850b57cec5SDimitry Andric 36860b57cec5SDimitry Andric// stable, 2-3 compares, 0-2 swaps 36870b57cec5SDimitry Andric 36880b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator> 36890b57cec5SDimitry Andricunsigned 36900b57cec5SDimitry Andric__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c) 36910b57cec5SDimitry Andric{ 36920b57cec5SDimitry Andric unsigned __r = 0; 36930b57cec5SDimitry Andric if (!__c(*__y, *__x)) // if x <= y 36940b57cec5SDimitry Andric { 36950b57cec5SDimitry Andric if (!__c(*__z, *__y)) // if y <= z 36960b57cec5SDimitry Andric return __r; // x <= y && y <= z 36970b57cec5SDimitry Andric // x <= y && y > z 36980b57cec5SDimitry Andric swap(*__y, *__z); // x <= z && y < z 36990b57cec5SDimitry Andric __r = 1; 37000b57cec5SDimitry Andric if (__c(*__y, *__x)) // if x > y 37010b57cec5SDimitry Andric { 37020b57cec5SDimitry Andric swap(*__x, *__y); // x < y && y <= z 37030b57cec5SDimitry Andric __r = 2; 37040b57cec5SDimitry Andric } 37050b57cec5SDimitry Andric return __r; // x <= y && y < z 37060b57cec5SDimitry Andric } 37070b57cec5SDimitry Andric if (__c(*__z, *__y)) // x > y, if y > z 37080b57cec5SDimitry Andric { 37090b57cec5SDimitry Andric swap(*__x, *__z); // x < y && y < z 37100b57cec5SDimitry Andric __r = 1; 37110b57cec5SDimitry Andric return __r; 37120b57cec5SDimitry Andric } 37130b57cec5SDimitry Andric swap(*__x, *__y); // x > y && y <= z 37140b57cec5SDimitry Andric __r = 1; // x < y && x <= z 37150b57cec5SDimitry Andric if (__c(*__z, *__y)) // if y > z 37160b57cec5SDimitry Andric { 37170b57cec5SDimitry Andric swap(*__y, *__z); // x <= y && y < z 37180b57cec5SDimitry Andric __r = 2; 37190b57cec5SDimitry Andric } 37200b57cec5SDimitry Andric return __r; 37210b57cec5SDimitry Andric} // x <= y && y <= z 37220b57cec5SDimitry Andric 37230b57cec5SDimitry Andric// stable, 3-6 compares, 0-5 swaps 37240b57cec5SDimitry Andric 37250b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator> 37260b57cec5SDimitry Andricunsigned 37270b57cec5SDimitry Andric__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, 37280b57cec5SDimitry Andric _ForwardIterator __x4, _Compare __c) 37290b57cec5SDimitry Andric{ 37300b57cec5SDimitry Andric unsigned __r = __sort3<_Compare>(__x1, __x2, __x3, __c); 37310b57cec5SDimitry Andric if (__c(*__x4, *__x3)) 37320b57cec5SDimitry Andric { 37330b57cec5SDimitry Andric swap(*__x3, *__x4); 37340b57cec5SDimitry Andric ++__r; 37350b57cec5SDimitry Andric if (__c(*__x3, *__x2)) 37360b57cec5SDimitry Andric { 37370b57cec5SDimitry Andric swap(*__x2, *__x3); 37380b57cec5SDimitry Andric ++__r; 37390b57cec5SDimitry Andric if (__c(*__x2, *__x1)) 37400b57cec5SDimitry Andric { 37410b57cec5SDimitry Andric swap(*__x1, *__x2); 37420b57cec5SDimitry Andric ++__r; 37430b57cec5SDimitry Andric } 37440b57cec5SDimitry Andric } 37450b57cec5SDimitry Andric } 37460b57cec5SDimitry Andric return __r; 37470b57cec5SDimitry Andric} 37480b57cec5SDimitry Andric 37490b57cec5SDimitry Andric// stable, 4-10 compares, 0-9 swaps 37500b57cec5SDimitry Andric 37510b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator> 37520b57cec5SDimitry Andric_LIBCPP_HIDDEN 37530b57cec5SDimitry Andricunsigned 37540b57cec5SDimitry Andric__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, 37550b57cec5SDimitry Andric _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c) 37560b57cec5SDimitry Andric{ 37570b57cec5SDimitry Andric unsigned __r = __sort4<_Compare>(__x1, __x2, __x3, __x4, __c); 37580b57cec5SDimitry Andric if (__c(*__x5, *__x4)) 37590b57cec5SDimitry Andric { 37600b57cec5SDimitry Andric swap(*__x4, *__x5); 37610b57cec5SDimitry Andric ++__r; 37620b57cec5SDimitry Andric if (__c(*__x4, *__x3)) 37630b57cec5SDimitry Andric { 37640b57cec5SDimitry Andric swap(*__x3, *__x4); 37650b57cec5SDimitry Andric ++__r; 37660b57cec5SDimitry Andric if (__c(*__x3, *__x2)) 37670b57cec5SDimitry Andric { 37680b57cec5SDimitry Andric swap(*__x2, *__x3); 37690b57cec5SDimitry Andric ++__r; 37700b57cec5SDimitry Andric if (__c(*__x2, *__x1)) 37710b57cec5SDimitry Andric { 37720b57cec5SDimitry Andric swap(*__x1, *__x2); 37730b57cec5SDimitry Andric ++__r; 37740b57cec5SDimitry Andric } 37750b57cec5SDimitry Andric } 37760b57cec5SDimitry Andric } 37770b57cec5SDimitry Andric } 37780b57cec5SDimitry Andric return __r; 37790b57cec5SDimitry Andric} 37800b57cec5SDimitry Andric 37810b57cec5SDimitry Andric// Assumes size > 0 37820b57cec5SDimitry Andrictemplate <class _Compare, class _BirdirectionalIterator> 37830b57cec5SDimitry Andricvoid 37840b57cec5SDimitry Andric__selection_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp) 37850b57cec5SDimitry Andric{ 37860b57cec5SDimitry Andric _BirdirectionalIterator __lm1 = __last; 37870b57cec5SDimitry Andric for (--__lm1; __first != __lm1; ++__first) 37880b57cec5SDimitry Andric { 37890b57cec5SDimitry Andric _BirdirectionalIterator __i = _VSTD::min_element<_BirdirectionalIterator, 37900b57cec5SDimitry Andric typename add_lvalue_reference<_Compare>::type> 37910b57cec5SDimitry Andric (__first, __last, __comp); 37920b57cec5SDimitry Andric if (__i != __first) 37930b57cec5SDimitry Andric swap(*__first, *__i); 37940b57cec5SDimitry Andric } 37950b57cec5SDimitry Andric} 37960b57cec5SDimitry Andric 37970b57cec5SDimitry Andrictemplate <class _Compare, class _BirdirectionalIterator> 37980b57cec5SDimitry Andricvoid 37990b57cec5SDimitry Andric__insertion_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp) 38000b57cec5SDimitry Andric{ 38010b57cec5SDimitry Andric typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type; 38020b57cec5SDimitry Andric if (__first != __last) 38030b57cec5SDimitry Andric { 38040b57cec5SDimitry Andric _BirdirectionalIterator __i = __first; 38050b57cec5SDimitry Andric for (++__i; __i != __last; ++__i) 38060b57cec5SDimitry Andric { 38070b57cec5SDimitry Andric _BirdirectionalIterator __j = __i; 38080b57cec5SDimitry Andric value_type __t(_VSTD::move(*__j)); 38090b57cec5SDimitry Andric for (_BirdirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j) 38100b57cec5SDimitry Andric *__j = _VSTD::move(*__k); 38110b57cec5SDimitry Andric *__j = _VSTD::move(__t); 38120b57cec5SDimitry Andric } 38130b57cec5SDimitry Andric } 38140b57cec5SDimitry Andric} 38150b57cec5SDimitry Andric 38160b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 38170b57cec5SDimitry Andricvoid 38180b57cec5SDimitry Andric__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 38190b57cec5SDimitry Andric{ 38200b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 38210b57cec5SDimitry Andric _RandomAccessIterator __j = __first+2; 38220b57cec5SDimitry Andric __sort3<_Compare>(__first, __first+1, __j, __comp); 38230b57cec5SDimitry Andric for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) 38240b57cec5SDimitry Andric { 38250b57cec5SDimitry Andric if (__comp(*__i, *__j)) 38260b57cec5SDimitry Andric { 38270b57cec5SDimitry Andric value_type __t(_VSTD::move(*__i)); 38280b57cec5SDimitry Andric _RandomAccessIterator __k = __j; 38290b57cec5SDimitry Andric __j = __i; 38300b57cec5SDimitry Andric do 38310b57cec5SDimitry Andric { 38320b57cec5SDimitry Andric *__j = _VSTD::move(*__k); 38330b57cec5SDimitry Andric __j = __k; 38340b57cec5SDimitry Andric } while (__j != __first && __comp(__t, *--__k)); 38350b57cec5SDimitry Andric *__j = _VSTD::move(__t); 38360b57cec5SDimitry Andric } 38370b57cec5SDimitry Andric __j = __i; 38380b57cec5SDimitry Andric } 38390b57cec5SDimitry Andric} 38400b57cec5SDimitry Andric 38410b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 38420b57cec5SDimitry Andricbool 38430b57cec5SDimitry Andric__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 38440b57cec5SDimitry Andric{ 38450b57cec5SDimitry Andric switch (__last - __first) 38460b57cec5SDimitry Andric { 38470b57cec5SDimitry Andric case 0: 38480b57cec5SDimitry Andric case 1: 38490b57cec5SDimitry Andric return true; 38500b57cec5SDimitry Andric case 2: 38510b57cec5SDimitry Andric if (__comp(*--__last, *__first)) 38520b57cec5SDimitry Andric swap(*__first, *__last); 38530b57cec5SDimitry Andric return true; 38540b57cec5SDimitry Andric case 3: 38550b57cec5SDimitry Andric _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); 38560b57cec5SDimitry Andric return true; 38570b57cec5SDimitry Andric case 4: 38580b57cec5SDimitry Andric _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); 38590b57cec5SDimitry Andric return true; 38600b57cec5SDimitry Andric case 5: 38610b57cec5SDimitry Andric _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); 38620b57cec5SDimitry Andric return true; 38630b57cec5SDimitry Andric } 38640b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 38650b57cec5SDimitry Andric _RandomAccessIterator __j = __first+2; 38660b57cec5SDimitry Andric __sort3<_Compare>(__first, __first+1, __j, __comp); 38670b57cec5SDimitry Andric const unsigned __limit = 8; 38680b57cec5SDimitry Andric unsigned __count = 0; 38690b57cec5SDimitry Andric for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) 38700b57cec5SDimitry Andric { 38710b57cec5SDimitry Andric if (__comp(*__i, *__j)) 38720b57cec5SDimitry Andric { 38730b57cec5SDimitry Andric value_type __t(_VSTD::move(*__i)); 38740b57cec5SDimitry Andric _RandomAccessIterator __k = __j; 38750b57cec5SDimitry Andric __j = __i; 38760b57cec5SDimitry Andric do 38770b57cec5SDimitry Andric { 38780b57cec5SDimitry Andric *__j = _VSTD::move(*__k); 38790b57cec5SDimitry Andric __j = __k; 38800b57cec5SDimitry Andric } while (__j != __first && __comp(__t, *--__k)); 38810b57cec5SDimitry Andric *__j = _VSTD::move(__t); 38820b57cec5SDimitry Andric if (++__count == __limit) 38830b57cec5SDimitry Andric return ++__i == __last; 38840b57cec5SDimitry Andric } 38850b57cec5SDimitry Andric __j = __i; 38860b57cec5SDimitry Andric } 38870b57cec5SDimitry Andric return true; 38880b57cec5SDimitry Andric} 38890b57cec5SDimitry Andric 38900b57cec5SDimitry Andrictemplate <class _Compare, class _BirdirectionalIterator> 38910b57cec5SDimitry Andricvoid 38920b57cec5SDimitry Andric__insertion_sort_move(_BirdirectionalIterator __first1, _BirdirectionalIterator __last1, 38930b57cec5SDimitry Andric typename iterator_traits<_BirdirectionalIterator>::value_type* __first2, _Compare __comp) 38940b57cec5SDimitry Andric{ 38950b57cec5SDimitry Andric typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type; 38960b57cec5SDimitry Andric if (__first1 != __last1) 38970b57cec5SDimitry Andric { 38980b57cec5SDimitry Andric __destruct_n __d(0); 38990b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h(__first2, __d); 39000b57cec5SDimitry Andric value_type* __last2 = __first2; 39010b57cec5SDimitry Andric ::new(__last2) value_type(_VSTD::move(*__first1)); 39020b57cec5SDimitry Andric __d.__incr((value_type*)0); 39030b57cec5SDimitry Andric for (++__last2; ++__first1 != __last1; ++__last2) 39040b57cec5SDimitry Andric { 39050b57cec5SDimitry Andric value_type* __j2 = __last2; 39060b57cec5SDimitry Andric value_type* __i2 = __j2; 39070b57cec5SDimitry Andric if (__comp(*__first1, *--__i2)) 39080b57cec5SDimitry Andric { 39090b57cec5SDimitry Andric ::new(__j2) value_type(_VSTD::move(*__i2)); 39100b57cec5SDimitry Andric __d.__incr((value_type*)0); 39110b57cec5SDimitry Andric for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2) 39120b57cec5SDimitry Andric *__j2 = _VSTD::move(*__i2); 39130b57cec5SDimitry Andric *__j2 = _VSTD::move(*__first1); 39140b57cec5SDimitry Andric } 39150b57cec5SDimitry Andric else 39160b57cec5SDimitry Andric { 39170b57cec5SDimitry Andric ::new(__j2) value_type(_VSTD::move(*__first1)); 39180b57cec5SDimitry Andric __d.__incr((value_type*)0); 39190b57cec5SDimitry Andric } 39200b57cec5SDimitry Andric } 39210b57cec5SDimitry Andric __h.release(); 39220b57cec5SDimitry Andric } 39230b57cec5SDimitry Andric} 39240b57cec5SDimitry Andric 39250b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 39260b57cec5SDimitry Andricvoid 39270b57cec5SDimitry Andric__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 39280b57cec5SDimitry Andric{ 39290b57cec5SDimitry Andric // _Compare is known to be a reference type 39300b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 39310b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 39320b57cec5SDimitry Andric const difference_type __limit = is_trivially_copy_constructible<value_type>::value && 39330b57cec5SDimitry Andric is_trivially_copy_assignable<value_type>::value ? 30 : 6; 39340b57cec5SDimitry Andric while (true) 39350b57cec5SDimitry Andric { 39360b57cec5SDimitry Andric __restart: 39370b57cec5SDimitry Andric difference_type __len = __last - __first; 39380b57cec5SDimitry Andric switch (__len) 39390b57cec5SDimitry Andric { 39400b57cec5SDimitry Andric case 0: 39410b57cec5SDimitry Andric case 1: 39420b57cec5SDimitry Andric return; 39430b57cec5SDimitry Andric case 2: 39440b57cec5SDimitry Andric if (__comp(*--__last, *__first)) 39450b57cec5SDimitry Andric swap(*__first, *__last); 39460b57cec5SDimitry Andric return; 39470b57cec5SDimitry Andric case 3: 39480b57cec5SDimitry Andric _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); 39490b57cec5SDimitry Andric return; 39500b57cec5SDimitry Andric case 4: 39510b57cec5SDimitry Andric _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); 39520b57cec5SDimitry Andric return; 39530b57cec5SDimitry Andric case 5: 39540b57cec5SDimitry Andric _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); 39550b57cec5SDimitry Andric return; 39560b57cec5SDimitry Andric } 39570b57cec5SDimitry Andric if (__len <= __limit) 39580b57cec5SDimitry Andric { 39590b57cec5SDimitry Andric _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp); 39600b57cec5SDimitry Andric return; 39610b57cec5SDimitry Andric } 39620b57cec5SDimitry Andric // __len > 5 39630b57cec5SDimitry Andric _RandomAccessIterator __m = __first; 39640b57cec5SDimitry Andric _RandomAccessIterator __lm1 = __last; 39650b57cec5SDimitry Andric --__lm1; 39660b57cec5SDimitry Andric unsigned __n_swaps; 39670b57cec5SDimitry Andric { 39680b57cec5SDimitry Andric difference_type __delta; 39690b57cec5SDimitry Andric if (__len >= 1000) 39700b57cec5SDimitry Andric { 39710b57cec5SDimitry Andric __delta = __len/2; 39720b57cec5SDimitry Andric __m += __delta; 39730b57cec5SDimitry Andric __delta /= 2; 39740b57cec5SDimitry Andric __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp); 39750b57cec5SDimitry Andric } 39760b57cec5SDimitry Andric else 39770b57cec5SDimitry Andric { 39780b57cec5SDimitry Andric __delta = __len/2; 39790b57cec5SDimitry Andric __m += __delta; 39800b57cec5SDimitry Andric __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp); 39810b57cec5SDimitry Andric } 39820b57cec5SDimitry Andric } 39830b57cec5SDimitry Andric // *__m is median 39840b57cec5SDimitry Andric // partition [__first, __m) < *__m and *__m <= [__m, __last) 39850b57cec5SDimitry Andric // (this inhibits tossing elements equivalent to __m around unnecessarily) 39860b57cec5SDimitry Andric _RandomAccessIterator __i = __first; 39870b57cec5SDimitry Andric _RandomAccessIterator __j = __lm1; 39880b57cec5SDimitry Andric // j points beyond range to be tested, *__m is known to be <= *__lm1 39890b57cec5SDimitry Andric // The search going up is known to be guarded but the search coming down isn't. 39900b57cec5SDimitry Andric // Prime the downward search with a guard. 39910b57cec5SDimitry Andric if (!__comp(*__i, *__m)) // if *__first == *__m 39920b57cec5SDimitry Andric { 39930b57cec5SDimitry Andric // *__first == *__m, *__first doesn't go in first part 39940b57cec5SDimitry Andric // manually guard downward moving __j against __i 39950b57cec5SDimitry Andric while (true) 39960b57cec5SDimitry Andric { 39970b57cec5SDimitry Andric if (__i == --__j) 39980b57cec5SDimitry Andric { 39990b57cec5SDimitry Andric // *__first == *__m, *__m <= all other elements 40000b57cec5SDimitry Andric // Parition instead into [__first, __i) == *__first and *__first < [__i, __last) 40010b57cec5SDimitry Andric ++__i; // __first + 1 40020b57cec5SDimitry Andric __j = __last; 40030b57cec5SDimitry Andric if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1) 40040b57cec5SDimitry Andric { 40050b57cec5SDimitry Andric while (true) 40060b57cec5SDimitry Andric { 40070b57cec5SDimitry Andric if (__i == __j) 40080b57cec5SDimitry Andric return; // [__first, __last) all equivalent elements 40090b57cec5SDimitry Andric if (__comp(*__first, *__i)) 40100b57cec5SDimitry Andric { 40110b57cec5SDimitry Andric swap(*__i, *__j); 40120b57cec5SDimitry Andric ++__n_swaps; 40130b57cec5SDimitry Andric ++__i; 40140b57cec5SDimitry Andric break; 40150b57cec5SDimitry Andric } 40160b57cec5SDimitry Andric ++__i; 40170b57cec5SDimitry Andric } 40180b57cec5SDimitry Andric } 40190b57cec5SDimitry Andric // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 40200b57cec5SDimitry Andric if (__i == __j) 40210b57cec5SDimitry Andric return; 40220b57cec5SDimitry Andric while (true) 40230b57cec5SDimitry Andric { 40240b57cec5SDimitry Andric while (!__comp(*__first, *__i)) 40250b57cec5SDimitry Andric ++__i; 40260b57cec5SDimitry Andric while (__comp(*__first, *--__j)) 40270b57cec5SDimitry Andric ; 40280b57cec5SDimitry Andric if (__i >= __j) 40290b57cec5SDimitry Andric break; 40300b57cec5SDimitry Andric swap(*__i, *__j); 40310b57cec5SDimitry Andric ++__n_swaps; 40320b57cec5SDimitry Andric ++__i; 40330b57cec5SDimitry Andric } 40340b57cec5SDimitry Andric // [__first, __i) == *__first and *__first < [__i, __last) 40350b57cec5SDimitry Andric // The first part is sorted, sort the secod part 40360b57cec5SDimitry Andric // _VSTD::__sort<_Compare>(__i, __last, __comp); 40370b57cec5SDimitry Andric __first = __i; 40380b57cec5SDimitry Andric goto __restart; 40390b57cec5SDimitry Andric } 40400b57cec5SDimitry Andric if (__comp(*__j, *__m)) 40410b57cec5SDimitry Andric { 40420b57cec5SDimitry Andric swap(*__i, *__j); 40430b57cec5SDimitry Andric ++__n_swaps; 40440b57cec5SDimitry Andric break; // found guard for downward moving __j, now use unguarded partition 40450b57cec5SDimitry Andric } 40460b57cec5SDimitry Andric } 40470b57cec5SDimitry Andric } 40480b57cec5SDimitry Andric // It is known that *__i < *__m 40490b57cec5SDimitry Andric ++__i; 40500b57cec5SDimitry Andric // j points beyond range to be tested, *__m is known to be <= *__lm1 40510b57cec5SDimitry Andric // if not yet partitioned... 40520b57cec5SDimitry Andric if (__i < __j) 40530b57cec5SDimitry Andric { 40540b57cec5SDimitry Andric // known that *(__i - 1) < *__m 40550b57cec5SDimitry Andric // known that __i <= __m 40560b57cec5SDimitry Andric while (true) 40570b57cec5SDimitry Andric { 40580b57cec5SDimitry Andric // __m still guards upward moving __i 40590b57cec5SDimitry Andric while (__comp(*__i, *__m)) 40600b57cec5SDimitry Andric ++__i; 40610b57cec5SDimitry Andric // It is now known that a guard exists for downward moving __j 40620b57cec5SDimitry Andric while (!__comp(*--__j, *__m)) 40630b57cec5SDimitry Andric ; 40640b57cec5SDimitry Andric if (__i > __j) 40650b57cec5SDimitry Andric break; 40660b57cec5SDimitry Andric swap(*__i, *__j); 40670b57cec5SDimitry Andric ++__n_swaps; 40680b57cec5SDimitry Andric // It is known that __m != __j 40690b57cec5SDimitry Andric // If __m just moved, follow it 40700b57cec5SDimitry Andric if (__m == __i) 40710b57cec5SDimitry Andric __m = __j; 40720b57cec5SDimitry Andric ++__i; 40730b57cec5SDimitry Andric } 40740b57cec5SDimitry Andric } 40750b57cec5SDimitry Andric // [__first, __i) < *__m and *__m <= [__i, __last) 40760b57cec5SDimitry Andric if (__i != __m && __comp(*__m, *__i)) 40770b57cec5SDimitry Andric { 40780b57cec5SDimitry Andric swap(*__i, *__m); 40790b57cec5SDimitry Andric ++__n_swaps; 40800b57cec5SDimitry Andric } 40810b57cec5SDimitry Andric // [__first, __i) < *__i and *__i <= [__i+1, __last) 40820b57cec5SDimitry Andric // If we were given a perfect partition, see if insertion sort is quick... 40830b57cec5SDimitry Andric if (__n_swaps == 0) 40840b57cec5SDimitry Andric { 40850b57cec5SDimitry Andric bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp); 40860b57cec5SDimitry Andric if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp)) 40870b57cec5SDimitry Andric { 40880b57cec5SDimitry Andric if (__fs) 40890b57cec5SDimitry Andric return; 40900b57cec5SDimitry Andric __last = __i; 40910b57cec5SDimitry Andric continue; 40920b57cec5SDimitry Andric } 40930b57cec5SDimitry Andric else 40940b57cec5SDimitry Andric { 40950b57cec5SDimitry Andric if (__fs) 40960b57cec5SDimitry Andric { 40970b57cec5SDimitry Andric __first = ++__i; 40980b57cec5SDimitry Andric continue; 40990b57cec5SDimitry Andric } 41000b57cec5SDimitry Andric } 41010b57cec5SDimitry Andric } 41020b57cec5SDimitry Andric // sort smaller range with recursive call and larger with tail recursion elimination 41030b57cec5SDimitry Andric if (__i - __first < __last - __i) 41040b57cec5SDimitry Andric { 41050b57cec5SDimitry Andric _VSTD::__sort<_Compare>(__first, __i, __comp); 41060b57cec5SDimitry Andric // _VSTD::__sort<_Compare>(__i+1, __last, __comp); 41070b57cec5SDimitry Andric __first = ++__i; 41080b57cec5SDimitry Andric } 41090b57cec5SDimitry Andric else 41100b57cec5SDimitry Andric { 41110b57cec5SDimitry Andric _VSTD::__sort<_Compare>(__i+1, __last, __comp); 41120b57cec5SDimitry Andric // _VSTD::__sort<_Compare>(__first, __i, __comp); 41130b57cec5SDimitry Andric __last = __i; 41140b57cec5SDimitry Andric } 41150b57cec5SDimitry Andric } 41160b57cec5SDimitry Andric} 41170b57cec5SDimitry Andric 41180b57cec5SDimitry Andric// This forwarder keeps the top call and the recursive calls using the same instantiation, forcing a reference _Compare 41190b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 41200b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 41210b57cec5SDimitry Andricvoid 41220b57cec5SDimitry Andricsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 41230b57cec5SDimitry Andric{ 41240b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 41250b57cec5SDimitry Andric _VSTD::__sort<_Comp_ref>(__first, __last, _Comp_ref(__comp)); 41260b57cec5SDimitry Andric} 41270b57cec5SDimitry Andric 41280b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 41290b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 41300b57cec5SDimitry Andricvoid 41310b57cec5SDimitry Andricsort(_RandomAccessIterator __first, _RandomAccessIterator __last) 41320b57cec5SDimitry Andric{ 41330b57cec5SDimitry Andric _VSTD::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 41340b57cec5SDimitry Andric} 41350b57cec5SDimitry Andric 41360b57cec5SDimitry Andrictemplate <class _Tp> 41370b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 41380b57cec5SDimitry Andricvoid 41390b57cec5SDimitry Andricsort(_Tp** __first, _Tp** __last) 41400b57cec5SDimitry Andric{ 41410b57cec5SDimitry Andric _VSTD::sort((size_t*)__first, (size_t*)__last, __less<size_t>()); 41420b57cec5SDimitry Andric} 41430b57cec5SDimitry Andric 41440b57cec5SDimitry Andrictemplate <class _Tp> 41450b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 41460b57cec5SDimitry Andricvoid 41470b57cec5SDimitry Andricsort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last) 41480b57cec5SDimitry Andric{ 41490b57cec5SDimitry Andric _VSTD::sort(__first.base(), __last.base()); 41500b57cec5SDimitry Andric} 41510b57cec5SDimitry Andric 41520b57cec5SDimitry Andrictemplate <class _Tp, class _Compare> 41530b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 41540b57cec5SDimitry Andricvoid 41550b57cec5SDimitry Andricsort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last, _Compare __comp) 41560b57cec5SDimitry Andric{ 41570b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 41580b57cec5SDimitry Andric _VSTD::sort<_Tp*, _Comp_ref>(__first.base(), __last.base(), __comp); 41590b57cec5SDimitry Andric} 41600b57cec5SDimitry Andric 41610b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&)) 41620b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&)) 41630b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&)) 41640b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&)) 41650b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&)) 41660b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&)) 41670b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&)) 41680b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&)) 41690b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&)) 41700b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&)) 41710b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&)) 41720b57cec5SDimitry 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>&)) 41730b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&)) 41740b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&)) 41750b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&)) 41760b57cec5SDimitry Andric 41770b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&)) 41780b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&)) 41790b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&)) 41800b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&)) 41810b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&)) 41820b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&)) 41830b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&)) 41840b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&)) 41850b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&)) 41860b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&)) 41870b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&)) 41880b57cec5SDimitry 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>&)) 41890b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&)) 41900b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&)) 41910b57cec5SDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&)) 41920b57cec5SDimitry Andric 41930b57cec5SDimitry 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>&)) 41940b57cec5SDimitry Andric 41950b57cec5SDimitry Andric// lower_bound 41960b57cec5SDimitry Andric 41970b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator, class _Tp> 41980b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 41990b57cec5SDimitry Andric__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 42000b57cec5SDimitry Andric{ 42010b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 42020b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last); 42030b57cec5SDimitry Andric while (__len != 0) 42040b57cec5SDimitry Andric { 42050b57cec5SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 42060b57cec5SDimitry Andric _ForwardIterator __m = __first; 42070b57cec5SDimitry Andric _VSTD::advance(__m, __l2); 42080b57cec5SDimitry Andric if (__comp(*__m, __value_)) 42090b57cec5SDimitry Andric { 42100b57cec5SDimitry Andric __first = ++__m; 42110b57cec5SDimitry Andric __len -= __l2 + 1; 42120b57cec5SDimitry Andric } 42130b57cec5SDimitry Andric else 42140b57cec5SDimitry Andric __len = __l2; 42150b57cec5SDimitry Andric } 42160b57cec5SDimitry Andric return __first; 42170b57cec5SDimitry Andric} 42180b57cec5SDimitry Andric 42190b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp, class _Compare> 42200b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 42210b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 42220b57cec5SDimitry Andric_ForwardIterator 42230b57cec5SDimitry Andriclower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 42240b57cec5SDimitry Andric{ 42250b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 42260b57cec5SDimitry Andric return __lower_bound<_Comp_ref>(__first, __last, __value_, __comp); 42270b57cec5SDimitry Andric} 42280b57cec5SDimitry Andric 42290b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 42300b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 42310b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 42320b57cec5SDimitry Andric_ForwardIterator 42330b57cec5SDimitry Andriclower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 42340b57cec5SDimitry Andric{ 42350b57cec5SDimitry Andric return _VSTD::lower_bound(__first, __last, __value_, 42360b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); 42370b57cec5SDimitry Andric} 42380b57cec5SDimitry Andric 42390b57cec5SDimitry Andric// upper_bound 42400b57cec5SDimitry Andric 42410b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator, class _Tp> 42420b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 42430b57cec5SDimitry Andric__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 42440b57cec5SDimitry Andric{ 42450b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 42460b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last); 42470b57cec5SDimitry Andric while (__len != 0) 42480b57cec5SDimitry Andric { 42490b57cec5SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 42500b57cec5SDimitry Andric _ForwardIterator __m = __first; 42510b57cec5SDimitry Andric _VSTD::advance(__m, __l2); 42520b57cec5SDimitry Andric if (__comp(__value_, *__m)) 42530b57cec5SDimitry Andric __len = __l2; 42540b57cec5SDimitry Andric else 42550b57cec5SDimitry Andric { 42560b57cec5SDimitry Andric __first = ++__m; 42570b57cec5SDimitry Andric __len -= __l2 + 1; 42580b57cec5SDimitry Andric } 42590b57cec5SDimitry Andric } 42600b57cec5SDimitry Andric return __first; 42610b57cec5SDimitry Andric} 42620b57cec5SDimitry Andric 42630b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp, class _Compare> 42640b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 42650b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 42660b57cec5SDimitry Andric_ForwardIterator 42670b57cec5SDimitry Andricupper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 42680b57cec5SDimitry Andric{ 42690b57cec5SDimitry Andric typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 42700b57cec5SDimitry Andric return __upper_bound<_Comp_ref>(__first, __last, __value_, __comp); 42710b57cec5SDimitry Andric} 42720b57cec5SDimitry Andric 42730b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 42740b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 42750b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 42760b57cec5SDimitry Andric_ForwardIterator 42770b57cec5SDimitry Andricupper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 42780b57cec5SDimitry Andric{ 42790b57cec5SDimitry Andric return _VSTD::upper_bound(__first, __last, __value_, 42800b57cec5SDimitry Andric __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); 42810b57cec5SDimitry Andric} 42820b57cec5SDimitry Andric 42830b57cec5SDimitry Andric// equal_range 42840b57cec5SDimitry Andric 42850b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator, class _Tp> 42860b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> 42870b57cec5SDimitry Andric__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 42880b57cec5SDimitry Andric{ 42890b57cec5SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 42900b57cec5SDimitry Andric difference_type __len = _VSTD::distance(__first, __last); 42910b57cec5SDimitry Andric while (__len != 0) 42920b57cec5SDimitry Andric { 42930b57cec5SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 42940b57cec5SDimitry Andric _ForwardIterator __m = __first; 42950b57cec5SDimitry Andric _VSTD::advance(__m, __l2); 42960b57cec5SDimitry Andric if (__comp(*__m, __value_)) 42970b57cec5SDimitry Andric { 42980b57cec5SDimitry Andric __first = ++__m; 42990b57cec5SDimitry Andric __len -= __l2 + 1; 43000b57cec5SDimitry Andric } 43010b57cec5SDimitry Andric else if (__comp(__value_, *__m)) 43020b57cec5SDimitry Andric { 43030b57cec5SDimitry Andric __last = __m; 43040b57cec5SDimitry Andric __len = __l2; 43050b57cec5SDimitry Andric } 43060b57cec5SDimitry Andric else 43070b57cec5SDimitry Andric { 43080b57cec5SDimitry Andric _ForwardIterator __mp1 = __m; 43090b57cec5SDimitry Andric return pair<_ForwardIterator, _ForwardIterator> 43100b57cec5SDimitry Andric ( 43110b57cec5SDimitry Andric __lower_bound<_Compare>(__first, __m, __value_, __comp), 43120b57cec5SDimitry Andric __upper_bound<_Compare>(++__mp1, __last, __value_, __comp) 43130b57cec5SDimitry Andric ); 43140b57cec5SDimitry Andric } 43150b57cec5SDimitry Andric } 43160b57cec5SDimitry Andric return pair<_ForwardIterator, _ForwardIterator>(__first, __first); 43170b57cec5SDimitry Andric} 43180b57cec5SDimitry Andric 43190b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp, class _Compare> 43200b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 43210b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 43220b57cec5SDimitry Andricpair<_ForwardIterator, _ForwardIterator> 43230b57cec5SDimitry Andricequal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 43240b57cec5SDimitry Andric{ 43250b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 43260b57cec5SDimitry Andric return __equal_range<_Comp_ref>(__first, __last, __value_, __comp); 43270b57cec5SDimitry Andric} 43280b57cec5SDimitry Andric 43290b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 43300b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 43310b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 43320b57cec5SDimitry Andricpair<_ForwardIterator, _ForwardIterator> 43330b57cec5SDimitry Andricequal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 43340b57cec5SDimitry Andric{ 43350b57cec5SDimitry Andric return _VSTD::equal_range(__first, __last, __value_, 43360b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); 43370b57cec5SDimitry Andric} 43380b57cec5SDimitry Andric 43390b57cec5SDimitry Andric// binary_search 43400b57cec5SDimitry Andric 43410b57cec5SDimitry Andrictemplate <class _Compare, class _ForwardIterator, class _Tp> 43420b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 43430b57cec5SDimitry Andricbool 43440b57cec5SDimitry Andric__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 43450b57cec5SDimitry Andric{ 43460b57cec5SDimitry Andric __first = __lower_bound<_Compare>(__first, __last, __value_, __comp); 43470b57cec5SDimitry Andric return __first != __last && !__comp(__value_, *__first); 43480b57cec5SDimitry Andric} 43490b57cec5SDimitry Andric 43500b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp, class _Compare> 43510b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 43520b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 43530b57cec5SDimitry Andricbool 43540b57cec5SDimitry Andricbinary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 43550b57cec5SDimitry Andric{ 43560b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 43570b57cec5SDimitry Andric return __binary_search<_Comp_ref>(__first, __last, __value_, __comp); 43580b57cec5SDimitry Andric} 43590b57cec5SDimitry Andric 43600b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp> 43610b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 43620b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 43630b57cec5SDimitry Andricbool 43640b57cec5SDimitry Andricbinary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 43650b57cec5SDimitry Andric{ 43660b57cec5SDimitry Andric return _VSTD::binary_search(__first, __last, __value_, 43670b57cec5SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); 43680b57cec5SDimitry Andric} 43690b57cec5SDimitry Andric 43700b57cec5SDimitry Andric// merge 43710b57cec5SDimitry Andric 43720b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 43730b57cec5SDimitry Andric_OutputIterator 43740b57cec5SDimitry Andric__merge(_InputIterator1 __first1, _InputIterator1 __last1, 43750b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 43760b57cec5SDimitry Andric{ 43770b57cec5SDimitry Andric for (; __first1 != __last1; ++__result) 43780b57cec5SDimitry Andric { 43790b57cec5SDimitry Andric if (__first2 == __last2) 43800b57cec5SDimitry Andric return _VSTD::copy(__first1, __last1, __result); 43810b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 43820b57cec5SDimitry Andric { 43830b57cec5SDimitry Andric *__result = *__first2; 43840b57cec5SDimitry Andric ++__first2; 43850b57cec5SDimitry Andric } 43860b57cec5SDimitry Andric else 43870b57cec5SDimitry Andric { 43880b57cec5SDimitry Andric *__result = *__first1; 43890b57cec5SDimitry Andric ++__first1; 43900b57cec5SDimitry Andric } 43910b57cec5SDimitry Andric } 43920b57cec5SDimitry Andric return _VSTD::copy(__first2, __last2, __result); 43930b57cec5SDimitry Andric} 43940b57cec5SDimitry Andric 43950b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 43960b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 43970b57cec5SDimitry Andric_OutputIterator 43980b57cec5SDimitry Andricmerge(_InputIterator1 __first1, _InputIterator1 __last1, 43990b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 44000b57cec5SDimitry Andric{ 44010b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 44020b57cec5SDimitry Andric return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 44030b57cec5SDimitry Andric} 44040b57cec5SDimitry Andric 44050b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 44060b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 44070b57cec5SDimitry Andric_OutputIterator 44080b57cec5SDimitry Andricmerge(_InputIterator1 __first1, _InputIterator1 __last1, 44090b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 44100b57cec5SDimitry Andric{ 44110b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type __v1; 44120b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator2>::value_type __v2; 4413e40139ffSDimitry Andric return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>()); 44140b57cec5SDimitry Andric} 44150b57cec5SDimitry Andric 44160b57cec5SDimitry Andric// inplace_merge 44170b57cec5SDimitry Andric 44180b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, 44190b57cec5SDimitry Andric class _OutputIterator> 44200b57cec5SDimitry Andricvoid __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1, 44210b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, 44220b57cec5SDimitry Andric _OutputIterator __result, _Compare __comp) 44230b57cec5SDimitry Andric{ 44240b57cec5SDimitry Andric for (; __first1 != __last1; ++__result) 44250b57cec5SDimitry Andric { 44260b57cec5SDimitry Andric if (__first2 == __last2) 44270b57cec5SDimitry Andric { 44280b57cec5SDimitry Andric _VSTD::move(__first1, __last1, __result); 44290b57cec5SDimitry Andric return; 44300b57cec5SDimitry Andric } 44310b57cec5SDimitry Andric 44320b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 44330b57cec5SDimitry Andric { 44340b57cec5SDimitry Andric *__result = _VSTD::move(*__first2); 44350b57cec5SDimitry Andric ++__first2; 44360b57cec5SDimitry Andric } 44370b57cec5SDimitry Andric else 44380b57cec5SDimitry Andric { 44390b57cec5SDimitry Andric *__result = _VSTD::move(*__first1); 44400b57cec5SDimitry Andric ++__first1; 44410b57cec5SDimitry Andric } 44420b57cec5SDimitry Andric } 44430b57cec5SDimitry Andric // __first2 through __last2 are already in the right spot. 44440b57cec5SDimitry Andric} 44450b57cec5SDimitry Andric 44460b57cec5SDimitry Andrictemplate <class _Compare, class _BidirectionalIterator> 44470b57cec5SDimitry Andricvoid 44480b57cec5SDimitry Andric__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 44490b57cec5SDimitry Andric _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, 44500b57cec5SDimitry Andric typename iterator_traits<_BidirectionalIterator>::difference_type __len2, 44510b57cec5SDimitry Andric typename iterator_traits<_BidirectionalIterator>::value_type* __buff) 44520b57cec5SDimitry Andric{ 44530b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 44540b57cec5SDimitry Andric __destruct_n __d(0); 44550b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h2(__buff, __d); 44560b57cec5SDimitry Andric if (__len1 <= __len2) 44570b57cec5SDimitry Andric { 44580b57cec5SDimitry Andric value_type* __p = __buff; 4459e40139ffSDimitry Andric for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), (void) ++__i, (void) ++__p) 44600b57cec5SDimitry Andric ::new(__p) value_type(_VSTD::move(*__i)); 44610b57cec5SDimitry Andric __half_inplace_merge(__buff, __p, __middle, __last, __first, __comp); 44620b57cec5SDimitry Andric } 44630b57cec5SDimitry Andric else 44640b57cec5SDimitry Andric { 44650b57cec5SDimitry Andric value_type* __p = __buff; 4466e40139ffSDimitry Andric for (_BidirectionalIterator __i = __middle; __i != __last; __d.__incr((value_type*)0), (void) ++__i, (void) ++__p) 44670b57cec5SDimitry Andric ::new(__p) value_type(_VSTD::move(*__i)); 44680b57cec5SDimitry Andric typedef reverse_iterator<_BidirectionalIterator> _RBi; 44690b57cec5SDimitry Andric typedef reverse_iterator<value_type*> _Rv; 44700b57cec5SDimitry Andric __half_inplace_merge(_Rv(__p), _Rv(__buff), 44710b57cec5SDimitry Andric _RBi(__middle), _RBi(__first), 44720b57cec5SDimitry Andric _RBi(__last), __invert<_Compare>(__comp)); 44730b57cec5SDimitry Andric } 44740b57cec5SDimitry Andric} 44750b57cec5SDimitry Andric 44760b57cec5SDimitry Andrictemplate <class _Compare, class _BidirectionalIterator> 44770b57cec5SDimitry Andricvoid 44780b57cec5SDimitry Andric__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 44790b57cec5SDimitry Andric _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, 44800b57cec5SDimitry Andric typename iterator_traits<_BidirectionalIterator>::difference_type __len2, 44810b57cec5SDimitry Andric typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size) 44820b57cec5SDimitry Andric{ 44830b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; 44840b57cec5SDimitry Andric while (true) 44850b57cec5SDimitry Andric { 44860b57cec5SDimitry Andric // if __middle == __last, we're done 44870b57cec5SDimitry Andric if (__len2 == 0) 44880b57cec5SDimitry Andric return; 44890b57cec5SDimitry Andric if (__len1 <= __buff_size || __len2 <= __buff_size) 44900b57cec5SDimitry Andric return __buffered_inplace_merge<_Compare> 44910b57cec5SDimitry Andric (__first, __middle, __last, __comp, __len1, __len2, __buff); 44920b57cec5SDimitry Andric // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 44930b57cec5SDimitry Andric for (; true; ++__first, (void) --__len1) 44940b57cec5SDimitry Andric { 44950b57cec5SDimitry Andric if (__len1 == 0) 44960b57cec5SDimitry Andric return; 44970b57cec5SDimitry Andric if (__comp(*__middle, *__first)) 44980b57cec5SDimitry Andric break; 44990b57cec5SDimitry Andric } 45000b57cec5SDimitry Andric // __first < __middle < __last 45010b57cec5SDimitry Andric // *__first > *__middle 45020b57cec5SDimitry Andric // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that 45030b57cec5SDimitry Andric // all elements in: 45040b57cec5SDimitry Andric // [__first, __m1) <= [__middle, __m2) 45050b57cec5SDimitry Andric // [__middle, __m2) < [__m1, __middle) 45060b57cec5SDimitry Andric // [__m1, __middle) <= [__m2, __last) 45070b57cec5SDimitry Andric // and __m1 or __m2 is in the middle of its range 45080b57cec5SDimitry Andric _BidirectionalIterator __m1; // "median" of [__first, __middle) 45090b57cec5SDimitry Andric _BidirectionalIterator __m2; // "median" of [__middle, __last) 45100b57cec5SDimitry Andric difference_type __len11; // distance(__first, __m1) 45110b57cec5SDimitry Andric difference_type __len21; // distance(__middle, __m2) 45120b57cec5SDimitry Andric // binary search smaller range 45130b57cec5SDimitry Andric if (__len1 < __len2) 45140b57cec5SDimitry Andric { // __len >= 1, __len2 >= 2 45150b57cec5SDimitry Andric __len21 = __len2 / 2; 45160b57cec5SDimitry Andric __m2 = __middle; 45170b57cec5SDimitry Andric _VSTD::advance(__m2, __len21); 45180b57cec5SDimitry Andric __m1 = __upper_bound<_Compare>(__first, __middle, *__m2, __comp); 45190b57cec5SDimitry Andric __len11 = _VSTD::distance(__first, __m1); 45200b57cec5SDimitry Andric } 45210b57cec5SDimitry Andric else 45220b57cec5SDimitry Andric { 45230b57cec5SDimitry Andric if (__len1 == 1) 45240b57cec5SDimitry Andric { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 45250b57cec5SDimitry Andric // It is known *__first > *__middle 45260b57cec5SDimitry Andric swap(*__first, *__middle); 45270b57cec5SDimitry Andric return; 45280b57cec5SDimitry Andric } 45290b57cec5SDimitry Andric // __len1 >= 2, __len2 >= 1 45300b57cec5SDimitry Andric __len11 = __len1 / 2; 45310b57cec5SDimitry Andric __m1 = __first; 45320b57cec5SDimitry Andric _VSTD::advance(__m1, __len11); 45330b57cec5SDimitry Andric __m2 = __lower_bound<_Compare>(__middle, __last, *__m1, __comp); 45340b57cec5SDimitry Andric __len21 = _VSTD::distance(__middle, __m2); 45350b57cec5SDimitry Andric } 45360b57cec5SDimitry Andric difference_type __len12 = __len1 - __len11; // distance(__m1, __middle) 45370b57cec5SDimitry Andric difference_type __len22 = __len2 - __len21; // distance(__m2, __last) 45380b57cec5SDimitry Andric // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) 45390b57cec5SDimitry Andric // swap middle two partitions 45400b57cec5SDimitry Andric __middle = _VSTD::rotate(__m1, __middle, __m2); 45410b57cec5SDimitry Andric // __len12 and __len21 now have swapped meanings 45420b57cec5SDimitry Andric // merge smaller range with recurisve call and larger with tail recursion elimination 45430b57cec5SDimitry Andric if (__len11 + __len21 < __len12 + __len22) 45440b57cec5SDimitry Andric { 45450b57cec5SDimitry Andric __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); 45460b57cec5SDimitry Andric// __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); 45470b57cec5SDimitry Andric __first = __middle; 45480b57cec5SDimitry Andric __middle = __m2; 45490b57cec5SDimitry Andric __len1 = __len12; 45500b57cec5SDimitry Andric __len2 = __len22; 45510b57cec5SDimitry Andric } 45520b57cec5SDimitry Andric else 45530b57cec5SDimitry Andric { 45540b57cec5SDimitry Andric __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); 45550b57cec5SDimitry Andric// __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); 45560b57cec5SDimitry Andric __last = __middle; 45570b57cec5SDimitry Andric __middle = __m1; 45580b57cec5SDimitry Andric __len1 = __len11; 45590b57cec5SDimitry Andric __len2 = __len21; 45600b57cec5SDimitry Andric } 45610b57cec5SDimitry Andric } 45620b57cec5SDimitry Andric} 45630b57cec5SDimitry Andric 45640b57cec5SDimitry Andrictemplate <class _BidirectionalIterator, class _Compare> 45650b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 45660b57cec5SDimitry Andricvoid 45670b57cec5SDimitry Andricinplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 45680b57cec5SDimitry Andric _Compare __comp) 45690b57cec5SDimitry Andric{ 45700b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 45710b57cec5SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; 45720b57cec5SDimitry Andric difference_type __len1 = _VSTD::distance(__first, __middle); 45730b57cec5SDimitry Andric difference_type __len2 = _VSTD::distance(__middle, __last); 45740b57cec5SDimitry Andric difference_type __buf_size = _VSTD::min(__len1, __len2); 45750b57cec5SDimitry Andric pair<value_type*, ptrdiff_t> __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size); 45760b57cec5SDimitry Andric unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first); 45770b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 45780b57cec5SDimitry Andric return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2, 45790b57cec5SDimitry Andric __buf.first, __buf.second); 45800b57cec5SDimitry Andric} 45810b57cec5SDimitry Andric 45820b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 45830b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 45840b57cec5SDimitry Andricvoid 45850b57cec5SDimitry Andricinplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) 45860b57cec5SDimitry Andric{ 45870b57cec5SDimitry Andric _VSTD::inplace_merge(__first, __middle, __last, 45880b57cec5SDimitry Andric __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); 45890b57cec5SDimitry Andric} 45900b57cec5SDimitry Andric 45910b57cec5SDimitry Andric// stable_sort 45920b57cec5SDimitry Andric 45930b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2> 45940b57cec5SDimitry Andricvoid 45950b57cec5SDimitry Andric__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, 45960b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, 45970b57cec5SDimitry Andric typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp) 45980b57cec5SDimitry Andric{ 45990b57cec5SDimitry Andric typedef typename iterator_traits<_InputIterator1>::value_type value_type; 46000b57cec5SDimitry Andric __destruct_n __d(0); 46010b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h(__result, __d); 46020b57cec5SDimitry Andric for (; true; ++__result) 46030b57cec5SDimitry Andric { 46040b57cec5SDimitry Andric if (__first1 == __last1) 46050b57cec5SDimitry Andric { 4606e40139ffSDimitry Andric for (; __first2 != __last2; ++__first2, ++__result, (void) __d.__incr((value_type*)0)) 46070b57cec5SDimitry Andric ::new (__result) value_type(_VSTD::move(*__first2)); 46080b57cec5SDimitry Andric __h.release(); 46090b57cec5SDimitry Andric return; 46100b57cec5SDimitry Andric } 46110b57cec5SDimitry Andric if (__first2 == __last2) 46120b57cec5SDimitry Andric { 4613e40139ffSDimitry Andric for (; __first1 != __last1; ++__first1, ++__result, (void) __d.__incr((value_type*)0)) 46140b57cec5SDimitry Andric ::new (__result) value_type(_VSTD::move(*__first1)); 46150b57cec5SDimitry Andric __h.release(); 46160b57cec5SDimitry Andric return; 46170b57cec5SDimitry Andric } 46180b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 46190b57cec5SDimitry Andric { 46200b57cec5SDimitry Andric ::new (__result) value_type(_VSTD::move(*__first2)); 46210b57cec5SDimitry Andric __d.__incr((value_type*)0); 46220b57cec5SDimitry Andric ++__first2; 46230b57cec5SDimitry Andric } 46240b57cec5SDimitry Andric else 46250b57cec5SDimitry Andric { 46260b57cec5SDimitry Andric ::new (__result) value_type(_VSTD::move(*__first1)); 46270b57cec5SDimitry Andric __d.__incr((value_type*)0); 46280b57cec5SDimitry Andric ++__first1; 46290b57cec5SDimitry Andric } 46300b57cec5SDimitry Andric } 46310b57cec5SDimitry Andric} 46320b57cec5SDimitry Andric 46330b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 46340b57cec5SDimitry Andricvoid 46350b57cec5SDimitry Andric__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, 46360b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, 46370b57cec5SDimitry Andric _OutputIterator __result, _Compare __comp) 46380b57cec5SDimitry Andric{ 46390b57cec5SDimitry Andric for (; __first1 != __last1; ++__result) 46400b57cec5SDimitry Andric { 46410b57cec5SDimitry Andric if (__first2 == __last2) 46420b57cec5SDimitry Andric { 4643e40139ffSDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__result) 46440b57cec5SDimitry Andric *__result = _VSTD::move(*__first1); 46450b57cec5SDimitry Andric return; 46460b57cec5SDimitry Andric } 46470b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 46480b57cec5SDimitry Andric { 46490b57cec5SDimitry Andric *__result = _VSTD::move(*__first2); 46500b57cec5SDimitry Andric ++__first2; 46510b57cec5SDimitry Andric } 46520b57cec5SDimitry Andric else 46530b57cec5SDimitry Andric { 46540b57cec5SDimitry Andric *__result = _VSTD::move(*__first1); 46550b57cec5SDimitry Andric ++__first1; 46560b57cec5SDimitry Andric } 46570b57cec5SDimitry Andric } 4658e40139ffSDimitry Andric for (; __first2 != __last2; ++__first2, (void) ++__result) 46590b57cec5SDimitry Andric *__result = _VSTD::move(*__first2); 46600b57cec5SDimitry Andric} 46610b57cec5SDimitry Andric 46620b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 46630b57cec5SDimitry Andricvoid 46640b57cec5SDimitry Andric__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 46650b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len, 46660b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size); 46670b57cec5SDimitry Andric 46680b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 46690b57cec5SDimitry Andricvoid 46700b57cec5SDimitry Andric__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp, 46710b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len, 46720b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::value_type* __first2) 46730b57cec5SDimitry Andric{ 46740b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 46750b57cec5SDimitry Andric switch (__len) 46760b57cec5SDimitry Andric { 46770b57cec5SDimitry Andric case 0: 46780b57cec5SDimitry Andric return; 46790b57cec5SDimitry Andric case 1: 46800b57cec5SDimitry Andric ::new(__first2) value_type(_VSTD::move(*__first1)); 46810b57cec5SDimitry Andric return; 46820b57cec5SDimitry Andric case 2: 46830b57cec5SDimitry Andric __destruct_n __d(0); 46840b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h2(__first2, __d); 46850b57cec5SDimitry Andric if (__comp(*--__last1, *__first1)) 46860b57cec5SDimitry Andric { 46870b57cec5SDimitry Andric ::new(__first2) value_type(_VSTD::move(*__last1)); 46880b57cec5SDimitry Andric __d.__incr((value_type*)0); 46890b57cec5SDimitry Andric ++__first2; 46900b57cec5SDimitry Andric ::new(__first2) value_type(_VSTD::move(*__first1)); 46910b57cec5SDimitry Andric } 46920b57cec5SDimitry Andric else 46930b57cec5SDimitry Andric { 46940b57cec5SDimitry Andric ::new(__first2) value_type(_VSTD::move(*__first1)); 46950b57cec5SDimitry Andric __d.__incr((value_type*)0); 46960b57cec5SDimitry Andric ++__first2; 46970b57cec5SDimitry Andric ::new(__first2) value_type(_VSTD::move(*__last1)); 46980b57cec5SDimitry Andric } 46990b57cec5SDimitry Andric __h2.release(); 47000b57cec5SDimitry Andric return; 47010b57cec5SDimitry Andric } 47020b57cec5SDimitry Andric if (__len <= 8) 47030b57cec5SDimitry Andric { 47040b57cec5SDimitry Andric __insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp); 47050b57cec5SDimitry Andric return; 47060b57cec5SDimitry Andric } 47070b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; 47080b57cec5SDimitry Andric _RandomAccessIterator __m = __first1 + __l2; 47090b57cec5SDimitry Andric __stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2); 47100b57cec5SDimitry Andric __stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); 47110b57cec5SDimitry Andric __merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp); 47120b57cec5SDimitry Andric} 47130b57cec5SDimitry Andric 47140b57cec5SDimitry Andrictemplate <class _Tp> 47150b57cec5SDimitry Andricstruct __stable_sort_switch 47160b57cec5SDimitry Andric{ 47170b57cec5SDimitry Andric static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value; 47180b57cec5SDimitry Andric}; 47190b57cec5SDimitry Andric 47200b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 47210b57cec5SDimitry Andricvoid 47220b57cec5SDimitry Andric__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 47230b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len, 47240b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size) 47250b57cec5SDimitry Andric{ 47260b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 47270b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 47280b57cec5SDimitry Andric switch (__len) 47290b57cec5SDimitry Andric { 47300b57cec5SDimitry Andric case 0: 47310b57cec5SDimitry Andric case 1: 47320b57cec5SDimitry Andric return; 47330b57cec5SDimitry Andric case 2: 47340b57cec5SDimitry Andric if (__comp(*--__last, *__first)) 47350b57cec5SDimitry Andric swap(*__first, *__last); 47360b57cec5SDimitry Andric return; 47370b57cec5SDimitry Andric } 47380b57cec5SDimitry Andric if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value)) 47390b57cec5SDimitry Andric { 47400b57cec5SDimitry Andric __insertion_sort<_Compare>(__first, __last, __comp); 47410b57cec5SDimitry Andric return; 47420b57cec5SDimitry Andric } 47430b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; 47440b57cec5SDimitry Andric _RandomAccessIterator __m = __first + __l2; 47450b57cec5SDimitry Andric if (__len <= __buff_size) 47460b57cec5SDimitry Andric { 47470b57cec5SDimitry Andric __destruct_n __d(0); 47480b57cec5SDimitry Andric unique_ptr<value_type, __destruct_n&> __h2(__buff, __d); 47490b57cec5SDimitry Andric __stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff); 47500b57cec5SDimitry Andric __d.__set(__l2, (value_type*)0); 47510b57cec5SDimitry Andric __stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); 47520b57cec5SDimitry Andric __d.__set(__len, (value_type*)0); 47530b57cec5SDimitry Andric __merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); 47540b57cec5SDimitry Andric// __merge<_Compare>(move_iterator<value_type*>(__buff), 47550b57cec5SDimitry Andric// move_iterator<value_type*>(__buff + __l2), 47560b57cec5SDimitry Andric// move_iterator<_RandomAccessIterator>(__buff + __l2), 47570b57cec5SDimitry Andric// move_iterator<_RandomAccessIterator>(__buff + __len), 47580b57cec5SDimitry Andric// __first, __comp); 47590b57cec5SDimitry Andric return; 47600b57cec5SDimitry Andric } 47610b57cec5SDimitry Andric __stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size); 47620b57cec5SDimitry Andric __stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); 47630b57cec5SDimitry Andric __inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); 47640b57cec5SDimitry Andric} 47650b57cec5SDimitry Andric 47660b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 47670b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 47680b57cec5SDimitry Andricvoid 47690b57cec5SDimitry Andricstable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 47700b57cec5SDimitry Andric{ 47710b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 47720b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 47730b57cec5SDimitry Andric difference_type __len = __last - __first; 47740b57cec5SDimitry Andric pair<value_type*, ptrdiff_t> __buf(0, 0); 47750b57cec5SDimitry Andric unique_ptr<value_type, __return_temporary_buffer> __h; 47760b57cec5SDimitry Andric if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) 47770b57cec5SDimitry Andric { 47780b57cec5SDimitry Andric __buf = _VSTD::get_temporary_buffer<value_type>(__len); 47790b57cec5SDimitry Andric __h.reset(__buf.first); 47800b57cec5SDimitry Andric } 47810b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 47820b57cec5SDimitry Andric __stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second); 47830b57cec5SDimitry Andric} 47840b57cec5SDimitry Andric 47850b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 47860b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 47870b57cec5SDimitry Andricvoid 47880b57cec5SDimitry Andricstable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) 47890b57cec5SDimitry Andric{ 47900b57cec5SDimitry Andric _VSTD::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 47910b57cec5SDimitry Andric} 47920b57cec5SDimitry Andric 47930b57cec5SDimitry Andric// is_heap_until 47940b57cec5SDimitry Andric 47950b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 47960b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator 47970b57cec5SDimitry Andricis_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 47980b57cec5SDimitry Andric{ 47990b57cec5SDimitry Andric typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::difference_type difference_type; 48000b57cec5SDimitry Andric difference_type __len = __last - __first; 48010b57cec5SDimitry Andric difference_type __p = 0; 48020b57cec5SDimitry Andric difference_type __c = 1; 48030b57cec5SDimitry Andric _RandomAccessIterator __pp = __first; 48040b57cec5SDimitry Andric while (__c < __len) 48050b57cec5SDimitry Andric { 48060b57cec5SDimitry Andric _RandomAccessIterator __cp = __first + __c; 48070b57cec5SDimitry Andric if (__comp(*__pp, *__cp)) 48080b57cec5SDimitry Andric return __cp; 48090b57cec5SDimitry Andric ++__c; 48100b57cec5SDimitry Andric ++__cp; 48110b57cec5SDimitry Andric if (__c == __len) 48120b57cec5SDimitry Andric return __last; 48130b57cec5SDimitry Andric if (__comp(*__pp, *__cp)) 48140b57cec5SDimitry Andric return __cp; 48150b57cec5SDimitry Andric ++__p; 48160b57cec5SDimitry Andric ++__pp; 48170b57cec5SDimitry Andric __c = 2 * __p + 1; 48180b57cec5SDimitry Andric } 48190b57cec5SDimitry Andric return __last; 48200b57cec5SDimitry Andric} 48210b57cec5SDimitry Andric 48220b57cec5SDimitry Andrictemplate<class _RandomAccessIterator> 48230b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 48240b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 48250b57cec5SDimitry Andric_RandomAccessIterator 48260b57cec5SDimitry Andricis_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) 48270b57cec5SDimitry Andric{ 48280b57cec5SDimitry Andric return _VSTD::is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 48290b57cec5SDimitry Andric} 48300b57cec5SDimitry Andric 48310b57cec5SDimitry Andric// is_heap 48320b57cec5SDimitry Andric 48330b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 48340b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 48350b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 48360b57cec5SDimitry Andricbool 48370b57cec5SDimitry Andricis_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 48380b57cec5SDimitry Andric{ 48390b57cec5SDimitry Andric return _VSTD::is_heap_until(__first, __last, __comp) == __last; 48400b57cec5SDimitry Andric} 48410b57cec5SDimitry Andric 48420b57cec5SDimitry Andrictemplate<class _RandomAccessIterator> 48430b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 48440b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 48450b57cec5SDimitry Andricbool 48460b57cec5SDimitry Andricis_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 48470b57cec5SDimitry Andric{ 48480b57cec5SDimitry Andric return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 48490b57cec5SDimitry Andric} 48500b57cec5SDimitry Andric 48510b57cec5SDimitry Andric// push_heap 48520b57cec5SDimitry Andric 48530b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 48540b57cec5SDimitry Andricvoid 48550b57cec5SDimitry Andric__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 48560b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len) 48570b57cec5SDimitry Andric{ 48580b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 48590b57cec5SDimitry Andric if (__len > 1) 48600b57cec5SDimitry Andric { 48610b57cec5SDimitry Andric __len = (__len - 2) / 2; 48620b57cec5SDimitry Andric _RandomAccessIterator __ptr = __first + __len; 48630b57cec5SDimitry Andric if (__comp(*__ptr, *--__last)) 48640b57cec5SDimitry Andric { 48650b57cec5SDimitry Andric value_type __t(_VSTD::move(*__last)); 48660b57cec5SDimitry Andric do 48670b57cec5SDimitry Andric { 48680b57cec5SDimitry Andric *__last = _VSTD::move(*__ptr); 48690b57cec5SDimitry Andric __last = __ptr; 48700b57cec5SDimitry Andric if (__len == 0) 48710b57cec5SDimitry Andric break; 48720b57cec5SDimitry Andric __len = (__len - 1) / 2; 48730b57cec5SDimitry Andric __ptr = __first + __len; 48740b57cec5SDimitry Andric } while (__comp(*__ptr, __t)); 48750b57cec5SDimitry Andric *__last = _VSTD::move(__t); 48760b57cec5SDimitry Andric } 48770b57cec5SDimitry Andric } 48780b57cec5SDimitry Andric} 48790b57cec5SDimitry Andric 48800b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 48810b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 48820b57cec5SDimitry Andricvoid 48830b57cec5SDimitry Andricpush_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 48840b57cec5SDimitry Andric{ 48850b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 48860b57cec5SDimitry Andric __sift_up<_Comp_ref>(__first, __last, __comp, __last - __first); 48870b57cec5SDimitry Andric} 48880b57cec5SDimitry Andric 48890b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 48900b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 48910b57cec5SDimitry Andricvoid 48920b57cec5SDimitry Andricpush_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 48930b57cec5SDimitry Andric{ 48940b57cec5SDimitry Andric _VSTD::push_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 48950b57cec5SDimitry Andric} 48960b57cec5SDimitry Andric 48970b57cec5SDimitry Andric// pop_heap 48980b57cec5SDimitry Andric 48990b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 49000b57cec5SDimitry Andricvoid 49010b57cec5SDimitry Andric__sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, 49020b57cec5SDimitry Andric _Compare __comp, 49030b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len, 49040b57cec5SDimitry Andric _RandomAccessIterator __start) 49050b57cec5SDimitry Andric{ 49060b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 49070b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 49080b57cec5SDimitry Andric // left-child of __start is at 2 * __start + 1 49090b57cec5SDimitry Andric // right-child of __start is at 2 * __start + 2 49100b57cec5SDimitry Andric difference_type __child = __start - __first; 49110b57cec5SDimitry Andric 49120b57cec5SDimitry Andric if (__len < 2 || (__len - 2) / 2 < __child) 49130b57cec5SDimitry Andric return; 49140b57cec5SDimitry Andric 49150b57cec5SDimitry Andric __child = 2 * __child + 1; 49160b57cec5SDimitry Andric _RandomAccessIterator __child_i = __first + __child; 49170b57cec5SDimitry Andric 49180b57cec5SDimitry Andric if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { 49190b57cec5SDimitry Andric // right-child exists and is greater than left-child 49200b57cec5SDimitry Andric ++__child_i; 49210b57cec5SDimitry Andric ++__child; 49220b57cec5SDimitry Andric } 49230b57cec5SDimitry Andric 49240b57cec5SDimitry Andric // check if we are in heap-order 49250b57cec5SDimitry Andric if (__comp(*__child_i, *__start)) 49260b57cec5SDimitry Andric // we are, __start is larger than it's largest child 49270b57cec5SDimitry Andric return; 49280b57cec5SDimitry Andric 49290b57cec5SDimitry Andric value_type __top(_VSTD::move(*__start)); 49300b57cec5SDimitry Andric do 49310b57cec5SDimitry Andric { 49320b57cec5SDimitry Andric // we are not in heap-order, swap the parent with it's largest child 49330b57cec5SDimitry Andric *__start = _VSTD::move(*__child_i); 49340b57cec5SDimitry Andric __start = __child_i; 49350b57cec5SDimitry Andric 49360b57cec5SDimitry Andric if ((__len - 2) / 2 < __child) 49370b57cec5SDimitry Andric break; 49380b57cec5SDimitry Andric 49390b57cec5SDimitry Andric // recompute the child based off of the updated parent 49400b57cec5SDimitry Andric __child = 2 * __child + 1; 49410b57cec5SDimitry Andric __child_i = __first + __child; 49420b57cec5SDimitry Andric 49430b57cec5SDimitry Andric if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { 49440b57cec5SDimitry Andric // right-child exists and is greater than left-child 49450b57cec5SDimitry Andric ++__child_i; 49460b57cec5SDimitry Andric ++__child; 49470b57cec5SDimitry Andric } 49480b57cec5SDimitry Andric 49490b57cec5SDimitry Andric // check if we are in heap-order 49500b57cec5SDimitry Andric } while (!__comp(*__child_i, __top)); 49510b57cec5SDimitry Andric *__start = _VSTD::move(__top); 49520b57cec5SDimitry Andric} 49530b57cec5SDimitry Andric 49540b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 49550b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 49560b57cec5SDimitry Andricvoid 49570b57cec5SDimitry Andric__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 49580b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len) 49590b57cec5SDimitry Andric{ 49600b57cec5SDimitry Andric if (__len > 1) 49610b57cec5SDimitry Andric { 49620b57cec5SDimitry Andric swap(*__first, *--__last); 49630b57cec5SDimitry Andric __sift_down<_Compare>(__first, __last, __comp, __len - 1, __first); 49640b57cec5SDimitry Andric } 49650b57cec5SDimitry Andric} 49660b57cec5SDimitry Andric 49670b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 49680b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 49690b57cec5SDimitry Andricvoid 49700b57cec5SDimitry Andricpop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 49710b57cec5SDimitry Andric{ 49720b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 49730b57cec5SDimitry Andric __pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first); 49740b57cec5SDimitry Andric} 49750b57cec5SDimitry Andric 49760b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 49770b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 49780b57cec5SDimitry Andricvoid 49790b57cec5SDimitry Andricpop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 49800b57cec5SDimitry Andric{ 49810b57cec5SDimitry Andric _VSTD::pop_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 49820b57cec5SDimitry Andric} 49830b57cec5SDimitry Andric 49840b57cec5SDimitry Andric// make_heap 49850b57cec5SDimitry Andric 49860b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 49870b57cec5SDimitry Andricvoid 49880b57cec5SDimitry Andric__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 49890b57cec5SDimitry Andric{ 49900b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 49910b57cec5SDimitry Andric difference_type __n = __last - __first; 49920b57cec5SDimitry Andric if (__n > 1) 49930b57cec5SDimitry Andric { 49940b57cec5SDimitry Andric // start from the first parent, there is no need to consider children 49950b57cec5SDimitry Andric for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) 49960b57cec5SDimitry Andric { 49970b57cec5SDimitry Andric __sift_down<_Compare>(__first, __last, __comp, __n, __first + __start); 49980b57cec5SDimitry Andric } 49990b57cec5SDimitry Andric } 50000b57cec5SDimitry Andric} 50010b57cec5SDimitry Andric 50020b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 50030b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 50040b57cec5SDimitry Andricvoid 50050b57cec5SDimitry Andricmake_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 50060b57cec5SDimitry Andric{ 50070b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 50080b57cec5SDimitry Andric __make_heap<_Comp_ref>(__first, __last, __comp); 50090b57cec5SDimitry Andric} 50100b57cec5SDimitry Andric 50110b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 50120b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 50130b57cec5SDimitry Andricvoid 50140b57cec5SDimitry Andricmake_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 50150b57cec5SDimitry Andric{ 50160b57cec5SDimitry Andric _VSTD::make_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 50170b57cec5SDimitry Andric} 50180b57cec5SDimitry Andric 50190b57cec5SDimitry Andric// sort_heap 50200b57cec5SDimitry Andric 50210b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 50220b57cec5SDimitry Andricvoid 50230b57cec5SDimitry Andric__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 50240b57cec5SDimitry Andric{ 50250b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 5026e40139ffSDimitry Andric for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) 50270b57cec5SDimitry Andric __pop_heap<_Compare>(__first, __last, __comp, __n); 50280b57cec5SDimitry Andric} 50290b57cec5SDimitry Andric 50300b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 50310b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 50320b57cec5SDimitry Andricvoid 50330b57cec5SDimitry Andricsort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 50340b57cec5SDimitry Andric{ 50350b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 50360b57cec5SDimitry Andric __sort_heap<_Comp_ref>(__first, __last, __comp); 50370b57cec5SDimitry Andric} 50380b57cec5SDimitry Andric 50390b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 50400b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 50410b57cec5SDimitry Andricvoid 50420b57cec5SDimitry Andricsort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 50430b57cec5SDimitry Andric{ 50440b57cec5SDimitry Andric _VSTD::sort_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 50450b57cec5SDimitry Andric} 50460b57cec5SDimitry Andric 50470b57cec5SDimitry Andric// partial_sort 50480b57cec5SDimitry Andric 50490b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 50500b57cec5SDimitry Andricvoid 50510b57cec5SDimitry Andric__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, 50520b57cec5SDimitry Andric _Compare __comp) 50530b57cec5SDimitry Andric{ 50540b57cec5SDimitry Andric __make_heap<_Compare>(__first, __middle, __comp); 50550b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; 50560b57cec5SDimitry Andric for (_RandomAccessIterator __i = __middle; __i != __last; ++__i) 50570b57cec5SDimitry Andric { 50580b57cec5SDimitry Andric if (__comp(*__i, *__first)) 50590b57cec5SDimitry Andric { 50600b57cec5SDimitry Andric swap(*__i, *__first); 50610b57cec5SDimitry Andric __sift_down<_Compare>(__first, __middle, __comp, __len, __first); 50620b57cec5SDimitry Andric } 50630b57cec5SDimitry Andric } 50640b57cec5SDimitry Andric __sort_heap<_Compare>(__first, __middle, __comp); 50650b57cec5SDimitry Andric} 50660b57cec5SDimitry Andric 50670b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 50680b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 50690b57cec5SDimitry Andricvoid 50700b57cec5SDimitry Andricpartial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, 50710b57cec5SDimitry Andric _Compare __comp) 50720b57cec5SDimitry Andric{ 50730b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 50740b57cec5SDimitry Andric __partial_sort<_Comp_ref>(__first, __middle, __last, __comp); 50750b57cec5SDimitry Andric} 50760b57cec5SDimitry Andric 50770b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 50780b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 50790b57cec5SDimitry Andricvoid 50800b57cec5SDimitry Andricpartial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) 50810b57cec5SDimitry Andric{ 50820b57cec5SDimitry Andric _VSTD::partial_sort(__first, __middle, __last, 50830b57cec5SDimitry Andric __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 50840b57cec5SDimitry Andric} 50850b57cec5SDimitry Andric 50860b57cec5SDimitry Andric// partial_sort_copy 50870b57cec5SDimitry Andric 50880b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator, class _RandomAccessIterator> 50890b57cec5SDimitry Andric_RandomAccessIterator 50900b57cec5SDimitry Andric__partial_sort_copy(_InputIterator __first, _InputIterator __last, 50910b57cec5SDimitry Andric _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) 50920b57cec5SDimitry Andric{ 50930b57cec5SDimitry Andric _RandomAccessIterator __r = __result_first; 50940b57cec5SDimitry Andric if (__r != __result_last) 50950b57cec5SDimitry Andric { 5096e40139ffSDimitry Andric for (; __first != __last && __r != __result_last; ++__first, (void) ++__r) 50970b57cec5SDimitry Andric *__r = *__first; 50980b57cec5SDimitry Andric __make_heap<_Compare>(__result_first, __r, __comp); 50990b57cec5SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; 51000b57cec5SDimitry Andric for (; __first != __last; ++__first) 51010b57cec5SDimitry Andric if (__comp(*__first, *__result_first)) 51020b57cec5SDimitry Andric { 51030b57cec5SDimitry Andric *__result_first = *__first; 51040b57cec5SDimitry Andric __sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first); 51050b57cec5SDimitry Andric } 51060b57cec5SDimitry Andric __sort_heap<_Compare>(__result_first, __r, __comp); 51070b57cec5SDimitry Andric } 51080b57cec5SDimitry Andric return __r; 51090b57cec5SDimitry Andric} 51100b57cec5SDimitry Andric 51110b57cec5SDimitry Andrictemplate <class _InputIterator, class _RandomAccessIterator, class _Compare> 51120b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 51130b57cec5SDimitry Andric_RandomAccessIterator 51140b57cec5SDimitry Andricpartial_sort_copy(_InputIterator __first, _InputIterator __last, 51150b57cec5SDimitry Andric _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) 51160b57cec5SDimitry Andric{ 51170b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 51180b57cec5SDimitry Andric return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp); 51190b57cec5SDimitry Andric} 51200b57cec5SDimitry Andric 51210b57cec5SDimitry Andrictemplate <class _InputIterator, class _RandomAccessIterator> 51220b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 51230b57cec5SDimitry Andric_RandomAccessIterator 51240b57cec5SDimitry Andricpartial_sort_copy(_InputIterator __first, _InputIterator __last, 51250b57cec5SDimitry Andric _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) 51260b57cec5SDimitry Andric{ 51270b57cec5SDimitry Andric return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, 51280b57cec5SDimitry Andric __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 51290b57cec5SDimitry Andric} 51300b57cec5SDimitry Andric 51310b57cec5SDimitry Andric// nth_element 51320b57cec5SDimitry Andric 51330b57cec5SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 51340b57cec5SDimitry Andricvoid 51350b57cec5SDimitry Andric__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) 51360b57cec5SDimitry Andric{ 51370b57cec5SDimitry Andric // _Compare is known to be a reference type 51380b57cec5SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 51390b57cec5SDimitry Andric const difference_type __limit = 7; 51400b57cec5SDimitry Andric while (true) 51410b57cec5SDimitry Andric { 51420b57cec5SDimitry Andric __restart: 51430b57cec5SDimitry Andric if (__nth == __last) 51440b57cec5SDimitry Andric return; 51450b57cec5SDimitry Andric difference_type __len = __last - __first; 51460b57cec5SDimitry Andric switch (__len) 51470b57cec5SDimitry Andric { 51480b57cec5SDimitry Andric case 0: 51490b57cec5SDimitry Andric case 1: 51500b57cec5SDimitry Andric return; 51510b57cec5SDimitry Andric case 2: 51520b57cec5SDimitry Andric if (__comp(*--__last, *__first)) 51530b57cec5SDimitry Andric swap(*__first, *__last); 51540b57cec5SDimitry Andric return; 51550b57cec5SDimitry Andric case 3: 51560b57cec5SDimitry Andric { 51570b57cec5SDimitry Andric _RandomAccessIterator __m = __first; 51580b57cec5SDimitry Andric _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp); 51590b57cec5SDimitry Andric return; 51600b57cec5SDimitry Andric } 51610b57cec5SDimitry Andric } 51620b57cec5SDimitry Andric if (__len <= __limit) 51630b57cec5SDimitry Andric { 51640b57cec5SDimitry Andric __selection_sort<_Compare>(__first, __last, __comp); 51650b57cec5SDimitry Andric return; 51660b57cec5SDimitry Andric } 51670b57cec5SDimitry Andric // __len > __limit >= 3 51680b57cec5SDimitry Andric _RandomAccessIterator __m = __first + __len/2; 51690b57cec5SDimitry Andric _RandomAccessIterator __lm1 = __last; 51700b57cec5SDimitry Andric unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp); 51710b57cec5SDimitry Andric // *__m is median 51720b57cec5SDimitry Andric // partition [__first, __m) < *__m and *__m <= [__m, __last) 51730b57cec5SDimitry Andric // (this inhibits tossing elements equivalent to __m around unnecessarily) 51740b57cec5SDimitry Andric _RandomAccessIterator __i = __first; 51750b57cec5SDimitry Andric _RandomAccessIterator __j = __lm1; 51760b57cec5SDimitry Andric // j points beyond range to be tested, *__lm1 is known to be <= *__m 51770b57cec5SDimitry Andric // The search going up is known to be guarded but the search coming down isn't. 51780b57cec5SDimitry Andric // Prime the downward search with a guard. 51790b57cec5SDimitry Andric if (!__comp(*__i, *__m)) // if *__first == *__m 51800b57cec5SDimitry Andric { 51810b57cec5SDimitry Andric // *__first == *__m, *__first doesn't go in first part 51820b57cec5SDimitry Andric // manually guard downward moving __j against __i 51830b57cec5SDimitry Andric while (true) 51840b57cec5SDimitry Andric { 51850b57cec5SDimitry Andric if (__i == --__j) 51860b57cec5SDimitry Andric { 51870b57cec5SDimitry Andric // *__first == *__m, *__m <= all other elements 51880b57cec5SDimitry Andric // Parition instead into [__first, __i) == *__first and *__first < [__i, __last) 51890b57cec5SDimitry Andric ++__i; // __first + 1 51900b57cec5SDimitry Andric __j = __last; 51910b57cec5SDimitry Andric if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1) 51920b57cec5SDimitry Andric { 51930b57cec5SDimitry Andric while (true) 51940b57cec5SDimitry Andric { 51950b57cec5SDimitry Andric if (__i == __j) 51960b57cec5SDimitry Andric return; // [__first, __last) all equivalent elements 51970b57cec5SDimitry Andric if (__comp(*__first, *__i)) 51980b57cec5SDimitry Andric { 51990b57cec5SDimitry Andric swap(*__i, *__j); 52000b57cec5SDimitry Andric ++__n_swaps; 52010b57cec5SDimitry Andric ++__i; 52020b57cec5SDimitry Andric break; 52030b57cec5SDimitry Andric } 52040b57cec5SDimitry Andric ++__i; 52050b57cec5SDimitry Andric } 52060b57cec5SDimitry Andric } 52070b57cec5SDimitry Andric // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 52080b57cec5SDimitry Andric if (__i == __j) 52090b57cec5SDimitry Andric return; 52100b57cec5SDimitry Andric while (true) 52110b57cec5SDimitry Andric { 52120b57cec5SDimitry Andric while (!__comp(*__first, *__i)) 52130b57cec5SDimitry Andric ++__i; 52140b57cec5SDimitry Andric while (__comp(*__first, *--__j)) 52150b57cec5SDimitry Andric ; 52160b57cec5SDimitry Andric if (__i >= __j) 52170b57cec5SDimitry Andric break; 52180b57cec5SDimitry Andric swap(*__i, *__j); 52190b57cec5SDimitry Andric ++__n_swaps; 52200b57cec5SDimitry Andric ++__i; 52210b57cec5SDimitry Andric } 52220b57cec5SDimitry Andric // [__first, __i) == *__first and *__first < [__i, __last) 52230b57cec5SDimitry Andric // The first part is sorted, 52240b57cec5SDimitry Andric if (__nth < __i) 52250b57cec5SDimitry Andric return; 52260b57cec5SDimitry Andric // __nth_element the secod part 52270b57cec5SDimitry Andric // __nth_element<_Compare>(__i, __nth, __last, __comp); 52280b57cec5SDimitry Andric __first = __i; 52290b57cec5SDimitry Andric goto __restart; 52300b57cec5SDimitry Andric } 52310b57cec5SDimitry Andric if (__comp(*__j, *__m)) 52320b57cec5SDimitry Andric { 52330b57cec5SDimitry Andric swap(*__i, *__j); 52340b57cec5SDimitry Andric ++__n_swaps; 52350b57cec5SDimitry Andric break; // found guard for downward moving __j, now use unguarded partition 52360b57cec5SDimitry Andric } 52370b57cec5SDimitry Andric } 52380b57cec5SDimitry Andric } 52390b57cec5SDimitry Andric ++__i; 52400b57cec5SDimitry Andric // j points beyond range to be tested, *__lm1 is known to be <= *__m 52410b57cec5SDimitry Andric // if not yet partitioned... 52420b57cec5SDimitry Andric if (__i < __j) 52430b57cec5SDimitry Andric { 52440b57cec5SDimitry Andric // known that *(__i - 1) < *__m 52450b57cec5SDimitry Andric while (true) 52460b57cec5SDimitry Andric { 52470b57cec5SDimitry Andric // __m still guards upward moving __i 52480b57cec5SDimitry Andric while (__comp(*__i, *__m)) 52490b57cec5SDimitry Andric ++__i; 52500b57cec5SDimitry Andric // It is now known that a guard exists for downward moving __j 52510b57cec5SDimitry Andric while (!__comp(*--__j, *__m)) 52520b57cec5SDimitry Andric ; 52530b57cec5SDimitry Andric if (__i >= __j) 52540b57cec5SDimitry Andric break; 52550b57cec5SDimitry Andric swap(*__i, *__j); 52560b57cec5SDimitry Andric ++__n_swaps; 52570b57cec5SDimitry Andric // It is known that __m != __j 52580b57cec5SDimitry Andric // If __m just moved, follow it 52590b57cec5SDimitry Andric if (__m == __i) 52600b57cec5SDimitry Andric __m = __j; 52610b57cec5SDimitry Andric ++__i; 52620b57cec5SDimitry Andric } 52630b57cec5SDimitry Andric } 52640b57cec5SDimitry Andric // [__first, __i) < *__m and *__m <= [__i, __last) 52650b57cec5SDimitry Andric if (__i != __m && __comp(*__m, *__i)) 52660b57cec5SDimitry Andric { 52670b57cec5SDimitry Andric swap(*__i, *__m); 52680b57cec5SDimitry Andric ++__n_swaps; 52690b57cec5SDimitry Andric } 52700b57cec5SDimitry Andric // [__first, __i) < *__i and *__i <= [__i+1, __last) 52710b57cec5SDimitry Andric if (__nth == __i) 52720b57cec5SDimitry Andric return; 52730b57cec5SDimitry Andric if (__n_swaps == 0) 52740b57cec5SDimitry Andric { 52750b57cec5SDimitry Andric // We were given a perfectly partitioned sequence. Coincidence? 52760b57cec5SDimitry Andric if (__nth < __i) 52770b57cec5SDimitry Andric { 52780b57cec5SDimitry Andric // Check for [__first, __i) already sorted 52790b57cec5SDimitry Andric __j = __m = __first; 52800b57cec5SDimitry Andric while (++__j != __i) 52810b57cec5SDimitry Andric { 52820b57cec5SDimitry Andric if (__comp(*__j, *__m)) 52830b57cec5SDimitry Andric // not yet sorted, so sort 52840b57cec5SDimitry Andric goto not_sorted; 52850b57cec5SDimitry Andric __m = __j; 52860b57cec5SDimitry Andric } 52870b57cec5SDimitry Andric // [__first, __i) sorted 52880b57cec5SDimitry Andric return; 52890b57cec5SDimitry Andric } 52900b57cec5SDimitry Andric else 52910b57cec5SDimitry Andric { 52920b57cec5SDimitry Andric // Check for [__i, __last) already sorted 52930b57cec5SDimitry Andric __j = __m = __i; 52940b57cec5SDimitry Andric while (++__j != __last) 52950b57cec5SDimitry Andric { 52960b57cec5SDimitry Andric if (__comp(*__j, *__m)) 52970b57cec5SDimitry Andric // not yet sorted, so sort 52980b57cec5SDimitry Andric goto not_sorted; 52990b57cec5SDimitry Andric __m = __j; 53000b57cec5SDimitry Andric } 53010b57cec5SDimitry Andric // [__i, __last) sorted 53020b57cec5SDimitry Andric return; 53030b57cec5SDimitry Andric } 53040b57cec5SDimitry Andric } 53050b57cec5SDimitry Andricnot_sorted: 53060b57cec5SDimitry Andric // __nth_element on range containing __nth 53070b57cec5SDimitry Andric if (__nth < __i) 53080b57cec5SDimitry Andric { 53090b57cec5SDimitry Andric // __nth_element<_Compare>(__first, __nth, __i, __comp); 53100b57cec5SDimitry Andric __last = __i; 53110b57cec5SDimitry Andric } 53120b57cec5SDimitry Andric else 53130b57cec5SDimitry Andric { 53140b57cec5SDimitry Andric // __nth_element<_Compare>(__i+1, __nth, __last, __comp); 53150b57cec5SDimitry Andric __first = ++__i; 53160b57cec5SDimitry Andric } 53170b57cec5SDimitry Andric } 53180b57cec5SDimitry Andric} 53190b57cec5SDimitry Andric 53200b57cec5SDimitry Andrictemplate <class _RandomAccessIterator, class _Compare> 53210b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 53220b57cec5SDimitry Andricvoid 53230b57cec5SDimitry Andricnth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) 53240b57cec5SDimitry Andric{ 53250b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 53260b57cec5SDimitry Andric __nth_element<_Comp_ref>(__first, __nth, __last, __comp); 53270b57cec5SDimitry Andric} 53280b57cec5SDimitry Andric 53290b57cec5SDimitry Andrictemplate <class _RandomAccessIterator> 53300b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 53310b57cec5SDimitry Andricvoid 53320b57cec5SDimitry Andricnth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) 53330b57cec5SDimitry Andric{ 53340b57cec5SDimitry Andric _VSTD::nth_element(__first, __nth, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 53350b57cec5SDimitry Andric} 53360b57cec5SDimitry Andric 53370b57cec5SDimitry Andric// includes 53380b57cec5SDimitry Andric 53390b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2> 53400b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 53410b57cec5SDimitry Andric__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, 53420b57cec5SDimitry Andric _Compare __comp) 53430b57cec5SDimitry Andric{ 53440b57cec5SDimitry Andric for (; __first2 != __last2; ++__first1) 53450b57cec5SDimitry Andric { 53460b57cec5SDimitry Andric if (__first1 == __last1 || __comp(*__first2, *__first1)) 53470b57cec5SDimitry Andric return false; 53480b57cec5SDimitry Andric if (!__comp(*__first1, *__first2)) 53490b57cec5SDimitry Andric ++__first2; 53500b57cec5SDimitry Andric } 53510b57cec5SDimitry Andric return true; 53520b57cec5SDimitry Andric} 53530b57cec5SDimitry Andric 53540b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _Compare> 53550b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 53560b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 53570b57cec5SDimitry Andricbool 53580b57cec5SDimitry Andricincludes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, 53590b57cec5SDimitry Andric _Compare __comp) 53600b57cec5SDimitry Andric{ 53610b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 53620b57cec5SDimitry Andric return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); 53630b57cec5SDimitry Andric} 53640b57cec5SDimitry Andric 53650b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 53660b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 53670b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 53680b57cec5SDimitry Andricbool 53690b57cec5SDimitry Andricincludes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) 53700b57cec5SDimitry Andric{ 53710b57cec5SDimitry Andric return _VSTD::includes(__first1, __last1, __first2, __last2, 53720b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 53730b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 53740b57cec5SDimitry Andric} 53750b57cec5SDimitry Andric 53760b57cec5SDimitry Andric// set_union 53770b57cec5SDimitry Andric 53780b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 53790b57cec5SDimitry Andric_OutputIterator 53800b57cec5SDimitry Andric__set_union(_InputIterator1 __first1, _InputIterator1 __last1, 53810b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 53820b57cec5SDimitry Andric{ 53830b57cec5SDimitry Andric for (; __first1 != __last1; ++__result) 53840b57cec5SDimitry Andric { 53850b57cec5SDimitry Andric if (__first2 == __last2) 53860b57cec5SDimitry Andric return _VSTD::copy(__first1, __last1, __result); 53870b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 53880b57cec5SDimitry Andric { 53890b57cec5SDimitry Andric *__result = *__first2; 53900b57cec5SDimitry Andric ++__first2; 53910b57cec5SDimitry Andric } 53920b57cec5SDimitry Andric else 53930b57cec5SDimitry Andric { 53940b57cec5SDimitry Andric if (!__comp(*__first1, *__first2)) 53950b57cec5SDimitry Andric ++__first2; 53960b57cec5SDimitry Andric *__result = *__first1; 53970b57cec5SDimitry Andric ++__first1; 53980b57cec5SDimitry Andric } 53990b57cec5SDimitry Andric } 54000b57cec5SDimitry Andric return _VSTD::copy(__first2, __last2, __result); 54010b57cec5SDimitry Andric} 54020b57cec5SDimitry Andric 54030b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 54040b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 54050b57cec5SDimitry Andric_OutputIterator 54060b57cec5SDimitry Andricset_union(_InputIterator1 __first1, _InputIterator1 __last1, 54070b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 54080b57cec5SDimitry Andric{ 54090b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 54100b57cec5SDimitry Andric return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 54110b57cec5SDimitry Andric} 54120b57cec5SDimitry Andric 54130b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 54140b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 54150b57cec5SDimitry Andric_OutputIterator 54160b57cec5SDimitry Andricset_union(_InputIterator1 __first1, _InputIterator1 __last1, 54170b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 54180b57cec5SDimitry Andric{ 54190b57cec5SDimitry Andric return _VSTD::set_union(__first1, __last1, __first2, __last2, __result, 54200b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 54210b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 54220b57cec5SDimitry Andric} 54230b57cec5SDimitry Andric 54240b57cec5SDimitry Andric// set_intersection 54250b57cec5SDimitry Andric 54260b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 54270b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 54280b57cec5SDimitry Andric__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 54290b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 54300b57cec5SDimitry Andric{ 54310b57cec5SDimitry Andric while (__first1 != __last1 && __first2 != __last2) 54320b57cec5SDimitry Andric { 54330b57cec5SDimitry Andric if (__comp(*__first1, *__first2)) 54340b57cec5SDimitry Andric ++__first1; 54350b57cec5SDimitry Andric else 54360b57cec5SDimitry Andric { 54370b57cec5SDimitry Andric if (!__comp(*__first2, *__first1)) 54380b57cec5SDimitry Andric { 54390b57cec5SDimitry Andric *__result = *__first1; 54400b57cec5SDimitry Andric ++__result; 54410b57cec5SDimitry Andric ++__first1; 54420b57cec5SDimitry Andric } 54430b57cec5SDimitry Andric ++__first2; 54440b57cec5SDimitry Andric } 54450b57cec5SDimitry Andric } 54460b57cec5SDimitry Andric return __result; 54470b57cec5SDimitry Andric} 54480b57cec5SDimitry Andric 54490b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 54500b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 54510b57cec5SDimitry Andric_OutputIterator 54520b57cec5SDimitry Andricset_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 54530b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 54540b57cec5SDimitry Andric{ 54550b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 54560b57cec5SDimitry Andric return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 54570b57cec5SDimitry Andric} 54580b57cec5SDimitry Andric 54590b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 54600b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 54610b57cec5SDimitry Andric_OutputIterator 54620b57cec5SDimitry Andricset_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 54630b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 54640b57cec5SDimitry Andric{ 54650b57cec5SDimitry Andric return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result, 54660b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 54670b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 54680b57cec5SDimitry Andric} 54690b57cec5SDimitry Andric 54700b57cec5SDimitry Andric// set_difference 54710b57cec5SDimitry Andric 54720b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 54730b57cec5SDimitry Andric_OutputIterator 54740b57cec5SDimitry Andric__set_difference(_InputIterator1 __first1, _InputIterator1 __last1, 54750b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 54760b57cec5SDimitry Andric{ 54770b57cec5SDimitry Andric while (__first1 != __last1) 54780b57cec5SDimitry Andric { 54790b57cec5SDimitry Andric if (__first2 == __last2) 54800b57cec5SDimitry Andric return _VSTD::copy(__first1, __last1, __result); 54810b57cec5SDimitry Andric if (__comp(*__first1, *__first2)) 54820b57cec5SDimitry Andric { 54830b57cec5SDimitry Andric *__result = *__first1; 54840b57cec5SDimitry Andric ++__result; 54850b57cec5SDimitry Andric ++__first1; 54860b57cec5SDimitry Andric } 54870b57cec5SDimitry Andric else 54880b57cec5SDimitry Andric { 54890b57cec5SDimitry Andric if (!__comp(*__first2, *__first1)) 54900b57cec5SDimitry Andric ++__first1; 54910b57cec5SDimitry Andric ++__first2; 54920b57cec5SDimitry Andric } 54930b57cec5SDimitry Andric } 54940b57cec5SDimitry Andric return __result; 54950b57cec5SDimitry Andric} 54960b57cec5SDimitry Andric 54970b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 54980b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 54990b57cec5SDimitry Andric_OutputIterator 55000b57cec5SDimitry Andricset_difference(_InputIterator1 __first1, _InputIterator1 __last1, 55010b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 55020b57cec5SDimitry Andric{ 55030b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 55040b57cec5SDimitry Andric return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 55050b57cec5SDimitry Andric} 55060b57cec5SDimitry Andric 55070b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 55080b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 55090b57cec5SDimitry Andric_OutputIterator 55100b57cec5SDimitry Andricset_difference(_InputIterator1 __first1, _InputIterator1 __last1, 55110b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 55120b57cec5SDimitry Andric{ 55130b57cec5SDimitry Andric return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result, 55140b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 55150b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 55160b57cec5SDimitry Andric} 55170b57cec5SDimitry Andric 55180b57cec5SDimitry Andric// set_symmetric_difference 55190b57cec5SDimitry Andric 55200b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 55210b57cec5SDimitry Andric_OutputIterator 55220b57cec5SDimitry Andric__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 55230b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 55240b57cec5SDimitry Andric{ 55250b57cec5SDimitry Andric while (__first1 != __last1) 55260b57cec5SDimitry Andric { 55270b57cec5SDimitry Andric if (__first2 == __last2) 55280b57cec5SDimitry Andric return _VSTD::copy(__first1, __last1, __result); 55290b57cec5SDimitry Andric if (__comp(*__first1, *__first2)) 55300b57cec5SDimitry Andric { 55310b57cec5SDimitry Andric *__result = *__first1; 55320b57cec5SDimitry Andric ++__result; 55330b57cec5SDimitry Andric ++__first1; 55340b57cec5SDimitry Andric } 55350b57cec5SDimitry Andric else 55360b57cec5SDimitry Andric { 55370b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 55380b57cec5SDimitry Andric { 55390b57cec5SDimitry Andric *__result = *__first2; 55400b57cec5SDimitry Andric ++__result; 55410b57cec5SDimitry Andric } 55420b57cec5SDimitry Andric else 55430b57cec5SDimitry Andric ++__first1; 55440b57cec5SDimitry Andric ++__first2; 55450b57cec5SDimitry Andric } 55460b57cec5SDimitry Andric } 55470b57cec5SDimitry Andric return _VSTD::copy(__first2, __last2, __result); 55480b57cec5SDimitry Andric} 55490b57cec5SDimitry Andric 55500b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 55510b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 55520b57cec5SDimitry Andric_OutputIterator 55530b57cec5SDimitry Andricset_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 55540b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 55550b57cec5SDimitry Andric{ 55560b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 55570b57cec5SDimitry Andric return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 55580b57cec5SDimitry Andric} 55590b57cec5SDimitry Andric 55600b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 55610b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 55620b57cec5SDimitry Andric_OutputIterator 55630b57cec5SDimitry Andricset_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 55640b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 55650b57cec5SDimitry Andric{ 55660b57cec5SDimitry Andric return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, 55670b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 55680b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 55690b57cec5SDimitry Andric} 55700b57cec5SDimitry Andric 55710b57cec5SDimitry Andric// lexicographical_compare 55720b57cec5SDimitry Andric 55730b57cec5SDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2> 55740b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 55750b57cec5SDimitry Andric__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, 55760b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) 55770b57cec5SDimitry Andric{ 55780b57cec5SDimitry Andric for (; __first2 != __last2; ++__first1, (void) ++__first2) 55790b57cec5SDimitry Andric { 55800b57cec5SDimitry Andric if (__first1 == __last1 || __comp(*__first1, *__first2)) 55810b57cec5SDimitry Andric return true; 55820b57cec5SDimitry Andric if (__comp(*__first2, *__first1)) 55830b57cec5SDimitry Andric return false; 55840b57cec5SDimitry Andric } 55850b57cec5SDimitry Andric return false; 55860b57cec5SDimitry Andric} 55870b57cec5SDimitry Andric 55880b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _Compare> 55890b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 55900b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 55910b57cec5SDimitry Andricbool 55920b57cec5SDimitry Andriclexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, 55930b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) 55940b57cec5SDimitry Andric{ 55950b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 55960b57cec5SDimitry Andric return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); 55970b57cec5SDimitry Andric} 55980b57cec5SDimitry Andric 55990b57cec5SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2> 56000b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT inline 56010b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 56020b57cec5SDimitry Andricbool 56030b57cec5SDimitry Andriclexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, 56040b57cec5SDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2) 56050b57cec5SDimitry Andric{ 56060b57cec5SDimitry Andric return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, 56070b57cec5SDimitry Andric __less<typename iterator_traits<_InputIterator1>::value_type, 56080b57cec5SDimitry Andric typename iterator_traits<_InputIterator2>::value_type>()); 56090b57cec5SDimitry Andric} 56100b57cec5SDimitry Andric 56110b57cec5SDimitry Andric// next_permutation 56120b57cec5SDimitry Andric 56130b57cec5SDimitry Andrictemplate <class _Compare, class _BidirectionalIterator> 56140b57cec5SDimitry Andricbool 56150b57cec5SDimitry Andric__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 56160b57cec5SDimitry Andric{ 56170b57cec5SDimitry Andric _BidirectionalIterator __i = __last; 56180b57cec5SDimitry Andric if (__first == __last || __first == --__i) 56190b57cec5SDimitry Andric return false; 56200b57cec5SDimitry Andric while (true) 56210b57cec5SDimitry Andric { 56220b57cec5SDimitry Andric _BidirectionalIterator __ip1 = __i; 56230b57cec5SDimitry Andric if (__comp(*--__i, *__ip1)) 56240b57cec5SDimitry Andric { 56250b57cec5SDimitry Andric _BidirectionalIterator __j = __last; 56260b57cec5SDimitry Andric while (!__comp(*__i, *--__j)) 56270b57cec5SDimitry Andric ; 56280b57cec5SDimitry Andric swap(*__i, *__j); 56290b57cec5SDimitry Andric _VSTD::reverse(__ip1, __last); 56300b57cec5SDimitry Andric return true; 56310b57cec5SDimitry Andric } 56320b57cec5SDimitry Andric if (__i == __first) 56330b57cec5SDimitry Andric { 56340b57cec5SDimitry Andric _VSTD::reverse(__first, __last); 56350b57cec5SDimitry Andric return false; 56360b57cec5SDimitry Andric } 56370b57cec5SDimitry Andric } 56380b57cec5SDimitry Andric} 56390b57cec5SDimitry Andric 56400b57cec5SDimitry Andrictemplate <class _BidirectionalIterator, class _Compare> 56410b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 56420b57cec5SDimitry Andricbool 56430b57cec5SDimitry Andricnext_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 56440b57cec5SDimitry Andric{ 56450b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 56460b57cec5SDimitry Andric return __next_permutation<_Comp_ref>(__first, __last, __comp); 56470b57cec5SDimitry Andric} 56480b57cec5SDimitry Andric 56490b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 56500b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 56510b57cec5SDimitry Andricbool 56520b57cec5SDimitry Andricnext_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) 56530b57cec5SDimitry Andric{ 56540b57cec5SDimitry Andric return _VSTD::next_permutation(__first, __last, 56550b57cec5SDimitry Andric __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); 56560b57cec5SDimitry Andric} 56570b57cec5SDimitry Andric 56580b57cec5SDimitry Andric// prev_permutation 56590b57cec5SDimitry Andric 56600b57cec5SDimitry Andrictemplate <class _Compare, class _BidirectionalIterator> 56610b57cec5SDimitry Andricbool 56620b57cec5SDimitry Andric__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 56630b57cec5SDimitry Andric{ 56640b57cec5SDimitry Andric _BidirectionalIterator __i = __last; 56650b57cec5SDimitry Andric if (__first == __last || __first == --__i) 56660b57cec5SDimitry Andric return false; 56670b57cec5SDimitry Andric while (true) 56680b57cec5SDimitry Andric { 56690b57cec5SDimitry Andric _BidirectionalIterator __ip1 = __i; 56700b57cec5SDimitry Andric if (__comp(*__ip1, *--__i)) 56710b57cec5SDimitry Andric { 56720b57cec5SDimitry Andric _BidirectionalIterator __j = __last; 56730b57cec5SDimitry Andric while (!__comp(*--__j, *__i)) 56740b57cec5SDimitry Andric ; 56750b57cec5SDimitry Andric swap(*__i, *__j); 56760b57cec5SDimitry Andric _VSTD::reverse(__ip1, __last); 56770b57cec5SDimitry Andric return true; 56780b57cec5SDimitry Andric } 56790b57cec5SDimitry Andric if (__i == __first) 56800b57cec5SDimitry Andric { 56810b57cec5SDimitry Andric _VSTD::reverse(__first, __last); 56820b57cec5SDimitry Andric return false; 56830b57cec5SDimitry Andric } 56840b57cec5SDimitry Andric } 56850b57cec5SDimitry Andric} 56860b57cec5SDimitry Andric 56870b57cec5SDimitry Andrictemplate <class _BidirectionalIterator, class _Compare> 56880b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 56890b57cec5SDimitry Andricbool 56900b57cec5SDimitry Andricprev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 56910b57cec5SDimitry Andric{ 56920b57cec5SDimitry Andric typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 56930b57cec5SDimitry Andric return __prev_permutation<_Comp_ref>(__first, __last, __comp); 56940b57cec5SDimitry Andric} 56950b57cec5SDimitry Andric 56960b57cec5SDimitry Andrictemplate <class _BidirectionalIterator> 56970b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 56980b57cec5SDimitry Andricbool 56990b57cec5SDimitry Andricprev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) 57000b57cec5SDimitry Andric{ 57010b57cec5SDimitry Andric return _VSTD::prev_permutation(__first, __last, 57020b57cec5SDimitry Andric __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); 57030b57cec5SDimitry Andric} 57040b57cec5SDimitry Andric 57050b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 57060b57cec5SDimitry Andric 57070b57cec5SDimitry Andric_LIBCPP_POP_MACROS 57080b57cec5SDimitry Andric 5709e40139ffSDimitry Andric#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 5710e40139ffSDimitry Andric# include <__pstl_algorithm> 5711e40139ffSDimitry Andric#endif 5712e40139ffSDimitry Andric 57130b57cec5SDimitry Andric#endif // _LIBCPP_ALGORITHM 5714