17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===-------------------------- algorithm ---------------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP_ALGORITHM 127a984708SDavid Chisnall#define _LIBCPP_ALGORITHM 137a984708SDavid Chisnall 147a984708SDavid Chisnall/* 157a984708SDavid Chisnall algorithm synopsis 167a984708SDavid Chisnall 177a984708SDavid Chisnall#include <initializer_list> 187a984708SDavid Chisnall 197a984708SDavid Chisnallnamespace std 207a984708SDavid Chisnall{ 217a984708SDavid Chisnall 227a984708SDavid Chisnalltemplate <class InputIterator, class Predicate> 234ba319b5SDimitry Andric constexpr bool // constexpr in C++20 247a984708SDavid Chisnall all_of(InputIterator first, InputIterator last, Predicate pred); 257a984708SDavid Chisnall 267a984708SDavid Chisnalltemplate <class InputIterator, class Predicate> 274ba319b5SDimitry Andric constexpr bool // constexpr in C++20 287a984708SDavid Chisnall any_of(InputIterator first, InputIterator last, Predicate pred); 297a984708SDavid Chisnall 307a984708SDavid Chisnalltemplate <class InputIterator, class Predicate> 314ba319b5SDimitry Andric constexpr bool // constexpr in C++20 327a984708SDavid Chisnall none_of(InputIterator first, InputIterator last, Predicate pred); 337a984708SDavid Chisnall 347a984708SDavid Chisnalltemplate <class InputIterator, class Function> 354ba319b5SDimitry Andric constexpr Function // constexpr in C++20 367a984708SDavid Chisnall for_each(InputIterator first, InputIterator last, Function f); 377a984708SDavid Chisnall 38302affcbSDimitry Andrictemplate<class InputIterator, class Size, class Function> 394ba319b5SDimitry Andric constexpr InputIterator // constexpr in C++20 404ba319b5SDimitry Andric for_each_n(InputIterator first, Size n, Function f); // C++17 41302affcbSDimitry Andric 427a984708SDavid Chisnalltemplate <class InputIterator, class T> 434ba319b5SDimitry Andric constexpr InputIterator // constexpr in C++20 447a984708SDavid Chisnall find(InputIterator first, InputIterator last, const T& value); 457a984708SDavid Chisnall 467a984708SDavid Chisnalltemplate <class InputIterator, class Predicate> 474ba319b5SDimitry Andric constexpr InputIterator // constexpr in C++20 487a984708SDavid Chisnall find_if(InputIterator first, InputIterator last, Predicate pred); 497a984708SDavid Chisnall 507a984708SDavid Chisnalltemplate<class InputIterator, class Predicate> 514ba319b5SDimitry Andric InputIterator // constexpr in C++20 527a984708SDavid Chisnall find_if_not(InputIterator first, InputIterator last, Predicate pred); 537a984708SDavid Chisnall 547a984708SDavid Chisnalltemplate <class ForwardIterator1, class ForwardIterator2> 554ba319b5SDimitry Andric ForwardIterator1 // constexpr in C++20 567a984708SDavid Chisnall find_end(ForwardIterator1 first1, ForwardIterator1 last1, 577a984708SDavid Chisnall ForwardIterator2 first2, ForwardIterator2 last2); 587a984708SDavid Chisnall 597a984708SDavid Chisnalltemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 604ba319b5SDimitry Andric ForwardIterator1 // constexpr in C++20 617a984708SDavid Chisnall find_end(ForwardIterator1 first1, ForwardIterator1 last1, 627a984708SDavid Chisnall ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); 637a984708SDavid Chisnall 647a984708SDavid Chisnalltemplate <class ForwardIterator1, class ForwardIterator2> 654ba319b5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 667a984708SDavid Chisnall find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, 677a984708SDavid Chisnall ForwardIterator2 first2, ForwardIterator2 last2); 687a984708SDavid Chisnall 697a984708SDavid Chisnalltemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 704ba319b5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 717a984708SDavid Chisnall find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, 727a984708SDavid Chisnall ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); 737a984708SDavid Chisnall 747a984708SDavid Chisnalltemplate <class ForwardIterator> 754ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 767a984708SDavid Chisnall adjacent_find(ForwardIterator first, ForwardIterator last); 777a984708SDavid Chisnall 787a984708SDavid Chisnalltemplate <class ForwardIterator, class BinaryPredicate> 794ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 807a984708SDavid Chisnall adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); 817a984708SDavid Chisnall 827a984708SDavid Chisnalltemplate <class InputIterator, class T> 834ba319b5SDimitry Andric constexpr typename iterator_traits<InputIterator>::difference_type // constexpr in C++20 847a984708SDavid Chisnall count(InputIterator first, InputIterator last, const T& value); 857a984708SDavid Chisnall 867a984708SDavid Chisnalltemplate <class InputIterator, class Predicate> 874ba319b5SDimitry Andric constexpr typename iterator_traits<InputIterator>::difference_type // constexpr in C++20 887a984708SDavid Chisnall count_if(InputIterator first, InputIterator last, Predicate pred); 897a984708SDavid Chisnall 907a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2> 914ba319b5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 927a984708SDavid Chisnall mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); 937a984708SDavid Chisnall 944bab9fd9SDavid Chisnalltemplate <class InputIterator1, class InputIterator2> 954ba319b5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 964bab9fd9SDavid Chisnall mismatch(InputIterator1 first1, InputIterator1 last1, 974bab9fd9SDavid Chisnall InputIterator2 first2, InputIterator2 last2); // **C++14** 984bab9fd9SDavid Chisnall 997a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 1004ba319b5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 1017a984708SDavid Chisnall mismatch(InputIterator1 first1, InputIterator1 last1, 1027a984708SDavid Chisnall InputIterator2 first2, BinaryPredicate pred); 1037a984708SDavid Chisnall 1044bab9fd9SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 1054ba319b5SDimitry Andric constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 1064bab9fd9SDavid Chisnall mismatch(InputIterator1 first1, InputIterator1 last1, 1074bab9fd9SDavid Chisnall InputIterator2 first2, InputIterator2 last2, 1084bab9fd9SDavid Chisnall BinaryPredicate pred); // **C++14** 1094bab9fd9SDavid Chisnall 1107a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2> 1114ba319b5SDimitry Andric constexpr bool // constexpr in C++20 1127a984708SDavid Chisnall equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); 1137a984708SDavid Chisnall 1144bab9fd9SDavid Chisnalltemplate <class InputIterator1, class InputIterator2> 1154ba319b5SDimitry Andric constexpr bool // constexpr in C++20 1164bab9fd9SDavid Chisnall equal(InputIterator1 first1, InputIterator1 last1, 1174bab9fd9SDavid Chisnall InputIterator2 first2, InputIterator2 last2); // **C++14** 1184bab9fd9SDavid Chisnall 1197a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 1204ba319b5SDimitry Andric constexpr bool // constexpr in C++20 1217a984708SDavid Chisnall equal(InputIterator1 first1, InputIterator1 last1, 1227a984708SDavid Chisnall InputIterator2 first2, BinaryPredicate pred); 1237a984708SDavid Chisnall 1244bab9fd9SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class BinaryPredicate> 1254ba319b5SDimitry Andric constexpr bool // constexpr in C++20 1264bab9fd9SDavid Chisnall equal(InputIterator1 first1, InputIterator1 last1, 1274bab9fd9SDavid Chisnall InputIterator2 first2, InputIterator2 last2, 1284bab9fd9SDavid Chisnall BinaryPredicate pred); // **C++14** 1294bab9fd9SDavid Chisnall 1307a984708SDavid Chisnalltemplate<class ForwardIterator1, class ForwardIterator2> 1314ba319b5SDimitry Andric constexpr bool // constexpr in C++20 1327a984708SDavid Chisnall is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 1337a984708SDavid Chisnall ForwardIterator2 first2); 1347a984708SDavid Chisnall 1354bab9fd9SDavid Chisnalltemplate<class ForwardIterator1, class ForwardIterator2> 1364ba319b5SDimitry Andric constexpr bool // constexpr in C++20 1374bab9fd9SDavid Chisnall is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 1384bab9fd9SDavid Chisnall ForwardIterator2 first2, ForwardIterator2 last2); // **C++14** 1394bab9fd9SDavid Chisnall 1407a984708SDavid Chisnalltemplate<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 1414ba319b5SDimitry Andric constexpr bool // constexpr in C++20 1427a984708SDavid Chisnall is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 1437a984708SDavid Chisnall ForwardIterator2 first2, BinaryPredicate pred); 1447a984708SDavid Chisnall 1454bab9fd9SDavid Chisnalltemplate<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 1464ba319b5SDimitry Andric constexpr bool // constexpr in C++20 1474bab9fd9SDavid Chisnall is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, 1484bab9fd9SDavid Chisnall ForwardIterator2 first2, ForwardIterator2 last2, 1494bab9fd9SDavid Chisnall BinaryPredicate pred); // **C++14** 1504bab9fd9SDavid Chisnall 1517a984708SDavid Chisnalltemplate <class ForwardIterator1, class ForwardIterator2> 1524ba319b5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 1537a984708SDavid Chisnall search(ForwardIterator1 first1, ForwardIterator1 last1, 1547a984708SDavid Chisnall ForwardIterator2 first2, ForwardIterator2 last2); 1557a984708SDavid Chisnall 1567a984708SDavid Chisnalltemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 1574ba319b5SDimitry Andric constexpr ForwardIterator1 // constexpr in C++20 1587a984708SDavid Chisnall search(ForwardIterator1 first1, ForwardIterator1 last1, 1597a984708SDavid Chisnall ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); 1607a984708SDavid Chisnall 1617a984708SDavid Chisnalltemplate <class ForwardIterator, class Size, class T> 1624ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 1637a984708SDavid Chisnall search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value); 1647a984708SDavid Chisnall 1657a984708SDavid Chisnalltemplate <class ForwardIterator, class Size, class T, class BinaryPredicate> 1664ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 1677a984708SDavid Chisnall search_n(ForwardIterator first, ForwardIterator last, 1687a984708SDavid Chisnall Size count, const T& value, BinaryPredicate pred); 1697a984708SDavid Chisnall 1707a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator> 1717a984708SDavid Chisnall OutputIterator 1727a984708SDavid Chisnall copy(InputIterator first, InputIterator last, OutputIterator result); 1737a984708SDavid Chisnall 1747a984708SDavid Chisnalltemplate<class InputIterator, class OutputIterator, class Predicate> 1757a984708SDavid Chisnall OutputIterator 1767a984708SDavid Chisnall copy_if(InputIterator first, InputIterator last, 1777a984708SDavid Chisnall OutputIterator result, Predicate pred); 1787a984708SDavid Chisnall 1797a984708SDavid Chisnalltemplate<class InputIterator, class Size, class OutputIterator> 1807a984708SDavid Chisnall OutputIterator 1817a984708SDavid Chisnall copy_n(InputIterator first, Size n, OutputIterator result); 1827a984708SDavid Chisnall 1837a984708SDavid Chisnalltemplate <class BidirectionalIterator1, class BidirectionalIterator2> 1847a984708SDavid Chisnall BidirectionalIterator2 1857a984708SDavid Chisnall copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, 1867a984708SDavid Chisnall BidirectionalIterator2 result); 1877a984708SDavid Chisnall 1887a984708SDavid Chisnalltemplate <class ForwardIterator1, class ForwardIterator2> 1897a984708SDavid Chisnall ForwardIterator2 1907a984708SDavid Chisnall swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); 1917a984708SDavid Chisnall 1927a984708SDavid Chisnalltemplate <class ForwardIterator1, class ForwardIterator2> 1937a984708SDavid Chisnall void 1947a984708SDavid Chisnall iter_swap(ForwardIterator1 a, ForwardIterator2 b); 1957a984708SDavid Chisnall 1967a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator, class UnaryOperation> 1974ba319b5SDimitry Andric constexpr OutputIterator // constexpr in C++20 1987a984708SDavid Chisnall transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op); 1997a984708SDavid Chisnall 2007a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation> 2014ba319b5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2027a984708SDavid Chisnall transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, 2037a984708SDavid Chisnall OutputIterator result, BinaryOperation binary_op); 2047a984708SDavid Chisnall 2057a984708SDavid Chisnalltemplate <class ForwardIterator, class T> 2064ba319b5SDimitry Andric constexpr void // constexpr in C++20 2077a984708SDavid Chisnall replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); 2087a984708SDavid Chisnall 2097a984708SDavid Chisnalltemplate <class ForwardIterator, class Predicate, class T> 2104ba319b5SDimitry Andric constexpr void // constexpr in C++20 2117a984708SDavid Chisnall replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value); 2127a984708SDavid Chisnall 2137a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator, class T> 2144ba319b5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2157a984708SDavid Chisnall replace_copy(InputIterator first, InputIterator last, OutputIterator result, 2167a984708SDavid Chisnall const T& old_value, const T& new_value); 2177a984708SDavid Chisnall 2187a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator, class Predicate, class T> 2194ba319b5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2207a984708SDavid Chisnall replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value); 2217a984708SDavid Chisnall 2227a984708SDavid Chisnalltemplate <class ForwardIterator, class T> 2234ba319b5SDimitry Andric constexpr void // constexpr in C++20 2247a984708SDavid Chisnall fill(ForwardIterator first, ForwardIterator last, const T& value); 2257a984708SDavid Chisnall 2267a984708SDavid Chisnalltemplate <class OutputIterator, class Size, class T> 2274ba319b5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2287a984708SDavid Chisnall fill_n(OutputIterator first, Size n, const T& value); 2297a984708SDavid Chisnall 2307a984708SDavid Chisnalltemplate <class ForwardIterator, class Generator> 2314ba319b5SDimitry Andric constexpr void // constexpr in C++20 2327a984708SDavid Chisnall generate(ForwardIterator first, ForwardIterator last, Generator gen); 2337a984708SDavid Chisnall 2347a984708SDavid Chisnalltemplate <class OutputIterator, class Size, class Generator> 2354ba319b5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2367a984708SDavid Chisnall generate_n(OutputIterator first, Size n, Generator gen); 2377a984708SDavid Chisnall 2387a984708SDavid Chisnalltemplate <class ForwardIterator, class T> 2394ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 2407a984708SDavid Chisnall remove(ForwardIterator first, ForwardIterator last, const T& value); 2417a984708SDavid Chisnall 2427a984708SDavid Chisnalltemplate <class ForwardIterator, class Predicate> 2434ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 2447a984708SDavid Chisnall remove_if(ForwardIterator first, ForwardIterator last, Predicate pred); 2457a984708SDavid Chisnall 2467a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator, class T> 2474ba319b5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2487a984708SDavid Chisnall remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value); 2497a984708SDavid Chisnall 2507a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator, class Predicate> 2514ba319b5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2527a984708SDavid Chisnall remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); 2537a984708SDavid Chisnall 2547a984708SDavid Chisnalltemplate <class ForwardIterator> 2557a984708SDavid Chisnall ForwardIterator 2567a984708SDavid Chisnall unique(ForwardIterator first, ForwardIterator last); 2577a984708SDavid Chisnall 2587a984708SDavid Chisnalltemplate <class ForwardIterator, class BinaryPredicate> 2597a984708SDavid Chisnall ForwardIterator 2607a984708SDavid Chisnall unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); 2617a984708SDavid Chisnall 2627a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator> 2637a984708SDavid Chisnall OutputIterator 2647a984708SDavid Chisnall unique_copy(InputIterator first, InputIterator last, OutputIterator result); 2657a984708SDavid Chisnall 2667a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator, class BinaryPredicate> 2677a984708SDavid Chisnall OutputIterator 2687a984708SDavid Chisnall unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); 2697a984708SDavid Chisnall 2707a984708SDavid Chisnalltemplate <class BidirectionalIterator> 2717a984708SDavid Chisnall void 2727a984708SDavid Chisnall reverse(BidirectionalIterator first, BidirectionalIterator last); 2737a984708SDavid Chisnall 2747a984708SDavid Chisnalltemplate <class BidirectionalIterator, class OutputIterator> 2754ba319b5SDimitry Andric constexpr OutputIterator // constexpr in C++20 2767a984708SDavid Chisnall reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result); 2777a984708SDavid Chisnall 2787a984708SDavid Chisnalltemplate <class ForwardIterator> 2797a984708SDavid Chisnall ForwardIterator 2807a984708SDavid Chisnall rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last); 2817a984708SDavid Chisnall 2827a984708SDavid Chisnalltemplate <class ForwardIterator, class OutputIterator> 2837a984708SDavid Chisnall OutputIterator 2847a984708SDavid Chisnall rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result); 2857a984708SDavid Chisnall 2867a984708SDavid Chisnalltemplate <class RandomAccessIterator> 2877a984708SDavid Chisnall void 288540d2a8bSDimitry Andric random_shuffle(RandomAccessIterator first, RandomAccessIterator last); // deprecated in C++14, removed in C++17 2897a984708SDavid Chisnall 2907a984708SDavid Chisnalltemplate <class RandomAccessIterator, class RandomNumberGenerator> 2917a984708SDavid Chisnall void 292d72607e9SDimitry Andric random_shuffle(RandomAccessIterator first, RandomAccessIterator last, 293540d2a8bSDimitry Andric RandomNumberGenerator& rand); // deprecated in C++14, removed in C++17 2947a984708SDavid Chisnall 295aed8d94eSDimitry Andrictemplate<class PopulationIterator, class SampleIterator, 296aed8d94eSDimitry Andric class Distance, class UniformRandomBitGenerator> 297aed8d94eSDimitry Andric SampleIterator sample(PopulationIterator first, PopulationIterator last, 298aed8d94eSDimitry Andric SampleIterator out, Distance n, 299aed8d94eSDimitry Andric UniformRandomBitGenerator&& g); // C++17 300aed8d94eSDimitry Andric 3017a984708SDavid Chisnalltemplate<class RandomAccessIterator, class UniformRandomNumberGenerator> 3027a984708SDavid Chisnall void shuffle(RandomAccessIterator first, RandomAccessIterator last, 3037a984708SDavid Chisnall UniformRandomNumberGenerator&& g); 3047a984708SDavid Chisnall 3057a984708SDavid Chisnalltemplate <class InputIterator, class Predicate> 3064ba319b5SDimitry Andric constexpr bool // constexpr in C++20 3077a984708SDavid Chisnall is_partitioned(InputIterator first, InputIterator last, Predicate pred); 3087a984708SDavid Chisnall 3097a984708SDavid Chisnalltemplate <class ForwardIterator, class Predicate> 3107a984708SDavid Chisnall ForwardIterator 3117a984708SDavid Chisnall partition(ForwardIterator first, ForwardIterator last, Predicate pred); 3127a984708SDavid Chisnall 3137a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator1, 3147a984708SDavid Chisnall class OutputIterator2, class Predicate> 3154ba319b5SDimitry Andric constexpr pair<OutputIterator1, OutputIterator2> // constexpr in C++20 3167a984708SDavid Chisnall partition_copy(InputIterator first, InputIterator last, 3177a984708SDavid Chisnall OutputIterator1 out_true, OutputIterator2 out_false, 3187a984708SDavid Chisnall Predicate pred); 3197a984708SDavid Chisnall 3207a984708SDavid Chisnalltemplate <class ForwardIterator, class Predicate> 3217a984708SDavid Chisnall ForwardIterator 3227a984708SDavid Chisnall stable_partition(ForwardIterator first, ForwardIterator last, Predicate pred); 3237a984708SDavid Chisnall 3247a984708SDavid Chisnalltemplate<class ForwardIterator, class Predicate> 3254ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3267a984708SDavid Chisnall partition_point(ForwardIterator first, ForwardIterator last, Predicate pred); 3277a984708SDavid Chisnall 3287a984708SDavid Chisnalltemplate <class ForwardIterator> 3294ba319b5SDimitry Andric constexpr bool // constexpr in C++20 3307a984708SDavid Chisnall is_sorted(ForwardIterator first, ForwardIterator last); 3317a984708SDavid Chisnall 3327a984708SDavid Chisnalltemplate <class ForwardIterator, class Compare> 3337a984708SDavid Chisnall bool 3347a984708SDavid Chisnall is_sorted(ForwardIterator first, ForwardIterator last, Compare comp); 3357a984708SDavid Chisnall 3367a984708SDavid Chisnalltemplate<class ForwardIterator> 3374ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3387a984708SDavid Chisnall is_sorted_until(ForwardIterator first, ForwardIterator last); 3397a984708SDavid Chisnall 3407a984708SDavid Chisnalltemplate <class ForwardIterator, class Compare> 3414ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3427a984708SDavid Chisnall is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp); 3437a984708SDavid Chisnall 3447a984708SDavid Chisnalltemplate <class RandomAccessIterator> 3457a984708SDavid Chisnall void 3467a984708SDavid Chisnall sort(RandomAccessIterator first, RandomAccessIterator last); 3477a984708SDavid Chisnall 3487a984708SDavid Chisnalltemplate <class RandomAccessIterator, class Compare> 3497a984708SDavid Chisnall void 3507a984708SDavid Chisnall sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 3517a984708SDavid Chisnall 3527a984708SDavid Chisnalltemplate <class RandomAccessIterator> 3537a984708SDavid Chisnall void 3547a984708SDavid Chisnall stable_sort(RandomAccessIterator first, RandomAccessIterator last); 3557a984708SDavid Chisnall 3567a984708SDavid Chisnalltemplate <class RandomAccessIterator, class Compare> 3577a984708SDavid Chisnall void 3587a984708SDavid Chisnall stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 3597a984708SDavid Chisnall 3607a984708SDavid Chisnalltemplate <class RandomAccessIterator> 3617a984708SDavid Chisnall void 3627a984708SDavid Chisnall partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); 3637a984708SDavid Chisnall 3647a984708SDavid Chisnalltemplate <class RandomAccessIterator, class Compare> 3657a984708SDavid Chisnall void 3667a984708SDavid Chisnall partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); 3677a984708SDavid Chisnall 3687a984708SDavid Chisnalltemplate <class InputIterator, class RandomAccessIterator> 3697a984708SDavid Chisnall RandomAccessIterator 3707a984708SDavid Chisnall partial_sort_copy(InputIterator first, InputIterator last, 3717a984708SDavid Chisnall RandomAccessIterator result_first, RandomAccessIterator result_last); 3727a984708SDavid Chisnall 3737a984708SDavid Chisnalltemplate <class InputIterator, class RandomAccessIterator, class Compare> 3747a984708SDavid Chisnall RandomAccessIterator 3757a984708SDavid Chisnall partial_sort_copy(InputIterator first, InputIterator last, 3767a984708SDavid Chisnall RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp); 3777a984708SDavid Chisnall 3787a984708SDavid Chisnalltemplate <class RandomAccessIterator> 3797a984708SDavid Chisnall void 3807a984708SDavid Chisnall nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); 3817a984708SDavid Chisnall 3827a984708SDavid Chisnalltemplate <class RandomAccessIterator, class Compare> 3837a984708SDavid Chisnall void 3847a984708SDavid Chisnall nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); 3857a984708SDavid Chisnall 3867a984708SDavid Chisnalltemplate <class ForwardIterator, class T> 3874ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3887a984708SDavid Chisnall lower_bound(ForwardIterator first, ForwardIterator last, const T& value); 3897a984708SDavid Chisnall 3907a984708SDavid Chisnalltemplate <class ForwardIterator, class T, class Compare> 3914ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3927a984708SDavid Chisnall lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 3937a984708SDavid Chisnall 3947a984708SDavid Chisnalltemplate <class ForwardIterator, class T> 3954ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 3967a984708SDavid Chisnall upper_bound(ForwardIterator first, ForwardIterator last, const T& value); 3977a984708SDavid Chisnall 3987a984708SDavid Chisnalltemplate <class ForwardIterator, class T, class Compare> 3994ba319b5SDimitry Andric constexpr ForwardIterator // constexpr in C++20 4007a984708SDavid Chisnall upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 4017a984708SDavid Chisnall 4027a984708SDavid Chisnalltemplate <class ForwardIterator, class T> 4034ba319b5SDimitry Andric constexpr pair<ForwardIterator, ForwardIterator> // constexpr in C++20 4047a984708SDavid Chisnall equal_range(ForwardIterator first, ForwardIterator last, const T& value); 4057a984708SDavid Chisnall 4067a984708SDavid Chisnalltemplate <class ForwardIterator, class T, class Compare> 4074ba319b5SDimitry Andric constexpr pair<ForwardIterator, ForwardIterator> // constexpr in C++20 4087a984708SDavid Chisnall equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 4097a984708SDavid Chisnall 4107a984708SDavid Chisnalltemplate <class ForwardIterator, class T> 4114ba319b5SDimitry Andric constexpr bool // constexpr in C++20 4127a984708SDavid Chisnall binary_search(ForwardIterator first, ForwardIterator last, const T& value); 4137a984708SDavid Chisnall 4147a984708SDavid Chisnalltemplate <class ForwardIterator, class T, class Compare> 4154ba319b5SDimitry Andric constexpr bool // constexpr in C++20 4167a984708SDavid Chisnall binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); 4177a984708SDavid Chisnall 4187a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class OutputIterator> 4197a984708SDavid Chisnall OutputIterator 4207a984708SDavid Chisnall merge(InputIterator1 first1, InputIterator1 last1, 4217a984708SDavid Chisnall InputIterator2 first2, InputIterator2 last2, OutputIterator result); 4227a984708SDavid Chisnall 4237a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 4247a984708SDavid Chisnall OutputIterator 4257a984708SDavid Chisnall merge(InputIterator1 first1, InputIterator1 last1, 4267a984708SDavid Chisnall InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 4277a984708SDavid Chisnall 4287a984708SDavid Chisnalltemplate <class BidirectionalIterator> 4297a984708SDavid Chisnall void 4307a984708SDavid Chisnall inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); 4317a984708SDavid Chisnall 4327a984708SDavid Chisnalltemplate <class BidirectionalIterator, class Compare> 4337a984708SDavid Chisnall void 4347a984708SDavid Chisnall inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); 4357a984708SDavid Chisnall 4367a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2> 4374ba319b5SDimitry Andric constexpr bool // constexpr in C++20 4387a984708SDavid Chisnall includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); 4397a984708SDavid Chisnall 4407a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class Compare> 4414ba319b5SDimitry Andric constexpr bool // constexpr in C++20 4427a984708SDavid Chisnall includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); 4437a984708SDavid Chisnall 4447a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class OutputIterator> 4457a984708SDavid Chisnall OutputIterator 4467a984708SDavid Chisnall set_union(InputIterator1 first1, InputIterator1 last1, 4477a984708SDavid Chisnall InputIterator2 first2, InputIterator2 last2, OutputIterator result); 4487a984708SDavid Chisnall 4497a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 4507a984708SDavid Chisnall OutputIterator 4517a984708SDavid Chisnall set_union(InputIterator1 first1, InputIterator1 last1, 4527a984708SDavid Chisnall InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 4537a984708SDavid Chisnall 4547a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class OutputIterator> 4554ba319b5SDimitry Andric constexpr OutputIterator // constexpr in C++20 4567a984708SDavid Chisnall set_intersection(InputIterator1 first1, InputIterator1 last1, 4577a984708SDavid Chisnall InputIterator2 first2, InputIterator2 last2, OutputIterator result); 4587a984708SDavid Chisnall 4597a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 4604ba319b5SDimitry Andric constexpr OutputIterator // constexpr in C++20 4617a984708SDavid Chisnall set_intersection(InputIterator1 first1, InputIterator1 last1, 4627a984708SDavid Chisnall InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 4637a984708SDavid Chisnall 4647a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class OutputIterator> 4657a984708SDavid Chisnall OutputIterator 4667a984708SDavid Chisnall set_difference(InputIterator1 first1, InputIterator1 last1, 4677a984708SDavid Chisnall InputIterator2 first2, InputIterator2 last2, OutputIterator result); 4687a984708SDavid Chisnall 4697a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 4707a984708SDavid Chisnall OutputIterator 4717a984708SDavid Chisnall set_difference(InputIterator1 first1, InputIterator1 last1, 4727a984708SDavid Chisnall InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 4737a984708SDavid Chisnall 4747a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class OutputIterator> 4757a984708SDavid Chisnall OutputIterator 4767a984708SDavid Chisnall set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, 4777a984708SDavid Chisnall InputIterator2 first2, InputIterator2 last2, OutputIterator result); 4787a984708SDavid Chisnall 4797a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> 4807a984708SDavid Chisnall OutputIterator 4817a984708SDavid Chisnall set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, 4827a984708SDavid Chisnall InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); 4837a984708SDavid Chisnall 4847a984708SDavid Chisnalltemplate <class RandomAccessIterator> 4857a984708SDavid Chisnall void 4867a984708SDavid Chisnall push_heap(RandomAccessIterator first, RandomAccessIterator last); 4877a984708SDavid Chisnall 4887a984708SDavid Chisnalltemplate <class RandomAccessIterator, class Compare> 4897a984708SDavid Chisnall void 4907a984708SDavid Chisnall push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 4917a984708SDavid Chisnall 4927a984708SDavid Chisnalltemplate <class RandomAccessIterator> 4937a984708SDavid Chisnall void 4947a984708SDavid Chisnall pop_heap(RandomAccessIterator first, RandomAccessIterator last); 4957a984708SDavid Chisnall 4967a984708SDavid Chisnalltemplate <class RandomAccessIterator, class Compare> 4977a984708SDavid Chisnall void 4987a984708SDavid Chisnall pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 4997a984708SDavid Chisnall 5007a984708SDavid Chisnalltemplate <class RandomAccessIterator> 5017a984708SDavid Chisnall void 5027a984708SDavid Chisnall make_heap(RandomAccessIterator first, RandomAccessIterator last); 5037a984708SDavid Chisnall 5047a984708SDavid Chisnalltemplate <class RandomAccessIterator, class Compare> 5057a984708SDavid Chisnall void 5067a984708SDavid Chisnall make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 5077a984708SDavid Chisnall 5087a984708SDavid Chisnalltemplate <class RandomAccessIterator> 5097a984708SDavid Chisnall void 5107a984708SDavid Chisnall sort_heap(RandomAccessIterator first, RandomAccessIterator last); 5117a984708SDavid Chisnall 5127a984708SDavid Chisnalltemplate <class RandomAccessIterator, class Compare> 5137a984708SDavid Chisnall void 5147a984708SDavid Chisnall sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 5157a984708SDavid Chisnall 5167a984708SDavid Chisnalltemplate <class RandomAccessIterator> 5174ba319b5SDimitry Andric constexpr bool // constexpr in C++20 5187a984708SDavid Chisnall is_heap(RandomAccessIterator first, RandomAccessiterator last); 5197a984708SDavid Chisnall 5207a984708SDavid Chisnalltemplate <class RandomAccessIterator, class Compare> 5214ba319b5SDimitry Andric constexpr bool // constexpr in C++20 5227a984708SDavid Chisnall is_heap(RandomAccessIterator first, RandomAccessiterator last, Compare comp); 5237a984708SDavid Chisnall 5247a984708SDavid Chisnalltemplate <class RandomAccessIterator> 5254ba319b5SDimitry Andric constexpr RandomAccessIterator // constexpr in C++20 5267a984708SDavid Chisnall is_heap_until(RandomAccessIterator first, RandomAccessiterator last); 5277a984708SDavid Chisnall 5287a984708SDavid Chisnalltemplate <class RandomAccessIterator, class Compare> 5294ba319b5SDimitry Andric constexpr RandomAccessIterator // constexpr in C++20 5307a984708SDavid Chisnall is_heap_until(RandomAccessIterator first, RandomAccessiterator last, Compare comp); 5317a984708SDavid Chisnall 5327a984708SDavid Chisnalltemplate <class ForwardIterator> 5337a984708SDavid Chisnall ForwardIterator 534854fa44bSDimitry Andric min_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14 5357a984708SDavid Chisnall 5367a984708SDavid Chisnalltemplate <class ForwardIterator, class Compare> 5377a984708SDavid Chisnall ForwardIterator 538854fa44bSDimitry Andric min_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14 5397a984708SDavid Chisnall 5407a984708SDavid Chisnalltemplate <class T> 5417a984708SDavid Chisnall const T& 542d72607e9SDimitry Andric min(const T& a, const T& b); // constexpr in C++14 5437a984708SDavid Chisnall 5447a984708SDavid Chisnalltemplate <class T, class Compare> 5457a984708SDavid Chisnall const T& 546d72607e9SDimitry Andric min(const T& a, const T& b, Compare comp); // constexpr in C++14 5477a984708SDavid Chisnall 5487a984708SDavid Chisnalltemplate<class T> 5497a984708SDavid Chisnall T 550d72607e9SDimitry Andric min(initializer_list<T> t); // constexpr in C++14 5517a984708SDavid Chisnall 5527a984708SDavid Chisnalltemplate<class T, class Compare> 5537a984708SDavid Chisnall T 554d72607e9SDimitry Andric min(initializer_list<T> t, Compare comp); // constexpr in C++14 5557a984708SDavid Chisnall 5567c82a1ecSDimitry Andrictemplate<class T> 5577c82a1ecSDimitry Andric constexpr const T& clamp( const T& v, const T& lo, const T& hi ); // C++17 5587c82a1ecSDimitry Andric 5597c82a1ecSDimitry Andrictemplate<class T, class Compare> 5607c82a1ecSDimitry Andric constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp ); // C++17 5617c82a1ecSDimitry Andric 5627a984708SDavid Chisnalltemplate <class ForwardIterator> 5637a984708SDavid Chisnall ForwardIterator 564854fa44bSDimitry Andric max_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14 5657a984708SDavid Chisnall 5667a984708SDavid Chisnalltemplate <class ForwardIterator, class Compare> 5677a984708SDavid Chisnall ForwardIterator 568854fa44bSDimitry Andric max_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14 5697a984708SDavid Chisnall 5707a984708SDavid Chisnalltemplate <class T> 5717a984708SDavid Chisnall const T& 572d72607e9SDimitry Andric max(const T& a, const T& b); // constexpr in C++14 5737a984708SDavid Chisnall 5747a984708SDavid Chisnalltemplate <class T, class Compare> 5757a984708SDavid Chisnall const T& 576d72607e9SDimitry Andric max(const T& a, const T& b, Compare comp); // constexpr in C++14 5777a984708SDavid Chisnall 5787a984708SDavid Chisnalltemplate<class T> 5797a984708SDavid Chisnall T 580d72607e9SDimitry Andric max(initializer_list<T> t); // constexpr in C++14 5817a984708SDavid Chisnall 5827a984708SDavid Chisnalltemplate<class T, class Compare> 5837a984708SDavid Chisnall T 584d72607e9SDimitry Andric max(initializer_list<T> t, Compare comp); // constexpr in C++14 5857a984708SDavid Chisnall 5867a984708SDavid Chisnalltemplate<class ForwardIterator> 5877a984708SDavid Chisnall pair<ForwardIterator, ForwardIterator> 588854fa44bSDimitry Andric minmax_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14 5897a984708SDavid Chisnall 5907a984708SDavid Chisnalltemplate<class ForwardIterator, class Compare> 5917a984708SDavid Chisnall pair<ForwardIterator, ForwardIterator> 592854fa44bSDimitry Andric minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14 5937a984708SDavid Chisnall 5947a984708SDavid Chisnalltemplate<class T> 5957a984708SDavid Chisnall pair<const T&, const T&> 596d72607e9SDimitry Andric minmax(const T& a, const T& b); // constexpr in C++14 5977a984708SDavid Chisnall 5987a984708SDavid Chisnalltemplate<class T, class Compare> 5997a984708SDavid Chisnall pair<const T&, const T&> 600d72607e9SDimitry Andric minmax(const T& a, const T& b, Compare comp); // constexpr in C++14 6017a984708SDavid Chisnall 6027a984708SDavid Chisnalltemplate<class T> 6037a984708SDavid Chisnall pair<T, T> 604d72607e9SDimitry Andric minmax(initializer_list<T> t); // constexpr in C++14 6057a984708SDavid Chisnall 6067a984708SDavid Chisnalltemplate<class T, class Compare> 6077a984708SDavid Chisnall pair<T, T> 608d72607e9SDimitry Andric minmax(initializer_list<T> t, Compare comp); // constexpr in C++14 6097a984708SDavid Chisnall 6107a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2> 6114ba319b5SDimitry Andric constexpr bool // constexpr in C++20 6127a984708SDavid Chisnall lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); 6137a984708SDavid Chisnall 6147a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class Compare> 6154ba319b5SDimitry Andric constexpr bool // constexpr in C++20 6167a984708SDavid Chisnall lexicographical_compare(InputIterator1 first1, InputIterator1 last1, 6177a984708SDavid Chisnall InputIterator2 first2, InputIterator2 last2, Compare comp); 6187a984708SDavid Chisnall 6197a984708SDavid Chisnalltemplate <class BidirectionalIterator> 6207a984708SDavid Chisnall bool 6217a984708SDavid Chisnall next_permutation(BidirectionalIterator first, BidirectionalIterator last); 6227a984708SDavid Chisnall 6237a984708SDavid Chisnalltemplate <class BidirectionalIterator, class Compare> 6247a984708SDavid Chisnall bool 6257a984708SDavid Chisnall next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); 6267a984708SDavid Chisnall 6277a984708SDavid Chisnalltemplate <class BidirectionalIterator> 6287a984708SDavid Chisnall bool 6297a984708SDavid Chisnall prev_permutation(BidirectionalIterator first, BidirectionalIterator last); 6307a984708SDavid Chisnall 6317a984708SDavid Chisnalltemplate <class BidirectionalIterator, class Compare> 6327a984708SDavid Chisnall bool 6337a984708SDavid Chisnall prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); 6347a984708SDavid Chisnall 6357a984708SDavid Chisnall} // std 6367a984708SDavid Chisnall 6377a984708SDavid Chisnall*/ 6387a984708SDavid Chisnall 6397a984708SDavid Chisnall#include <__config> 6407a984708SDavid Chisnall#include <initializer_list> 6417a984708SDavid Chisnall#include <type_traits> 6427a984708SDavid Chisnall#include <cstring> 6437c82a1ecSDimitry Andric#include <utility> // needed to provide swap_ranges. 6447a984708SDavid Chisnall#include <memory> 6454ba319b5SDimitry Andric#include <functional> 6467a984708SDavid Chisnall#include <iterator> 647936e9439SDimitry Andric#include <cstddef> 648*b5893f02SDimitry Andric#include <bit> 649*b5893f02SDimitry Andric#include <version> 6504f7ab58eSDimitry Andric 651d72607e9SDimitry Andric#include <__debug> 652d72607e9SDimitry Andric 6537a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 6547a984708SDavid Chisnall#pragma GCC system_header 6557a984708SDavid Chisnall#endif 6567a984708SDavid Chisnall 657f9448bf3SDimitry Andric_LIBCPP_PUSH_MACROS 658f9448bf3SDimitry Andric#include <__undef_macros> 659f9448bf3SDimitry Andric 660f9448bf3SDimitry Andric 6617a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD 6627a984708SDavid Chisnall 663d72607e9SDimitry Andric// I'd like to replace these with _VSTD::equal_to<void>, but can't because: 664d72607e9SDimitry Andric// * That only works with C++14 and later, and 665d72607e9SDimitry Andric// * We haven't included <functional> here. 6667a984708SDavid Chisnalltemplate <class _T1, class _T2 = _T1> 6677a984708SDavid Chisnallstruct __equal_to 6687a984708SDavid Chisnall{ 6694ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 6704ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;} 6714ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;} 6724ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;} 6737a984708SDavid Chisnall}; 6747a984708SDavid Chisnall 6757a984708SDavid Chisnalltemplate <class _T1> 6767a984708SDavid Chisnallstruct __equal_to<_T1, _T1> 6777a984708SDavid Chisnall{ 678d72607e9SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 679d72607e9SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 6807a984708SDavid Chisnall}; 6817a984708SDavid Chisnall 6827a984708SDavid Chisnalltemplate <class _T1> 6837a984708SDavid Chisnallstruct __equal_to<const _T1, _T1> 6847a984708SDavid Chisnall{ 685d72607e9SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 686d72607e9SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 6877a984708SDavid Chisnall}; 6887a984708SDavid Chisnall 6897a984708SDavid Chisnalltemplate <class _T1> 6907a984708SDavid Chisnallstruct __equal_to<_T1, const _T1> 6917a984708SDavid Chisnall{ 692d72607e9SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 693d72607e9SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} 6947a984708SDavid Chisnall}; 6957a984708SDavid Chisnall 6967a984708SDavid Chisnalltemplate <class _T1, class _T2 = _T1> 6977a984708SDavid Chisnallstruct __less 6987a984708SDavid Chisnall{ 699d72607e9SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 700d72607e9SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 701d72607e9SDimitry Andric 702d72607e9SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 703d72607e9SDimitry Andric bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;} 704d72607e9SDimitry Andric 705d72607e9SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 706d72607e9SDimitry Andric bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;} 707d72607e9SDimitry Andric 708d72607e9SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 709d72607e9SDimitry Andric bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;} 7107a984708SDavid Chisnall}; 7117a984708SDavid Chisnall 7127a984708SDavid Chisnalltemplate <class _T1> 7137a984708SDavid Chisnallstruct __less<_T1, _T1> 7147a984708SDavid Chisnall{ 715d72607e9SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 716d72607e9SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 7177a984708SDavid Chisnall}; 7187a984708SDavid Chisnall 7197a984708SDavid Chisnalltemplate <class _T1> 7207a984708SDavid Chisnallstruct __less<const _T1, _T1> 7217a984708SDavid Chisnall{ 722d72607e9SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 723d72607e9SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 7247a984708SDavid Chisnall}; 7257a984708SDavid Chisnall 7267a984708SDavid Chisnalltemplate <class _T1> 7277a984708SDavid Chisnallstruct __less<_T1, const _T1> 7287a984708SDavid Chisnall{ 729d72607e9SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 730d72607e9SDimitry Andric bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} 7317a984708SDavid Chisnall}; 7327a984708SDavid Chisnall 7337a984708SDavid Chisnalltemplate <class _Predicate> 734b2c7081bSDimitry Andricclass __invert // invert the sense of a comparison 7357a984708SDavid Chisnall{ 7367a984708SDavid Chisnallprivate: 7377a984708SDavid Chisnall _Predicate __p_; 7387a984708SDavid Chisnallpublic: 739b2c7081bSDimitry Andric _LIBCPP_INLINE_VISIBILITY __invert() {} 7407a984708SDavid Chisnall 7417a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 742b2c7081bSDimitry Andric explicit __invert(_Predicate __p) : __p_(__p) {} 7437a984708SDavid Chisnall 7447a984708SDavid Chisnall template <class _T1> 7457a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 7467a984708SDavid Chisnall bool operator()(const _T1& __x) {return !__p_(__x);} 7477a984708SDavid Chisnall 7487a984708SDavid Chisnall template <class _T1, class _T2> 7497a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 750b2c7081bSDimitry Andric bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} 7517a984708SDavid Chisnall}; 7527a984708SDavid Chisnall 753*b5893f02SDimitry Andric// Perform division by two quickly for positive integers (llvm.org/PR39129) 754*b5893f02SDimitry Andric 755*b5893f02SDimitry Andrictemplate <typename _Integral> 756*b5893f02SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 757*b5893f02SDimitry Andrictypename enable_if 758*b5893f02SDimitry Andric< 759*b5893f02SDimitry Andric is_integral<_Integral>::value, 760*b5893f02SDimitry Andric _Integral 761*b5893f02SDimitry Andric>::type 762*b5893f02SDimitry Andric__half_positive(_Integral __value) 763*b5893f02SDimitry Andric{ 764*b5893f02SDimitry Andric return static_cast<_Integral>(static_cast<typename make_unsigned<_Integral>::type>(__value) / 2); 765*b5893f02SDimitry Andric} 766*b5893f02SDimitry Andric 767*b5893f02SDimitry Andrictemplate <typename _Tp> 768*b5893f02SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 769*b5893f02SDimitry Andrictypename enable_if 770*b5893f02SDimitry Andric< 771*b5893f02SDimitry Andric !is_integral<_Tp>::value, 772*b5893f02SDimitry Andric _Tp 773*b5893f02SDimitry Andric>::type 774*b5893f02SDimitry Andric__half_positive(_Tp __value) 775*b5893f02SDimitry Andric{ 776*b5893f02SDimitry Andric return __value / 2; 777*b5893f02SDimitry Andric} 778*b5893f02SDimitry Andric 7794f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 7807a984708SDavid Chisnall 7817a984708SDavid Chisnalltemplate <class _Compare> 7827a984708SDavid Chisnallstruct __debug_less 7837a984708SDavid Chisnall{ 7847a984708SDavid Chisnall _Compare __comp_; 7857a984708SDavid Chisnall __debug_less(_Compare& __c) : __comp_(__c) {} 786aed8d94eSDimitry Andric 7877a984708SDavid Chisnall template <class _Tp, class _Up> 7887a984708SDavid Chisnall bool operator()(const _Tp& __x, const _Up& __y) 7897a984708SDavid Chisnall { 7907a984708SDavid Chisnall bool __r = __comp_(__x, __y); 7917a984708SDavid Chisnall if (__r) 792aed8d94eSDimitry Andric __do_compare_assert(0, __y, __x); 7937a984708SDavid Chisnall return __r; 7947a984708SDavid Chisnall } 795aed8d94eSDimitry Andric 796aed8d94eSDimitry Andric template <class _LHS, class _RHS> 797aed8d94eSDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 798aed8d94eSDimitry Andric decltype((void)_VSTD::declval<_Compare&>()( 799aed8d94eSDimitry Andric _VSTD::declval<_LHS const&>(), _VSTD::declval<_RHS const&>())) 800aed8d94eSDimitry Andric __do_compare_assert(int, _LHS const& __l, _RHS const& __r) { 801aed8d94eSDimitry Andric _LIBCPP_ASSERT(!__comp_(__l, __r), 802aed8d94eSDimitry Andric "Comparator does not induce a strict weak ordering"); 803aed8d94eSDimitry Andric } 804aed8d94eSDimitry Andric 805aed8d94eSDimitry Andric template <class _LHS, class _RHS> 806aed8d94eSDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 807aed8d94eSDimitry Andric void __do_compare_assert(long, _LHS const&, _RHS const&) {} 8087a984708SDavid Chisnall}; 8097a984708SDavid Chisnall 8104f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 8117a984708SDavid Chisnall 8127a984708SDavid Chisnall// all_of 8137a984708SDavid Chisnall 8147a984708SDavid Chisnalltemplate <class _InputIterator, class _Predicate> 8154ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 8167a984708SDavid Chisnallbool 8177a984708SDavid Chisnallall_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 8187a984708SDavid Chisnall{ 8197a984708SDavid Chisnall for (; __first != __last; ++__first) 8207a984708SDavid Chisnall if (!__pred(*__first)) 8217a984708SDavid Chisnall return false; 8227a984708SDavid Chisnall return true; 8237a984708SDavid Chisnall} 8247a984708SDavid Chisnall 8257a984708SDavid Chisnall// any_of 8267a984708SDavid Chisnall 8277a984708SDavid Chisnalltemplate <class _InputIterator, class _Predicate> 8284ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 8297a984708SDavid Chisnallbool 8307a984708SDavid Chisnallany_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 8317a984708SDavid Chisnall{ 8327a984708SDavid Chisnall for (; __first != __last; ++__first) 8337a984708SDavid Chisnall if (__pred(*__first)) 8347a984708SDavid Chisnall return true; 8357a984708SDavid Chisnall return false; 8367a984708SDavid Chisnall} 8377a984708SDavid Chisnall 8387a984708SDavid Chisnall// none_of 8397a984708SDavid Chisnall 8407a984708SDavid Chisnalltemplate <class _InputIterator, class _Predicate> 8414ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 8427a984708SDavid Chisnallbool 8437a984708SDavid Chisnallnone_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) 8447a984708SDavid Chisnall{ 8457a984708SDavid Chisnall for (; __first != __last; ++__first) 8467a984708SDavid Chisnall if (__pred(*__first)) 8477a984708SDavid Chisnall return false; 8487a984708SDavid Chisnall return true; 8497a984708SDavid Chisnall} 8507a984708SDavid Chisnall 8517a984708SDavid Chisnall// for_each 8527a984708SDavid Chisnall 8537a984708SDavid Chisnalltemplate <class _InputIterator, class _Function> 8544ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 8557a984708SDavid Chisnall_Function 8567a984708SDavid Chisnallfor_each(_InputIterator __first, _InputIterator __last, _Function __f) 8577a984708SDavid Chisnall{ 8587a984708SDavid Chisnall for (; __first != __last; ++__first) 8597a984708SDavid Chisnall __f(*__first); 860aed8d94eSDimitry Andric return __f; 8617a984708SDavid Chisnall} 8627a984708SDavid Chisnall 863302affcbSDimitry Andric#if _LIBCPP_STD_VER > 14 864302affcbSDimitry Andric// for_each_n 865302affcbSDimitry Andric 866302affcbSDimitry Andrictemplate <class _InputIterator, class _Size, class _Function> 8674ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 868302affcbSDimitry Andric_InputIterator 869302affcbSDimitry Andricfor_each_n(_InputIterator __first, _Size __orig_n, _Function __f) 870302affcbSDimitry Andric{ 871302affcbSDimitry Andric typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; 872302affcbSDimitry Andric _IntegralSize __n = __orig_n; 873302affcbSDimitry Andric while (__n > 0) 874302affcbSDimitry Andric { 875302affcbSDimitry Andric __f(*__first); 876302affcbSDimitry Andric ++__first; 877302affcbSDimitry Andric --__n; 878302affcbSDimitry Andric } 879302affcbSDimitry Andric return __first; 880302affcbSDimitry Andric} 881302affcbSDimitry Andric#endif 882302affcbSDimitry Andric 8837a984708SDavid Chisnall// find 8847a984708SDavid Chisnall 8857a984708SDavid Chisnalltemplate <class _InputIterator, class _Tp> 8864ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 8877a984708SDavid Chisnall_InputIterator 8887a984708SDavid Chisnallfind(_InputIterator __first, _InputIterator __last, const _Tp& __value_) 8897a984708SDavid Chisnall{ 8907a984708SDavid Chisnall for (; __first != __last; ++__first) 8917a984708SDavid Chisnall if (*__first == __value_) 8927a984708SDavid Chisnall break; 8937a984708SDavid Chisnall return __first; 8947a984708SDavid Chisnall} 8957a984708SDavid Chisnall 8967a984708SDavid Chisnall// find_if 8977a984708SDavid Chisnall 8987a984708SDavid Chisnalltemplate <class _InputIterator, class _Predicate> 8994ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 9007a984708SDavid Chisnall_InputIterator 9017a984708SDavid Chisnallfind_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) 9027a984708SDavid Chisnall{ 9037a984708SDavid Chisnall for (; __first != __last; ++__first) 9047a984708SDavid Chisnall if (__pred(*__first)) 9057a984708SDavid Chisnall break; 9067a984708SDavid Chisnall return __first; 9077a984708SDavid Chisnall} 9087a984708SDavid Chisnall 9097a984708SDavid Chisnall// find_if_not 9107a984708SDavid Chisnall 9117a984708SDavid Chisnalltemplate<class _InputIterator, class _Predicate> 9124ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 9137a984708SDavid Chisnall_InputIterator 9147a984708SDavid Chisnallfind_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) 9157a984708SDavid Chisnall{ 9167a984708SDavid Chisnall for (; __first != __last; ++__first) 9177a984708SDavid Chisnall if (!__pred(*__first)) 9187a984708SDavid Chisnall break; 9197a984708SDavid Chisnall return __first; 9207a984708SDavid Chisnall} 9217a984708SDavid Chisnall 9227a984708SDavid Chisnall// find_end 9237a984708SDavid Chisnall 9247a984708SDavid Chisnalltemplate <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> 9254ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 9267a984708SDavid Chisnall__find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 9277a984708SDavid Chisnall _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, 9287a984708SDavid Chisnall forward_iterator_tag, forward_iterator_tag) 9297a984708SDavid Chisnall{ 9307a984708SDavid Chisnall // modeled after search algorithm 9317a984708SDavid Chisnall _ForwardIterator1 __r = __last1; // __last1 is the "default" answer 9327a984708SDavid Chisnall if (__first2 == __last2) 9337a984708SDavid Chisnall return __r; 9347a984708SDavid Chisnall while (true) 9357a984708SDavid Chisnall { 9367a984708SDavid Chisnall while (true) 9377a984708SDavid Chisnall { 9387a984708SDavid Chisnall if (__first1 == __last1) // if source exhausted return last correct answer 9397a984708SDavid Chisnall return __r; // (or __last1 if never found) 9407a984708SDavid Chisnall if (__pred(*__first1, *__first2)) 9417a984708SDavid Chisnall break; 9427a984708SDavid Chisnall ++__first1; 9437a984708SDavid Chisnall } 9447a984708SDavid Chisnall // *__first1 matches *__first2, now match elements after here 9457a984708SDavid Chisnall _ForwardIterator1 __m1 = __first1; 9467a984708SDavid Chisnall _ForwardIterator2 __m2 = __first2; 9477a984708SDavid Chisnall while (true) 9487a984708SDavid Chisnall { 9497a984708SDavid Chisnall if (++__m2 == __last2) 9507a984708SDavid Chisnall { // Pattern exhaused, record answer and search for another one 9517a984708SDavid Chisnall __r = __first1; 9527a984708SDavid Chisnall ++__first1; 9537a984708SDavid Chisnall break; 9547a984708SDavid Chisnall } 9557a984708SDavid Chisnall if (++__m1 == __last1) // Source exhausted, return last answer 9567a984708SDavid Chisnall return __r; 9577a984708SDavid Chisnall if (!__pred(*__m1, *__m2)) // mismatch, restart with a new __first 9587a984708SDavid Chisnall { 9597a984708SDavid Chisnall ++__first1; 9607a984708SDavid Chisnall break; 9617a984708SDavid Chisnall } // else there is a match, check next elements 9627a984708SDavid Chisnall } 9637a984708SDavid Chisnall } 9647a984708SDavid Chisnall} 9657a984708SDavid Chisnall 9667a984708SDavid Chisnalltemplate <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2> 9674ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 9687a984708SDavid Chisnall__find_end(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, 9697a984708SDavid Chisnall _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, _BinaryPredicate __pred, 9707a984708SDavid Chisnall bidirectional_iterator_tag, bidirectional_iterator_tag) 9717a984708SDavid Chisnall{ 9727a984708SDavid Chisnall // modeled after search algorithm (in reverse) 9737a984708SDavid Chisnall if (__first2 == __last2) 9747a984708SDavid Chisnall return __last1; // Everything matches an empty sequence 9757a984708SDavid Chisnall _BidirectionalIterator1 __l1 = __last1; 9767a984708SDavid Chisnall _BidirectionalIterator2 __l2 = __last2; 9777a984708SDavid Chisnall --__l2; 9787a984708SDavid Chisnall while (true) 9797a984708SDavid Chisnall { 9807a984708SDavid Chisnall // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks 9817a984708SDavid Chisnall while (true) 9827a984708SDavid Chisnall { 9837a984708SDavid Chisnall if (__first1 == __l1) // return __last1 if no element matches *__first2 9847a984708SDavid Chisnall return __last1; 9857a984708SDavid Chisnall if (__pred(*--__l1, *__l2)) 9867a984708SDavid Chisnall break; 9877a984708SDavid Chisnall } 9887a984708SDavid Chisnall // *__l1 matches *__l2, now match elements before here 9897a984708SDavid Chisnall _BidirectionalIterator1 __m1 = __l1; 9907a984708SDavid Chisnall _BidirectionalIterator2 __m2 = __l2; 9917a984708SDavid Chisnall while (true) 9927a984708SDavid Chisnall { 9937a984708SDavid Chisnall if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern) 9947a984708SDavid Chisnall return __m1; 9957a984708SDavid Chisnall if (__m1 == __first1) // Otherwise if source exhaused, pattern not found 9967a984708SDavid Chisnall return __last1; 9977a984708SDavid Chisnall if (!__pred(*--__m1, *--__m2)) // if there is a mismatch, restart with a new __l1 9987a984708SDavid Chisnall { 9997a984708SDavid Chisnall break; 10007a984708SDavid Chisnall } // else there is a match, check next elements 10017a984708SDavid Chisnall } 10027a984708SDavid Chisnall } 10037a984708SDavid Chisnall} 10047a984708SDavid Chisnall 10057a984708SDavid Chisnalltemplate <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> 1006d72607e9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 10077a984708SDavid Chisnall__find_end(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, 10087a984708SDavid Chisnall _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, 10097a984708SDavid Chisnall random_access_iterator_tag, random_access_iterator_tag) 10107a984708SDavid Chisnall{ 10117a984708SDavid Chisnall // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern 10127a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2; 10137a984708SDavid Chisnall if (__len2 == 0) 10147a984708SDavid Chisnall return __last1; 10157a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1; 10167a984708SDavid Chisnall if (__len1 < __len2) 10177a984708SDavid Chisnall return __last1; 10187a984708SDavid Chisnall const _RandomAccessIterator1 __s = __first1 + (__len2 - 1); // End of pattern match can't go before here 10197a984708SDavid Chisnall _RandomAccessIterator1 __l1 = __last1; 10207a984708SDavid Chisnall _RandomAccessIterator2 __l2 = __last2; 10217a984708SDavid Chisnall --__l2; 10227a984708SDavid Chisnall while (true) 10237a984708SDavid Chisnall { 10247a984708SDavid Chisnall while (true) 10257a984708SDavid Chisnall { 10267a984708SDavid Chisnall if (__s == __l1) 10277a984708SDavid Chisnall return __last1; 10287a984708SDavid Chisnall if (__pred(*--__l1, *__l2)) 10297a984708SDavid Chisnall break; 10307a984708SDavid Chisnall } 10317a984708SDavid Chisnall _RandomAccessIterator1 __m1 = __l1; 10327a984708SDavid Chisnall _RandomAccessIterator2 __m2 = __l2; 10337a984708SDavid Chisnall while (true) 10347a984708SDavid Chisnall { 10357a984708SDavid Chisnall if (__m2 == __first2) 10367a984708SDavid Chisnall return __m1; 10377a984708SDavid Chisnall // no need to check range on __m1 because __s guarantees we have enough source 10387a984708SDavid Chisnall if (!__pred(*--__m1, *--__m2)) 10397a984708SDavid Chisnall { 10407a984708SDavid Chisnall break; 10417a984708SDavid Chisnall } 10427a984708SDavid Chisnall } 10437a984708SDavid Chisnall } 10447a984708SDavid Chisnall} 10457a984708SDavid Chisnall 10467a984708SDavid Chisnalltemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 10474ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 10487a984708SDavid Chisnall_ForwardIterator1 10497a984708SDavid Chisnallfind_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 10507a984708SDavid Chisnall _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 10517a984708SDavid Chisnall{ 10527a984708SDavid Chisnall return _VSTD::__find_end<typename add_lvalue_reference<_BinaryPredicate>::type> 10537a984708SDavid Chisnall (__first1, __last1, __first2, __last2, __pred, 10547a984708SDavid Chisnall typename iterator_traits<_ForwardIterator1>::iterator_category(), 10557a984708SDavid Chisnall typename iterator_traits<_ForwardIterator2>::iterator_category()); 10567a984708SDavid Chisnall} 10577a984708SDavid Chisnall 10587a984708SDavid Chisnalltemplate <class _ForwardIterator1, class _ForwardIterator2> 10594ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 10607a984708SDavid Chisnall_ForwardIterator1 10617a984708SDavid Chisnallfind_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 10627a984708SDavid Chisnall _ForwardIterator2 __first2, _ForwardIterator2 __last2) 10637a984708SDavid Chisnall{ 10647a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 10657a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 10667a984708SDavid Chisnall return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 10677a984708SDavid Chisnall} 10687a984708SDavid Chisnall 10697a984708SDavid Chisnall// find_first_of 10707a984708SDavid Chisnall 10717a984708SDavid Chisnalltemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 1072d72607e9SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1 1073d72607e9SDimitry Andric__find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 10747a984708SDavid Chisnall _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 10757a984708SDavid Chisnall{ 10767a984708SDavid Chisnall for (; __first1 != __last1; ++__first1) 10777a984708SDavid Chisnall for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) 10787a984708SDavid Chisnall if (__pred(*__first1, *__j)) 10797a984708SDavid Chisnall return __first1; 10807a984708SDavid Chisnall return __last1; 10817a984708SDavid Chisnall} 10827a984708SDavid Chisnall 1083d72607e9SDimitry Andric 1084d72607e9SDimitry Andrictemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 10854ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 1086d72607e9SDimitry Andric_ForwardIterator1 1087d72607e9SDimitry Andricfind_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 1088d72607e9SDimitry Andric _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 1089d72607e9SDimitry Andric{ 1090d72607e9SDimitry Andric return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); 1091d72607e9SDimitry Andric} 1092d72607e9SDimitry Andric 10937a984708SDavid Chisnalltemplate <class _ForwardIterator1, class _ForwardIterator2> 10944ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 10957a984708SDavid Chisnall_ForwardIterator1 10967a984708SDavid Chisnallfind_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 10977a984708SDavid Chisnall _ForwardIterator2 __first2, _ForwardIterator2 __last2) 10987a984708SDavid Chisnall{ 10997a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 11007a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 1101d72607e9SDimitry Andric return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 11027a984708SDavid Chisnall} 11037a984708SDavid Chisnall 11047a984708SDavid Chisnall// adjacent_find 11057a984708SDavid Chisnall 11067a984708SDavid Chisnalltemplate <class _ForwardIterator, class _BinaryPredicate> 11074ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11087a984708SDavid Chisnall_ForwardIterator 11097a984708SDavid Chisnalladjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) 11107a984708SDavid Chisnall{ 11117a984708SDavid Chisnall if (__first != __last) 11127a984708SDavid Chisnall { 11137a984708SDavid Chisnall _ForwardIterator __i = __first; 11147a984708SDavid Chisnall while (++__i != __last) 11157a984708SDavid Chisnall { 11167a984708SDavid Chisnall if (__pred(*__first, *__i)) 11177a984708SDavid Chisnall return __first; 11187a984708SDavid Chisnall __first = __i; 11197a984708SDavid Chisnall } 11207a984708SDavid Chisnall } 11217a984708SDavid Chisnall return __last; 11227a984708SDavid Chisnall} 11237a984708SDavid Chisnall 11247a984708SDavid Chisnalltemplate <class _ForwardIterator> 11254ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11267a984708SDavid Chisnall_ForwardIterator 11277a984708SDavid Chisnalladjacent_find(_ForwardIterator __first, _ForwardIterator __last) 11287a984708SDavid Chisnall{ 11297a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator>::value_type __v; 11307a984708SDavid Chisnall return _VSTD::adjacent_find(__first, __last, __equal_to<__v>()); 11317a984708SDavid Chisnall} 11327a984708SDavid Chisnall 11337a984708SDavid Chisnall// count 11347a984708SDavid Chisnall 11357a984708SDavid Chisnalltemplate <class _InputIterator, class _Tp> 11364ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11377a984708SDavid Chisnalltypename iterator_traits<_InputIterator>::difference_type 11387a984708SDavid Chisnallcount(_InputIterator __first, _InputIterator __last, const _Tp& __value_) 11397a984708SDavid Chisnall{ 11407a984708SDavid Chisnall typename iterator_traits<_InputIterator>::difference_type __r(0); 11417a984708SDavid Chisnall for (; __first != __last; ++__first) 11427a984708SDavid Chisnall if (*__first == __value_) 11437a984708SDavid Chisnall ++__r; 11447a984708SDavid Chisnall return __r; 11457a984708SDavid Chisnall} 11467a984708SDavid Chisnall 11477a984708SDavid Chisnall// count_if 11487a984708SDavid Chisnall 11497a984708SDavid Chisnalltemplate <class _InputIterator, class _Predicate> 11504ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11517a984708SDavid Chisnalltypename iterator_traits<_InputIterator>::difference_type 11527a984708SDavid Chisnallcount_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) 11537a984708SDavid Chisnall{ 11547a984708SDavid Chisnall typename iterator_traits<_InputIterator>::difference_type __r(0); 11557a984708SDavid Chisnall for (; __first != __last; ++__first) 11567a984708SDavid Chisnall if (__pred(*__first)) 11577a984708SDavid Chisnall ++__r; 11587a984708SDavid Chisnall return __r; 11597a984708SDavid Chisnall} 11607a984708SDavid Chisnall 11617a984708SDavid Chisnall// mismatch 11627a984708SDavid Chisnall 11637a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 11644ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11657a984708SDavid Chisnallpair<_InputIterator1, _InputIterator2> 11667a984708SDavid Chisnallmismatch(_InputIterator1 __first1, _InputIterator1 __last1, 11677a984708SDavid Chisnall _InputIterator2 __first2, _BinaryPredicate __pred) 11687a984708SDavid Chisnall{ 1169d72607e9SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2) 11707a984708SDavid Chisnall if (!__pred(*__first1, *__first2)) 11717a984708SDavid Chisnall break; 11727a984708SDavid Chisnall return pair<_InputIterator1, _InputIterator2>(__first1, __first2); 11737a984708SDavid Chisnall} 11747a984708SDavid Chisnall 11757a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2> 11764ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11777a984708SDavid Chisnallpair<_InputIterator1, _InputIterator2> 11787a984708SDavid Chisnallmismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) 11797a984708SDavid Chisnall{ 11807a984708SDavid Chisnall typedef typename iterator_traits<_InputIterator1>::value_type __v1; 11817a984708SDavid Chisnall typedef typename iterator_traits<_InputIterator2>::value_type __v2; 11827a984708SDavid Chisnall return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>()); 11837a984708SDavid Chisnall} 11847a984708SDavid Chisnall 11854bab9fd9SDavid Chisnall#if _LIBCPP_STD_VER > 11 11864bab9fd9SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 11874ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 11884bab9fd9SDavid Chisnallpair<_InputIterator1, _InputIterator2> 11894bab9fd9SDavid Chisnallmismatch(_InputIterator1 __first1, _InputIterator1 __last1, 11904bab9fd9SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, 11914bab9fd9SDavid Chisnall _BinaryPredicate __pred) 11924bab9fd9SDavid Chisnall{ 1193d72607e9SDimitry Andric for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) 11944bab9fd9SDavid Chisnall if (!__pred(*__first1, *__first2)) 11954bab9fd9SDavid Chisnall break; 11964bab9fd9SDavid Chisnall return pair<_InputIterator1, _InputIterator2>(__first1, __first2); 11974bab9fd9SDavid Chisnall} 11984bab9fd9SDavid Chisnall 11994bab9fd9SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2> 12004ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12014bab9fd9SDavid Chisnallpair<_InputIterator1, _InputIterator2> 12024bab9fd9SDavid Chisnallmismatch(_InputIterator1 __first1, _InputIterator1 __last1, 12034bab9fd9SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2) 12044bab9fd9SDavid Chisnall{ 12054bab9fd9SDavid Chisnall typedef typename iterator_traits<_InputIterator1>::value_type __v1; 12064bab9fd9SDavid Chisnall typedef typename iterator_traits<_InputIterator2>::value_type __v2; 12074bab9fd9SDavid Chisnall return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 12084bab9fd9SDavid Chisnall} 12094bab9fd9SDavid Chisnall#endif 12104bab9fd9SDavid Chisnall 12117a984708SDavid Chisnall// equal 12127a984708SDavid Chisnall 12137a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 12144ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12157a984708SDavid Chisnallbool 12167a984708SDavid Chisnallequal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) 12177a984708SDavid Chisnall{ 1218d72607e9SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2) 12197a984708SDavid Chisnall if (!__pred(*__first1, *__first2)) 12207a984708SDavid Chisnall return false; 12217a984708SDavid Chisnall return true; 12227a984708SDavid Chisnall} 12237a984708SDavid Chisnall 12247a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2> 12254ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12267a984708SDavid Chisnallbool 12277a984708SDavid Chisnallequal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) 12287a984708SDavid Chisnall{ 12297a984708SDavid Chisnall typedef typename iterator_traits<_InputIterator1>::value_type __v1; 12307a984708SDavid Chisnall typedef typename iterator_traits<_InputIterator2>::value_type __v2; 12317a984708SDavid Chisnall return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>()); 12327a984708SDavid Chisnall} 12337a984708SDavid Chisnall 12344bab9fd9SDavid Chisnall#if _LIBCPP_STD_VER > 11 12354bab9fd9SDavid Chisnalltemplate <class _BinaryPredicate, class _InputIterator1, class _InputIterator2> 12364ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12374bab9fd9SDavid Chisnallbool 12384bab9fd9SDavid Chisnall__equal(_InputIterator1 __first1, _InputIterator1 __last1, 12394bab9fd9SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred, 12404bab9fd9SDavid Chisnall input_iterator_tag, input_iterator_tag ) 12414bab9fd9SDavid Chisnall{ 1242d72607e9SDimitry Andric for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) 12434bab9fd9SDavid Chisnall if (!__pred(*__first1, *__first2)) 12444bab9fd9SDavid Chisnall return false; 12454bab9fd9SDavid Chisnall return __first1 == __last1 && __first2 == __last2; 12464bab9fd9SDavid Chisnall} 12474bab9fd9SDavid Chisnall 12484bab9fd9SDavid Chisnalltemplate <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> 12494ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12504bab9fd9SDavid Chisnallbool 12514bab9fd9SDavid Chisnall__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, 12524bab9fd9SDavid Chisnall _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, 12534bab9fd9SDavid Chisnall random_access_iterator_tag, random_access_iterator_tag ) 12544bab9fd9SDavid Chisnall{ 12554bab9fd9SDavid Chisnall if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) 12564bab9fd9SDavid Chisnall return false; 12574bab9fd9SDavid Chisnall return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2, 12584bab9fd9SDavid Chisnall typename add_lvalue_reference<_BinaryPredicate>::type> 12594bab9fd9SDavid Chisnall (__first1, __last1, __first2, __pred ); 12604bab9fd9SDavid Chisnall} 12614bab9fd9SDavid Chisnall 12624bab9fd9SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> 12634ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12644bab9fd9SDavid Chisnallbool 12654bab9fd9SDavid Chisnallequal(_InputIterator1 __first1, _InputIterator1 __last1, 12664bab9fd9SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred ) 12674bab9fd9SDavid Chisnall{ 12684bab9fd9SDavid Chisnall return _VSTD::__equal<typename add_lvalue_reference<_BinaryPredicate>::type> 12694bab9fd9SDavid Chisnall (__first1, __last1, __first2, __last2, __pred, 12704bab9fd9SDavid Chisnall typename iterator_traits<_InputIterator1>::iterator_category(), 12714bab9fd9SDavid Chisnall typename iterator_traits<_InputIterator2>::iterator_category()); 12724bab9fd9SDavid Chisnall} 12734bab9fd9SDavid Chisnall 12744bab9fd9SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2> 12754ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 12764bab9fd9SDavid Chisnallbool 12774bab9fd9SDavid Chisnallequal(_InputIterator1 __first1, _InputIterator1 __last1, 12784bab9fd9SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2) 12794bab9fd9SDavid Chisnall{ 12804bab9fd9SDavid Chisnall typedef typename iterator_traits<_InputIterator1>::value_type __v1; 12814bab9fd9SDavid Chisnall typedef typename iterator_traits<_InputIterator2>::value_type __v2; 12824bab9fd9SDavid Chisnall return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(), 12834bab9fd9SDavid Chisnall typename iterator_traits<_InputIterator1>::iterator_category(), 12844bab9fd9SDavid Chisnall typename iterator_traits<_InputIterator2>::iterator_category()); 12854bab9fd9SDavid Chisnall} 12864bab9fd9SDavid Chisnall#endif 12874bab9fd9SDavid Chisnall 12887a984708SDavid Chisnall// is_permutation 12897a984708SDavid Chisnall 12907a984708SDavid Chisnalltemplate<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 12914ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 12927a984708SDavid Chisnallis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 12937a984708SDavid Chisnall _ForwardIterator2 __first2, _BinaryPredicate __pred) 12947a984708SDavid Chisnall{ 12954ba319b5SDimitry Andric// shorten sequences as much as possible by lopping of any equal prefix 1296d72607e9SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2) 12977a984708SDavid Chisnall if (!__pred(*__first1, *__first2)) 12984ba319b5SDimitry Andric break; 12994ba319b5SDimitry Andric if (__first1 == __last1) 13007a984708SDavid Chisnall return true; 13014ba319b5SDimitry Andric 13027a984708SDavid Chisnall// __first1 != __last1 && *__first1 != *__first2 13037a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; 13047a984708SDavid Chisnall _D1 __l1 = _VSTD::distance(__first1, __last1); 13057a984708SDavid Chisnall if (__l1 == _D1(1)) 13067a984708SDavid Chisnall return false; 13077a984708SDavid Chisnall _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1); 13087a984708SDavid Chisnall // For each element in [f1, l1) see if there are the same number of 13097a984708SDavid Chisnall // equal elements in [f2, l2) 13107a984708SDavid Chisnall for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) 13117a984708SDavid Chisnall { 13127a984708SDavid Chisnall // Have we already counted the number of *__i in [f1, l1)? 13134ba319b5SDimitry Andric _ForwardIterator1 __match = __first1; 13144ba319b5SDimitry Andric for (; __match != __i; ++__match) 13154ba319b5SDimitry Andric if (__pred(*__match, *__i)) 13164ba319b5SDimitry Andric break; 13174ba319b5SDimitry Andric if (__match == __i) { 13187a984708SDavid Chisnall // Count number of *__i in [f2, l2) 13197a984708SDavid Chisnall _D1 __c2 = 0; 13207a984708SDavid Chisnall for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) 13217a984708SDavid Chisnall if (__pred(*__i, *__j)) 13227a984708SDavid Chisnall ++__c2; 13237a984708SDavid Chisnall if (__c2 == 0) 13247a984708SDavid Chisnall return false; 13257a984708SDavid Chisnall // Count number of *__i in [__i, l1) (we can start with 1) 13267a984708SDavid Chisnall _D1 __c1 = 1; 13277a984708SDavid Chisnall for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) 13287a984708SDavid Chisnall if (__pred(*__i, *__j)) 13297a984708SDavid Chisnall ++__c1; 13307a984708SDavid Chisnall if (__c1 != __c2) 13317a984708SDavid Chisnall return false; 13327a984708SDavid Chisnall } 13337a984708SDavid Chisnall } 13347a984708SDavid Chisnall return true; 13357a984708SDavid Chisnall} 13367a984708SDavid Chisnall 13377a984708SDavid Chisnalltemplate<class _ForwardIterator1, class _ForwardIterator2> 13384ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 13397a984708SDavid Chisnallbool 13407a984708SDavid Chisnallis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 13417a984708SDavid Chisnall _ForwardIterator2 __first2) 13427a984708SDavid Chisnall{ 13437a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 13447a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 13457a984708SDavid Chisnall return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>()); 13467a984708SDavid Chisnall} 13477a984708SDavid Chisnall 13484bab9fd9SDavid Chisnall#if _LIBCPP_STD_VER > 11 13494bab9fd9SDavid Chisnalltemplate<class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> 13504ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 13514bab9fd9SDavid Chisnall__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 13524bab9fd9SDavid Chisnall _ForwardIterator2 __first2, _ForwardIterator2 __last2, 13534bab9fd9SDavid Chisnall _BinaryPredicate __pred, 13544bab9fd9SDavid Chisnall forward_iterator_tag, forward_iterator_tag ) 13554bab9fd9SDavid Chisnall{ 13564ba319b5SDimitry Andric// shorten sequences as much as possible by lopping of any equal prefix 1357d72607e9SDimitry Andric for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) 13584bab9fd9SDavid Chisnall if (!__pred(*__first1, *__first2)) 13594ba319b5SDimitry Andric break; 13604ba319b5SDimitry Andric if (__first1 == __last1) 13614ba319b5SDimitry Andric return __first2 == __last2; 13624ba319b5SDimitry Andric else if (__first2 == __last2) 13634ba319b5SDimitry Andric return false; 13644ba319b5SDimitry Andric 13654bab9fd9SDavid Chisnall typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; 13664bab9fd9SDavid Chisnall _D1 __l1 = _VSTD::distance(__first1, __last1); 13674bab9fd9SDavid Chisnall 13684bab9fd9SDavid Chisnall typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2; 13694bab9fd9SDavid Chisnall _D2 __l2 = _VSTD::distance(__first2, __last2); 13704bab9fd9SDavid Chisnall if (__l1 != __l2) 13714bab9fd9SDavid Chisnall return false; 13724bab9fd9SDavid Chisnall 13734bab9fd9SDavid Chisnall // For each element in [f1, l1) see if there are the same number of 13744bab9fd9SDavid Chisnall // equal elements in [f2, l2) 13754bab9fd9SDavid Chisnall for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) 13764bab9fd9SDavid Chisnall { 13774bab9fd9SDavid Chisnall // Have we already counted the number of *__i in [f1, l1)? 13784ba319b5SDimitry Andric _ForwardIterator1 __match = __first1; 13794ba319b5SDimitry Andric for (; __match != __i; ++__match) 13804ba319b5SDimitry Andric if (__pred(*__match, *__i)) 13814ba319b5SDimitry Andric break; 13824ba319b5SDimitry Andric if (__match == __i) { 13834bab9fd9SDavid Chisnall // Count number of *__i in [f2, l2) 13844bab9fd9SDavid Chisnall _D1 __c2 = 0; 13854bab9fd9SDavid Chisnall for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) 13864bab9fd9SDavid Chisnall if (__pred(*__i, *__j)) 13874bab9fd9SDavid Chisnall ++__c2; 13884bab9fd9SDavid Chisnall if (__c2 == 0) 13894bab9fd9SDavid Chisnall return false; 13904bab9fd9SDavid Chisnall // Count number of *__i in [__i, l1) (we can start with 1) 13914bab9fd9SDavid Chisnall _D1 __c1 = 1; 13924bab9fd9SDavid Chisnall for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) 13934bab9fd9SDavid Chisnall if (__pred(*__i, *__j)) 13944bab9fd9SDavid Chisnall ++__c1; 13954bab9fd9SDavid Chisnall if (__c1 != __c2) 13964bab9fd9SDavid Chisnall return false; 13974bab9fd9SDavid Chisnall } 13984bab9fd9SDavid Chisnall } 13994bab9fd9SDavid Chisnall return true; 14004bab9fd9SDavid Chisnall} 14014bab9fd9SDavid Chisnall 14024bab9fd9SDavid Chisnalltemplate<class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> 14034ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 14044bab9fd9SDavid Chisnall__is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1, 14054bab9fd9SDavid Chisnall _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, 14064bab9fd9SDavid Chisnall _BinaryPredicate __pred, 14074bab9fd9SDavid Chisnall random_access_iterator_tag, random_access_iterator_tag ) 14084bab9fd9SDavid Chisnall{ 14094bab9fd9SDavid Chisnall if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) 14104bab9fd9SDavid Chisnall return false; 14114bab9fd9SDavid Chisnall return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2, 14124bab9fd9SDavid Chisnall typename add_lvalue_reference<_BinaryPredicate>::type> 14134bab9fd9SDavid Chisnall (__first1, __last1, __first2, __pred ); 14144bab9fd9SDavid Chisnall} 14154bab9fd9SDavid Chisnall 14164bab9fd9SDavid Chisnalltemplate<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 14174ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 14184bab9fd9SDavid Chisnallbool 14194bab9fd9SDavid Chisnallis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 14204bab9fd9SDavid Chisnall _ForwardIterator2 __first2, _ForwardIterator2 __last2, 14214bab9fd9SDavid Chisnall _BinaryPredicate __pred ) 14224bab9fd9SDavid Chisnall{ 14234bab9fd9SDavid Chisnall return _VSTD::__is_permutation<typename add_lvalue_reference<_BinaryPredicate>::type> 14244bab9fd9SDavid Chisnall (__first1, __last1, __first2, __last2, __pred, 14254bab9fd9SDavid Chisnall typename iterator_traits<_ForwardIterator1>::iterator_category(), 14264bab9fd9SDavid Chisnall typename iterator_traits<_ForwardIterator2>::iterator_category()); 14274bab9fd9SDavid Chisnall} 14284bab9fd9SDavid Chisnall 14294bab9fd9SDavid Chisnalltemplate<class _ForwardIterator1, class _ForwardIterator2> 14304ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 14314bab9fd9SDavid Chisnallbool 14324bab9fd9SDavid Chisnallis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 14334bab9fd9SDavid Chisnall _ForwardIterator2 __first2, _ForwardIterator2 __last2) 14344bab9fd9SDavid Chisnall{ 14354bab9fd9SDavid Chisnall typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 14364bab9fd9SDavid Chisnall typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 14374bab9fd9SDavid Chisnall return _VSTD::__is_permutation(__first1, __last1, __first2, __last2, 14384bab9fd9SDavid Chisnall __equal_to<__v1, __v2>(), 14394bab9fd9SDavid Chisnall typename iterator_traits<_ForwardIterator1>::iterator_category(), 14404bab9fd9SDavid Chisnall typename iterator_traits<_ForwardIterator2>::iterator_category()); 14414bab9fd9SDavid Chisnall} 14424bab9fd9SDavid Chisnall#endif 14434bab9fd9SDavid Chisnall 14447a984708SDavid Chisnall// search 14454ba319b5SDimitry Andric// __search is in <functional> 14467a984708SDavid Chisnall 14477a984708SDavid Chisnalltemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 14484ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 14497a984708SDavid Chisnall_ForwardIterator1 14507a984708SDavid Chisnallsearch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 14517a984708SDavid Chisnall _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) 14527a984708SDavid Chisnall{ 14537a984708SDavid Chisnall return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type> 14547a984708SDavid Chisnall (__first1, __last1, __first2, __last2, __pred, 14557c82a1ecSDimitry Andric typename iterator_traits<_ForwardIterator1>::iterator_category(), 14567c82a1ecSDimitry Andric typename iterator_traits<_ForwardIterator2>::iterator_category()) 14577c82a1ecSDimitry Andric .first; 14587a984708SDavid Chisnall} 14597a984708SDavid Chisnall 14607a984708SDavid Chisnalltemplate <class _ForwardIterator1, class _ForwardIterator2> 14614ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 14627a984708SDavid Chisnall_ForwardIterator1 14637a984708SDavid Chisnallsearch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 14647a984708SDavid Chisnall _ForwardIterator2 __first2, _ForwardIterator2 __last2) 14657a984708SDavid Chisnall{ 14667c82a1ecSDimitry Andric typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; 14677c82a1ecSDimitry Andric typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; 14687a984708SDavid Chisnall return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); 14697a984708SDavid Chisnall} 14707a984708SDavid Chisnall 14714ba319b5SDimitry Andric 14724ba319b5SDimitry Andric#if _LIBCPP_STD_VER > 14 14734ba319b5SDimitry Andrictemplate <class _ForwardIterator, class _Searcher> 14744ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 14754ba319b5SDimitry Andric_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s) 14764ba319b5SDimitry Andric{ return __s(__f, __l).first; } 14774ba319b5SDimitry Andric#endif 14784ba319b5SDimitry Andric 14797a984708SDavid Chisnall// search_n 14807a984708SDavid Chisnall 14817a984708SDavid Chisnalltemplate <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp> 14824ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 14837a984708SDavid Chisnall__search_n(_ForwardIterator __first, _ForwardIterator __last, 14847a984708SDavid Chisnall _Size __count, const _Tp& __value_, _BinaryPredicate __pred, forward_iterator_tag) 14857a984708SDavid Chisnall{ 14867a984708SDavid Chisnall if (__count <= 0) 14877a984708SDavid Chisnall return __first; 14887a984708SDavid Chisnall while (true) 14897a984708SDavid Chisnall { 14907a984708SDavid Chisnall // Find first element in sequence that matchs __value_, with a mininum of loop checks 14917a984708SDavid Chisnall while (true) 14927a984708SDavid Chisnall { 14937a984708SDavid Chisnall if (__first == __last) // return __last if no element matches __value_ 14947a984708SDavid Chisnall return __last; 14957a984708SDavid Chisnall if (__pred(*__first, __value_)) 14967a984708SDavid Chisnall break; 14977a984708SDavid Chisnall ++__first; 14987a984708SDavid Chisnall } 14997a984708SDavid Chisnall // *__first matches __value_, now match elements after here 15007a984708SDavid Chisnall _ForwardIterator __m = __first; 15017a984708SDavid Chisnall _Size __c(0); 15027a984708SDavid Chisnall while (true) 15037a984708SDavid Chisnall { 15047a984708SDavid Chisnall if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) 15057a984708SDavid Chisnall return __first; 15067a984708SDavid Chisnall if (++__m == __last) // Otherwise if source exhaused, pattern not found 15077a984708SDavid Chisnall return __last; 15087a984708SDavid Chisnall if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first 15097a984708SDavid Chisnall { 15107a984708SDavid Chisnall __first = __m; 15117a984708SDavid Chisnall ++__first; 15127a984708SDavid Chisnall break; 15137a984708SDavid Chisnall } // else there is a match, check next elements 15147a984708SDavid Chisnall } 15157a984708SDavid Chisnall } 15167a984708SDavid Chisnall} 15177a984708SDavid Chisnall 15187a984708SDavid Chisnalltemplate <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp> 15194ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator 15207a984708SDavid Chisnall__search_n(_RandomAccessIterator __first, _RandomAccessIterator __last, 15217a984708SDavid Chisnall _Size __count, const _Tp& __value_, _BinaryPredicate __pred, random_access_iterator_tag) 15227a984708SDavid Chisnall{ 15237a984708SDavid Chisnall if (__count <= 0) 15247a984708SDavid Chisnall return __first; 15257a984708SDavid Chisnall _Size __len = static_cast<_Size>(__last - __first); 15267a984708SDavid Chisnall if (__len < __count) 15277a984708SDavid Chisnall return __last; 15287a984708SDavid Chisnall const _RandomAccessIterator __s = __last - (__count - 1); // Start of pattern match can't go beyond here 15297a984708SDavid Chisnall while (true) 15307a984708SDavid Chisnall { 15317a984708SDavid Chisnall // Find first element in sequence that matchs __value_, with a mininum of loop checks 15327a984708SDavid Chisnall while (true) 15337a984708SDavid Chisnall { 15341bf9f7c1SDimitry Andric if (__first >= __s) // return __last if no element matches __value_ 15357a984708SDavid Chisnall return __last; 15367a984708SDavid Chisnall if (__pred(*__first, __value_)) 15377a984708SDavid Chisnall break; 15387a984708SDavid Chisnall ++__first; 15397a984708SDavid Chisnall } 15407a984708SDavid Chisnall // *__first matches __value_, now match elements after here 15417a984708SDavid Chisnall _RandomAccessIterator __m = __first; 15427a984708SDavid Chisnall _Size __c(0); 15437a984708SDavid Chisnall while (true) 15447a984708SDavid Chisnall { 15457a984708SDavid Chisnall if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) 15467a984708SDavid Chisnall return __first; 15477a984708SDavid Chisnall ++__m; // no need to check range on __m because __s guarantees we have enough source 15487a984708SDavid Chisnall if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first 15497a984708SDavid Chisnall { 15507a984708SDavid Chisnall __first = __m; 15517a984708SDavid Chisnall ++__first; 15527a984708SDavid Chisnall break; 15537a984708SDavid Chisnall } // else there is a match, check next elements 15547a984708SDavid Chisnall } 15557a984708SDavid Chisnall } 15567a984708SDavid Chisnall} 15577a984708SDavid Chisnall 15587a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> 15594ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 15607a984708SDavid Chisnall_ForwardIterator 15617a984708SDavid Chisnallsearch_n(_ForwardIterator __first, _ForwardIterator __last, 15627a984708SDavid Chisnall _Size __count, const _Tp& __value_, _BinaryPredicate __pred) 15637a984708SDavid Chisnall{ 15647a984708SDavid Chisnall return _VSTD::__search_n<typename add_lvalue_reference<_BinaryPredicate>::type> 1565854fa44bSDimitry Andric (__first, __last, __convert_to_integral(__count), __value_, __pred, 1566854fa44bSDimitry Andric typename iterator_traits<_ForwardIterator>::iterator_category()); 15677a984708SDavid Chisnall} 15687a984708SDavid Chisnall 15697a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Size, class _Tp> 15704ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 15717a984708SDavid Chisnall_ForwardIterator 15727a984708SDavid Chisnallsearch_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_) 15737a984708SDavid Chisnall{ 15747a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator>::value_type __v; 1575854fa44bSDimitry Andric return _VSTD::search_n(__first, __last, __convert_to_integral(__count), 1576854fa44bSDimitry Andric __value_, __equal_to<__v, _Tp>()); 15777a984708SDavid Chisnall} 15787a984708SDavid Chisnall 15797a984708SDavid Chisnall// copy 15807a984708SDavid Chisnalltemplate <class _Iter> 15817a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 15827a984708SDavid Chisnall_Iter 15837a984708SDavid Chisnall__unwrap_iter(_Iter __i) 15847a984708SDavid Chisnall{ 15857a984708SDavid Chisnall return __i; 15867a984708SDavid Chisnall} 15877a984708SDavid Chisnall 15887a984708SDavid Chisnalltemplate <class _Tp> 15897a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 15907a984708SDavid Chisnalltypename enable_if 15917a984708SDavid Chisnall< 15927a984708SDavid Chisnall is_trivially_copy_assignable<_Tp>::value, 15937a984708SDavid Chisnall _Tp* 15947a984708SDavid Chisnall>::type 15957a984708SDavid Chisnall__unwrap_iter(move_iterator<_Tp*> __i) 15967a984708SDavid Chisnall{ 15977a984708SDavid Chisnall return __i.base(); 15987a984708SDavid Chisnall} 15997a984708SDavid Chisnall 16004f7ab58eSDimitry Andric#if _LIBCPP_DEBUG_LEVEL < 2 16014f7ab58eSDimitry Andric 16027a984708SDavid Chisnalltemplate <class _Tp> 16034ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 16047a984708SDavid Chisnalltypename enable_if 16057a984708SDavid Chisnall< 16067a984708SDavid Chisnall is_trivially_copy_assignable<_Tp>::value, 16077a984708SDavid Chisnall _Tp* 16087a984708SDavid Chisnall>::type 16097a984708SDavid Chisnall__unwrap_iter(__wrap_iter<_Tp*> __i) 16107a984708SDavid Chisnall{ 16117a984708SDavid Chisnall return __i.base(); 16127a984708SDavid Chisnall} 16137a984708SDavid Chisnall 1614aed8d94eSDimitry Andric#else 1615aed8d94eSDimitry Andric 1616aed8d94eSDimitry Andrictemplate <class _Tp> 16174ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 1618aed8d94eSDimitry Andrictypename enable_if 1619aed8d94eSDimitry Andric< 1620aed8d94eSDimitry Andric is_trivially_copy_assignable<_Tp>::value, 1621aed8d94eSDimitry Andric __wrap_iter<_Tp*> 1622aed8d94eSDimitry Andric>::type 1623aed8d94eSDimitry Andric__unwrap_iter(__wrap_iter<_Tp*> __i) 1624aed8d94eSDimitry Andric{ 1625aed8d94eSDimitry Andric return __i; 1626aed8d94eSDimitry Andric} 1627aed8d94eSDimitry Andric 16284f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG_LEVEL < 2 16294f7ab58eSDimitry Andric 16307a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator> 16317a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 16327a984708SDavid Chisnall_OutputIterator 16337a984708SDavid Chisnall__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 16347a984708SDavid Chisnall{ 1635d72607e9SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 16367a984708SDavid Chisnall *__result = *__first; 16377a984708SDavid Chisnall return __result; 16387a984708SDavid Chisnall} 16397a984708SDavid Chisnall 16407a984708SDavid Chisnalltemplate <class _Tp, class _Up> 16417a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 16427a984708SDavid Chisnalltypename enable_if 16437a984708SDavid Chisnall< 16447a984708SDavid Chisnall is_same<typename remove_const<_Tp>::type, _Up>::value && 16457a984708SDavid Chisnall is_trivially_copy_assignable<_Up>::value, 16467a984708SDavid Chisnall _Up* 16477a984708SDavid Chisnall>::type 16487a984708SDavid Chisnall__copy(_Tp* __first, _Tp* __last, _Up* __result) 16497a984708SDavid Chisnall{ 16507a984708SDavid Chisnall const size_t __n = static_cast<size_t>(__last - __first); 1651854fa44bSDimitry Andric if (__n > 0) 16527a984708SDavid Chisnall _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 16537a984708SDavid Chisnall return __result + __n; 16547a984708SDavid Chisnall} 16557a984708SDavid Chisnall 16567a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator> 16577a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 16587a984708SDavid Chisnall_OutputIterator 16597a984708SDavid Chisnallcopy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 16607a984708SDavid Chisnall{ 16617a984708SDavid Chisnall return _VSTD::__copy(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); 16627a984708SDavid Chisnall} 16637a984708SDavid Chisnall 16647a984708SDavid Chisnall// copy_backward 16657a984708SDavid Chisnall 1666cfdf2879SDavid Chisnalltemplate <class _BidirectionalIterator, class _OutputIterator> 16677a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 16687a984708SDavid Chisnall_OutputIterator 1669cfdf2879SDavid Chisnall__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 16707a984708SDavid Chisnall{ 16717a984708SDavid Chisnall while (__first != __last) 16727a984708SDavid Chisnall *--__result = *--__last; 16737a984708SDavid Chisnall return __result; 16747a984708SDavid Chisnall} 16757a984708SDavid Chisnall 16767a984708SDavid Chisnalltemplate <class _Tp, class _Up> 16777a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 16787a984708SDavid Chisnalltypename enable_if 16797a984708SDavid Chisnall< 16807a984708SDavid Chisnall is_same<typename remove_const<_Tp>::type, _Up>::value && 16817a984708SDavid Chisnall is_trivially_copy_assignable<_Up>::value, 16827a984708SDavid Chisnall _Up* 16837a984708SDavid Chisnall>::type 16847a984708SDavid Chisnall__copy_backward(_Tp* __first, _Tp* __last, _Up* __result) 16857a984708SDavid Chisnall{ 16867a984708SDavid Chisnall const size_t __n = static_cast<size_t>(__last - __first); 1687854fa44bSDimitry Andric if (__n > 0) 1688854fa44bSDimitry Andric { 16897a984708SDavid Chisnall __result -= __n; 16907a984708SDavid Chisnall _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 1691854fa44bSDimitry Andric } 16927a984708SDavid Chisnall return __result; 16937a984708SDavid Chisnall} 16947a984708SDavid Chisnall 16957a984708SDavid Chisnalltemplate <class _BidirectionalIterator1, class _BidirectionalIterator2> 16967a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 16977a984708SDavid Chisnall_BidirectionalIterator2 16987a984708SDavid Chisnallcopy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, 16997a984708SDavid Chisnall _BidirectionalIterator2 __result) 17007a984708SDavid Chisnall{ 1701aed8d94eSDimitry Andric return _VSTD::__copy_backward(__unwrap_iter(__first), 1702aed8d94eSDimitry Andric __unwrap_iter(__last), 1703aed8d94eSDimitry Andric __unwrap_iter(__result)); 17047a984708SDavid Chisnall} 17057a984708SDavid Chisnall 17067a984708SDavid Chisnall// copy_if 17077a984708SDavid Chisnall 17087a984708SDavid Chisnalltemplate<class _InputIterator, class _OutputIterator, class _Predicate> 17097a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 17107a984708SDavid Chisnall_OutputIterator 17117a984708SDavid Chisnallcopy_if(_InputIterator __first, _InputIterator __last, 17127a984708SDavid Chisnall _OutputIterator __result, _Predicate __pred) 17137a984708SDavid Chisnall{ 17147a984708SDavid Chisnall for (; __first != __last; ++__first) 17157a984708SDavid Chisnall { 17167a984708SDavid Chisnall if (__pred(*__first)) 17177a984708SDavid Chisnall { 17187a984708SDavid Chisnall *__result = *__first; 17197a984708SDavid Chisnall ++__result; 17207a984708SDavid Chisnall } 17217a984708SDavid Chisnall } 17227a984708SDavid Chisnall return __result; 17237a984708SDavid Chisnall} 17247a984708SDavid Chisnall 17257a984708SDavid Chisnall// copy_n 17267a984708SDavid Chisnall 17277a984708SDavid Chisnalltemplate<class _InputIterator, class _Size, class _OutputIterator> 17287a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 17297a984708SDavid Chisnalltypename enable_if 17307a984708SDavid Chisnall< 17317a984708SDavid Chisnall __is_input_iterator<_InputIterator>::value && 17327a984708SDavid Chisnall !__is_random_access_iterator<_InputIterator>::value, 17337a984708SDavid Chisnall _OutputIterator 17347a984708SDavid Chisnall>::type 1735854fa44bSDimitry Andriccopy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) 17367a984708SDavid Chisnall{ 1737854fa44bSDimitry Andric typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; 1738854fa44bSDimitry Andric _IntegralSize __n = __orig_n; 17397a984708SDavid Chisnall if (__n > 0) 17407a984708SDavid Chisnall { 17417a984708SDavid Chisnall *__result = *__first; 17427a984708SDavid Chisnall ++__result; 17437a984708SDavid Chisnall for (--__n; __n > 0; --__n) 17447a984708SDavid Chisnall { 17457a984708SDavid Chisnall ++__first; 17467a984708SDavid Chisnall *__result = *__first; 17477a984708SDavid Chisnall ++__result; 17487a984708SDavid Chisnall } 17497a984708SDavid Chisnall } 17507a984708SDavid Chisnall return __result; 17517a984708SDavid Chisnall} 17527a984708SDavid Chisnall 17537a984708SDavid Chisnalltemplate<class _InputIterator, class _Size, class _OutputIterator> 17547a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 17557a984708SDavid Chisnalltypename enable_if 17567a984708SDavid Chisnall< 17577a984708SDavid Chisnall __is_random_access_iterator<_InputIterator>::value, 17587a984708SDavid Chisnall _OutputIterator 17597a984708SDavid Chisnall>::type 1760854fa44bSDimitry Andriccopy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) 17617a984708SDavid Chisnall{ 1762854fa44bSDimitry Andric typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; 1763854fa44bSDimitry Andric _IntegralSize __n = __orig_n; 17647a984708SDavid Chisnall return _VSTD::copy(__first, __first + __n, __result); 17657a984708SDavid Chisnall} 17667a984708SDavid Chisnall 17677a984708SDavid Chisnall// move 17687a984708SDavid Chisnall 17697a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator> 17707a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 17717a984708SDavid Chisnall_OutputIterator 17727a984708SDavid Chisnall__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 17737a984708SDavid Chisnall{ 1774d72607e9SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 17757a984708SDavid Chisnall *__result = _VSTD::move(*__first); 17767a984708SDavid Chisnall return __result; 17777a984708SDavid Chisnall} 17787a984708SDavid Chisnall 17797a984708SDavid Chisnalltemplate <class _Tp, class _Up> 17807a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 17817a984708SDavid Chisnalltypename enable_if 17827a984708SDavid Chisnall< 17837a984708SDavid Chisnall is_same<typename remove_const<_Tp>::type, _Up>::value && 17847a984708SDavid Chisnall is_trivially_copy_assignable<_Up>::value, 17857a984708SDavid Chisnall _Up* 17867a984708SDavid Chisnall>::type 17877a984708SDavid Chisnall__move(_Tp* __first, _Tp* __last, _Up* __result) 17887a984708SDavid Chisnall{ 17897a984708SDavid Chisnall const size_t __n = static_cast<size_t>(__last - __first); 1790854fa44bSDimitry Andric if (__n > 0) 17917a984708SDavid Chisnall _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 17927a984708SDavid Chisnall return __result + __n; 17937a984708SDavid Chisnall} 17947a984708SDavid Chisnall 17957a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator> 17967a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 17977a984708SDavid Chisnall_OutputIterator 17987a984708SDavid Chisnallmove(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 17997a984708SDavid Chisnall{ 18007a984708SDavid Chisnall return _VSTD::__move(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); 18017a984708SDavid Chisnall} 18027a984708SDavid Chisnall 18037a984708SDavid Chisnall// move_backward 18047a984708SDavid Chisnall 18057a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator> 18067a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 18077a984708SDavid Chisnall_OutputIterator 18087a984708SDavid Chisnall__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 18097a984708SDavid Chisnall{ 18107a984708SDavid Chisnall while (__first != __last) 18117a984708SDavid Chisnall *--__result = _VSTD::move(*--__last); 18127a984708SDavid Chisnall return __result; 18137a984708SDavid Chisnall} 18147a984708SDavid Chisnall 18157a984708SDavid Chisnalltemplate <class _Tp, class _Up> 18167a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 18177a984708SDavid Chisnalltypename enable_if 18187a984708SDavid Chisnall< 18197a984708SDavid Chisnall is_same<typename remove_const<_Tp>::type, _Up>::value && 18207a984708SDavid Chisnall is_trivially_copy_assignable<_Up>::value, 18217a984708SDavid Chisnall _Up* 18227a984708SDavid Chisnall>::type 18237a984708SDavid Chisnall__move_backward(_Tp* __first, _Tp* __last, _Up* __result) 18247a984708SDavid Chisnall{ 18257a984708SDavid Chisnall const size_t __n = static_cast<size_t>(__last - __first); 1826854fa44bSDimitry Andric if (__n > 0) 1827854fa44bSDimitry Andric { 18287a984708SDavid Chisnall __result -= __n; 18297a984708SDavid Chisnall _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 1830854fa44bSDimitry Andric } 18317a984708SDavid Chisnall return __result; 18327a984708SDavid Chisnall} 18337a984708SDavid Chisnall 18347a984708SDavid Chisnalltemplate <class _BidirectionalIterator1, class _BidirectionalIterator2> 18357a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 18367a984708SDavid Chisnall_BidirectionalIterator2 18377a984708SDavid Chisnallmove_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, 18387a984708SDavid Chisnall _BidirectionalIterator2 __result) 18397a984708SDavid Chisnall{ 18407a984708SDavid Chisnall return _VSTD::__move_backward(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); 18417a984708SDavid Chisnall} 18427a984708SDavid Chisnall 18437a984708SDavid Chisnall// iter_swap 18447a984708SDavid Chisnall 18457a984708SDavid Chisnall// moved to <type_traits> for better swap / noexcept support 18467a984708SDavid Chisnall 18477a984708SDavid Chisnall// transform 18487a984708SDavid Chisnall 18497a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator, class _UnaryOperation> 18504ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 18517a984708SDavid Chisnall_OutputIterator 18527a984708SDavid Chisnalltransform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) 18537a984708SDavid Chisnall{ 1854d72607e9SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 18557a984708SDavid Chisnall *__result = __op(*__first); 18567a984708SDavid Chisnall return __result; 18577a984708SDavid Chisnall} 18587a984708SDavid Chisnall 18597a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation> 18604ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 18617a984708SDavid Chisnall_OutputIterator 18627a984708SDavid Chisnalltransform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, 18637a984708SDavid Chisnall _OutputIterator __result, _BinaryOperation __binary_op) 18647a984708SDavid Chisnall{ 1865d72607e9SDimitry Andric for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result) 18667a984708SDavid Chisnall *__result = __binary_op(*__first1, *__first2); 18677a984708SDavid Chisnall return __result; 18687a984708SDavid Chisnall} 18697a984708SDavid Chisnall 18707a984708SDavid Chisnall// replace 18717a984708SDavid Chisnall 18727a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp> 18734ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 18747a984708SDavid Chisnallvoid 18757a984708SDavid Chisnallreplace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) 18767a984708SDavid Chisnall{ 18777a984708SDavid Chisnall for (; __first != __last; ++__first) 18787a984708SDavid Chisnall if (*__first == __old_value) 18797a984708SDavid Chisnall *__first = __new_value; 18807a984708SDavid Chisnall} 18817a984708SDavid Chisnall 18827a984708SDavid Chisnall// replace_if 18837a984708SDavid Chisnall 18847a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Predicate, class _Tp> 18854ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 18867a984708SDavid Chisnallvoid 18877a984708SDavid Chisnallreplace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) 18887a984708SDavid Chisnall{ 18897a984708SDavid Chisnall for (; __first != __last; ++__first) 18907a984708SDavid Chisnall if (__pred(*__first)) 18917a984708SDavid Chisnall *__first = __new_value; 18927a984708SDavid Chisnall} 18937a984708SDavid Chisnall 18947a984708SDavid Chisnall// replace_copy 18957a984708SDavid Chisnall 18967a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator, class _Tp> 18974ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 18987a984708SDavid Chisnall_OutputIterator 18997a984708SDavid Chisnallreplace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, 19007a984708SDavid Chisnall const _Tp& __old_value, const _Tp& __new_value) 19017a984708SDavid Chisnall{ 1902d72607e9SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 19037a984708SDavid Chisnall if (*__first == __old_value) 19047a984708SDavid Chisnall *__result = __new_value; 19057a984708SDavid Chisnall else 19067a984708SDavid Chisnall *__result = *__first; 19077a984708SDavid Chisnall return __result; 19087a984708SDavid Chisnall} 19097a984708SDavid Chisnall 19107a984708SDavid Chisnall// replace_copy_if 19117a984708SDavid Chisnall 19127a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp> 19134ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19147a984708SDavid Chisnall_OutputIterator 19157a984708SDavid Chisnallreplace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, 19167a984708SDavid Chisnall _Predicate __pred, const _Tp& __new_value) 19177a984708SDavid Chisnall{ 1918d72607e9SDimitry Andric for (; __first != __last; ++__first, (void) ++__result) 19197a984708SDavid Chisnall if (__pred(*__first)) 19207a984708SDavid Chisnall *__result = __new_value; 19217a984708SDavid Chisnall else 19227a984708SDavid Chisnall *__result = *__first; 19237a984708SDavid Chisnall return __result; 19247a984708SDavid Chisnall} 19257a984708SDavid Chisnall 19267a984708SDavid Chisnall// fill_n 19277a984708SDavid Chisnall 19287a984708SDavid Chisnalltemplate <class _OutputIterator, class _Size, class _Tp> 19294ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19307a984708SDavid Chisnall_OutputIterator 19314f7ab58eSDimitry Andric__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) 19327a984708SDavid Chisnall{ 1933d72607e9SDimitry Andric for (; __n > 0; ++__first, (void) --__n) 19347a984708SDavid Chisnall *__first = __value_; 19357a984708SDavid Chisnall return __first; 19367a984708SDavid Chisnall} 19377a984708SDavid Chisnall 19387a984708SDavid Chisnalltemplate <class _OutputIterator, class _Size, class _Tp> 19394ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19407a984708SDavid Chisnall_OutputIterator 19417a984708SDavid Chisnallfill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) 19427a984708SDavid Chisnall{ 1943854fa44bSDimitry Andric return _VSTD::__fill_n(__first, __convert_to_integral(__n), __value_); 19447a984708SDavid Chisnall} 19457a984708SDavid Chisnall 19467a984708SDavid Chisnall// fill 19477a984708SDavid Chisnall 19487a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp> 19494ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19507a984708SDavid Chisnallvoid 19517a984708SDavid Chisnall__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag) 19527a984708SDavid Chisnall{ 19537a984708SDavid Chisnall for (; __first != __last; ++__first) 19547a984708SDavid Chisnall *__first = __value_; 19557a984708SDavid Chisnall} 19567a984708SDavid Chisnall 19577a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _Tp> 19584ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19597a984708SDavid Chisnallvoid 19607a984708SDavid Chisnall__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag) 19617a984708SDavid Chisnall{ 19627a984708SDavid Chisnall _VSTD::fill_n(__first, __last - __first, __value_); 19637a984708SDavid Chisnall} 19647a984708SDavid Chisnall 19657a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp> 19664ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19677a984708SDavid Chisnallvoid 19687a984708SDavid Chisnallfill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 19697a984708SDavid Chisnall{ 19707a984708SDavid Chisnall _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category()); 19717a984708SDavid Chisnall} 19727a984708SDavid Chisnall 19737a984708SDavid Chisnall// generate 19747a984708SDavid Chisnall 19757a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Generator> 19764ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19777a984708SDavid Chisnallvoid 19787a984708SDavid Chisnallgenerate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) 19797a984708SDavid Chisnall{ 19807a984708SDavid Chisnall for (; __first != __last; ++__first) 19817a984708SDavid Chisnall *__first = __gen(); 19827a984708SDavid Chisnall} 19837a984708SDavid Chisnall 19847a984708SDavid Chisnall// generate_n 19857a984708SDavid Chisnall 19867a984708SDavid Chisnalltemplate <class _OutputIterator, class _Size, class _Generator> 19874ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 19887a984708SDavid Chisnall_OutputIterator 1989854fa44bSDimitry Andricgenerate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) 19907a984708SDavid Chisnall{ 1991854fa44bSDimitry Andric typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; 1992854fa44bSDimitry Andric _IntegralSize __n = __orig_n; 1993d72607e9SDimitry Andric for (; __n > 0; ++__first, (void) --__n) 19947a984708SDavid Chisnall *__first = __gen(); 19957a984708SDavid Chisnall return __first; 19967a984708SDavid Chisnall} 19977a984708SDavid Chisnall 19987a984708SDavid Chisnall// remove 19997a984708SDavid Chisnall 20007a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp> 20014ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 20027a984708SDavid Chisnallremove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 20037a984708SDavid Chisnall{ 20047a984708SDavid Chisnall __first = _VSTD::find(__first, __last, __value_); 20057a984708SDavid Chisnall if (__first != __last) 20067a984708SDavid Chisnall { 20077a984708SDavid Chisnall _ForwardIterator __i = __first; 20087a984708SDavid Chisnall while (++__i != __last) 20097a984708SDavid Chisnall { 20107a984708SDavid Chisnall if (!(*__i == __value_)) 20117a984708SDavid Chisnall { 20127a984708SDavid Chisnall *__first = _VSTD::move(*__i); 20137a984708SDavid Chisnall ++__first; 20147a984708SDavid Chisnall } 20157a984708SDavid Chisnall } 20167a984708SDavid Chisnall } 20177a984708SDavid Chisnall return __first; 20187a984708SDavid Chisnall} 20197a984708SDavid Chisnall 20207a984708SDavid Chisnall// remove_if 20217a984708SDavid Chisnall 20227a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Predicate> 20234ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 20247a984708SDavid Chisnallremove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 20257a984708SDavid Chisnall{ 20267a984708SDavid Chisnall __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type> 20277a984708SDavid Chisnall (__first, __last, __pred); 20287a984708SDavid Chisnall if (__first != __last) 20297a984708SDavid Chisnall { 20307a984708SDavid Chisnall _ForwardIterator __i = __first; 20317a984708SDavid Chisnall while (++__i != __last) 20327a984708SDavid Chisnall { 20337a984708SDavid Chisnall if (!__pred(*__i)) 20347a984708SDavid Chisnall { 20357a984708SDavid Chisnall *__first = _VSTD::move(*__i); 20367a984708SDavid Chisnall ++__first; 20377a984708SDavid Chisnall } 20387a984708SDavid Chisnall } 20397a984708SDavid Chisnall } 20407a984708SDavid Chisnall return __first; 20417a984708SDavid Chisnall} 20427a984708SDavid Chisnall 20437a984708SDavid Chisnall// remove_copy 20447a984708SDavid Chisnall 20457a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator, class _Tp> 20464ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 20477a984708SDavid Chisnall_OutputIterator 20487a984708SDavid Chisnallremove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_) 20497a984708SDavid Chisnall{ 20507a984708SDavid Chisnall for (; __first != __last; ++__first) 20517a984708SDavid Chisnall { 20527a984708SDavid Chisnall if (!(*__first == __value_)) 20537a984708SDavid Chisnall { 20547a984708SDavid Chisnall *__result = *__first; 20557a984708SDavid Chisnall ++__result; 20567a984708SDavid Chisnall } 20577a984708SDavid Chisnall } 20587a984708SDavid Chisnall return __result; 20597a984708SDavid Chisnall} 20607a984708SDavid Chisnall 20617a984708SDavid Chisnall// remove_copy_if 20627a984708SDavid Chisnall 20637a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator, class _Predicate> 20644ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 20657a984708SDavid Chisnall_OutputIterator 20667a984708SDavid Chisnallremove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) 20677a984708SDavid Chisnall{ 20687a984708SDavid Chisnall for (; __first != __last; ++__first) 20697a984708SDavid Chisnall { 20707a984708SDavid Chisnall if (!__pred(*__first)) 20717a984708SDavid Chisnall { 20727a984708SDavid Chisnall *__result = *__first; 20737a984708SDavid Chisnall ++__result; 20747a984708SDavid Chisnall } 20757a984708SDavid Chisnall } 20767a984708SDavid Chisnall return __result; 20777a984708SDavid Chisnall} 20787a984708SDavid Chisnall 20797a984708SDavid Chisnall// unique 20807a984708SDavid Chisnall 20817a984708SDavid Chisnalltemplate <class _ForwardIterator, class _BinaryPredicate> 20824ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 20837a984708SDavid Chisnallunique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) 20847a984708SDavid Chisnall{ 20857a984708SDavid Chisnall __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type> 20867a984708SDavid Chisnall (__first, __last, __pred); 20877a984708SDavid Chisnall if (__first != __last) 20887a984708SDavid Chisnall { 20897a984708SDavid Chisnall // ... a a ? ... 20907a984708SDavid Chisnall // f i 20917a984708SDavid Chisnall _ForwardIterator __i = __first; 20927a984708SDavid Chisnall for (++__i; ++__i != __last;) 20937a984708SDavid Chisnall if (!__pred(*__first, *__i)) 20947a984708SDavid Chisnall *++__first = _VSTD::move(*__i); 20957a984708SDavid Chisnall ++__first; 20967a984708SDavid Chisnall } 20977a984708SDavid Chisnall return __first; 20987a984708SDavid Chisnall} 20997a984708SDavid Chisnall 21007a984708SDavid Chisnalltemplate <class _ForwardIterator> 21014ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 21027a984708SDavid Chisnall_ForwardIterator 21037a984708SDavid Chisnallunique(_ForwardIterator __first, _ForwardIterator __last) 21047a984708SDavid Chisnall{ 21057a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator>::value_type __v; 21067a984708SDavid Chisnall return _VSTD::unique(__first, __last, __equal_to<__v>()); 21077a984708SDavid Chisnall} 21087a984708SDavid Chisnall 21097a984708SDavid Chisnall// unique_copy 21107a984708SDavid Chisnall 21117a984708SDavid Chisnalltemplate <class _BinaryPredicate, class _InputIterator, class _OutputIterator> 21124ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 21137a984708SDavid Chisnall__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred, 21147a984708SDavid Chisnall input_iterator_tag, output_iterator_tag) 21157a984708SDavid Chisnall{ 21167a984708SDavid Chisnall if (__first != __last) 21177a984708SDavid Chisnall { 21187a984708SDavid Chisnall typename iterator_traits<_InputIterator>::value_type __t(*__first); 21197a984708SDavid Chisnall *__result = __t; 21207a984708SDavid Chisnall ++__result; 21217a984708SDavid Chisnall while (++__first != __last) 21227a984708SDavid Chisnall { 21237a984708SDavid Chisnall if (!__pred(__t, *__first)) 21247a984708SDavid Chisnall { 21257a984708SDavid Chisnall __t = *__first; 21267a984708SDavid Chisnall *__result = __t; 21277a984708SDavid Chisnall ++__result; 21287a984708SDavid Chisnall } 21297a984708SDavid Chisnall } 21307a984708SDavid Chisnall } 21317a984708SDavid Chisnall return __result; 21327a984708SDavid Chisnall} 21337a984708SDavid Chisnall 21347a984708SDavid Chisnalltemplate <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator> 21354ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 21367a984708SDavid Chisnall__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred, 21377a984708SDavid Chisnall forward_iterator_tag, output_iterator_tag) 21387a984708SDavid Chisnall{ 21397a984708SDavid Chisnall if (__first != __last) 21407a984708SDavid Chisnall { 21417a984708SDavid Chisnall _ForwardIterator __i = __first; 21427a984708SDavid Chisnall *__result = *__i; 21437a984708SDavid Chisnall ++__result; 21447a984708SDavid Chisnall while (++__first != __last) 21457a984708SDavid Chisnall { 21467a984708SDavid Chisnall if (!__pred(*__i, *__first)) 21477a984708SDavid Chisnall { 21487a984708SDavid Chisnall *__result = *__first; 21497a984708SDavid Chisnall ++__result; 21507a984708SDavid Chisnall __i = __first; 21517a984708SDavid Chisnall } 21527a984708SDavid Chisnall } 21537a984708SDavid Chisnall } 21547a984708SDavid Chisnall return __result; 21557a984708SDavid Chisnall} 21567a984708SDavid Chisnall 21577a984708SDavid Chisnalltemplate <class _BinaryPredicate, class _InputIterator, class _ForwardIterator> 21584ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 21597a984708SDavid Chisnall__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred, 21607a984708SDavid Chisnall input_iterator_tag, forward_iterator_tag) 21617a984708SDavid Chisnall{ 21627a984708SDavid Chisnall if (__first != __last) 21637a984708SDavid Chisnall { 21647a984708SDavid Chisnall *__result = *__first; 21657a984708SDavid Chisnall while (++__first != __last) 21667a984708SDavid Chisnall if (!__pred(*__result, *__first)) 21677a984708SDavid Chisnall *++__result = *__first; 21687a984708SDavid Chisnall ++__result; 21697a984708SDavid Chisnall } 21707a984708SDavid Chisnall return __result; 21717a984708SDavid Chisnall} 21727a984708SDavid Chisnall 21737a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator, class _BinaryPredicate> 21744ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 21757a984708SDavid Chisnall_OutputIterator 21767a984708SDavid Chisnallunique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) 21777a984708SDavid Chisnall{ 21787a984708SDavid Chisnall return _VSTD::__unique_copy<typename add_lvalue_reference<_BinaryPredicate>::type> 21797a984708SDavid Chisnall (__first, __last, __result, __pred, 21807a984708SDavid Chisnall typename iterator_traits<_InputIterator>::iterator_category(), 21817a984708SDavid Chisnall typename iterator_traits<_OutputIterator>::iterator_category()); 21827a984708SDavid Chisnall} 21837a984708SDavid Chisnall 21847a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator> 21854ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 21867a984708SDavid Chisnall_OutputIterator 21877a984708SDavid Chisnallunique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 21887a984708SDavid Chisnall{ 21897a984708SDavid Chisnall typedef typename iterator_traits<_InputIterator>::value_type __v; 21907a984708SDavid Chisnall return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>()); 21917a984708SDavid Chisnall} 21927a984708SDavid Chisnall 21937a984708SDavid Chisnall// reverse 21947a984708SDavid Chisnall 21957a984708SDavid Chisnalltemplate <class _BidirectionalIterator> 21967a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 21977a984708SDavid Chisnallvoid 21987a984708SDavid Chisnall__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) 21997a984708SDavid Chisnall{ 22007a984708SDavid Chisnall while (__first != __last) 22017a984708SDavid Chisnall { 22027a984708SDavid Chisnall if (__first == --__last) 22037a984708SDavid Chisnall break; 22049729cf09SDimitry Andric _VSTD::iter_swap(__first, __last); 22057a984708SDavid Chisnall ++__first; 22067a984708SDavid Chisnall } 22077a984708SDavid Chisnall} 22087a984708SDavid Chisnall 22097a984708SDavid Chisnalltemplate <class _RandomAccessIterator> 22107a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 22117a984708SDavid Chisnallvoid 22127a984708SDavid Chisnall__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) 22137a984708SDavid Chisnall{ 22147a984708SDavid Chisnall if (__first != __last) 22157a984708SDavid Chisnall for (; __first < --__last; ++__first) 22169729cf09SDimitry Andric _VSTD::iter_swap(__first, __last); 22177a984708SDavid Chisnall} 22187a984708SDavid Chisnall 22197a984708SDavid Chisnalltemplate <class _BidirectionalIterator> 22207a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 22217a984708SDavid Chisnallvoid 22227a984708SDavid Chisnallreverse(_BidirectionalIterator __first, _BidirectionalIterator __last) 22237a984708SDavid Chisnall{ 22247a984708SDavid Chisnall _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category()); 22257a984708SDavid Chisnall} 22267a984708SDavid Chisnall 22277a984708SDavid Chisnall// reverse_copy 22287a984708SDavid Chisnall 22297a984708SDavid Chisnalltemplate <class _BidirectionalIterator, class _OutputIterator> 22304ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 22317a984708SDavid Chisnall_OutputIterator 22327a984708SDavid Chisnallreverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 22337a984708SDavid Chisnall{ 22347a984708SDavid Chisnall for (; __first != __last; ++__result) 22357a984708SDavid Chisnall *__result = *--__last; 22367a984708SDavid Chisnall return __result; 22377a984708SDavid Chisnall} 22387a984708SDavid Chisnall 22397a984708SDavid Chisnall// rotate 22407a984708SDavid Chisnall 22417a984708SDavid Chisnalltemplate <class _ForwardIterator> 22427a984708SDavid Chisnall_ForwardIterator 2243936e9439SDimitry Andric__rotate_left(_ForwardIterator __first, _ForwardIterator __last) 22447a984708SDavid Chisnall{ 2245936e9439SDimitry Andric typedef typename iterator_traits<_ForwardIterator>::value_type value_type; 2246936e9439SDimitry Andric value_type __tmp = _VSTD::move(*__first); 2247936e9439SDimitry Andric _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first); 2248936e9439SDimitry Andric *__lm1 = _VSTD::move(__tmp); 2249936e9439SDimitry Andric return __lm1; 2250936e9439SDimitry Andric} 2251936e9439SDimitry Andric 2252936e9439SDimitry Andrictemplate <class _BidirectionalIterator> 2253936e9439SDimitry Andric_BidirectionalIterator 2254936e9439SDimitry Andric__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) 2255936e9439SDimitry Andric{ 2256936e9439SDimitry Andric typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 2257936e9439SDimitry Andric _BidirectionalIterator __lm1 = _VSTD::prev(__last); 2258936e9439SDimitry Andric value_type __tmp = _VSTD::move(*__lm1); 2259936e9439SDimitry Andric _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last); 2260936e9439SDimitry Andric *__first = _VSTD::move(__tmp); 2261936e9439SDimitry Andric return __fp1; 2262936e9439SDimitry Andric} 2263936e9439SDimitry Andric 2264936e9439SDimitry Andrictemplate <class _ForwardIterator> 2265936e9439SDimitry Andric_ForwardIterator 2266936e9439SDimitry Andric__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) 2267936e9439SDimitry Andric{ 22687a984708SDavid Chisnall _ForwardIterator __i = __middle; 22697a984708SDavid Chisnall while (true) 22707a984708SDavid Chisnall { 22717a984708SDavid Chisnall swap(*__first, *__i); 22727a984708SDavid Chisnall ++__first; 22737a984708SDavid Chisnall if (++__i == __last) 22747a984708SDavid Chisnall break; 22757a984708SDavid Chisnall if (__first == __middle) 22767a984708SDavid Chisnall __middle = __i; 22777a984708SDavid Chisnall } 22787a984708SDavid Chisnall _ForwardIterator __r = __first; 22797a984708SDavid Chisnall if (__first != __middle) 22807a984708SDavid Chisnall { 22817a984708SDavid Chisnall __i = __middle; 22827a984708SDavid Chisnall while (true) 22837a984708SDavid Chisnall { 22847a984708SDavid Chisnall swap(*__first, *__i); 22857a984708SDavid Chisnall ++__first; 22867a984708SDavid Chisnall if (++__i == __last) 22877a984708SDavid Chisnall { 22887a984708SDavid Chisnall if (__first == __middle) 22897a984708SDavid Chisnall break; 22907a984708SDavid Chisnall __i = __middle; 22917a984708SDavid Chisnall } 22927a984708SDavid Chisnall else if (__first == __middle) 22937a984708SDavid Chisnall __middle = __i; 22947a984708SDavid Chisnall } 22957a984708SDavid Chisnall } 22967a984708SDavid Chisnall return __r; 22977a984708SDavid Chisnall} 22987a984708SDavid Chisnall 22997a984708SDavid Chisnalltemplate<typename _Integral> 23007a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 23017a984708SDavid Chisnall_Integral 2302aed8d94eSDimitry Andric__algo_gcd(_Integral __x, _Integral __y) 23037a984708SDavid Chisnall{ 23047a984708SDavid Chisnall do 23057a984708SDavid Chisnall { 23067a984708SDavid Chisnall _Integral __t = __x % __y; 23077a984708SDavid Chisnall __x = __y; 23087a984708SDavid Chisnall __y = __t; 23097a984708SDavid Chisnall } while (__y); 23107a984708SDavid Chisnall return __x; 23117a984708SDavid Chisnall} 23127a984708SDavid Chisnall 23137a984708SDavid Chisnalltemplate<typename _RandomAccessIterator> 23147a984708SDavid Chisnall_RandomAccessIterator 2315936e9439SDimitry Andric__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) 23167a984708SDavid Chisnall{ 23177a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 23187a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 23197a984708SDavid Chisnall 23207a984708SDavid Chisnall const difference_type __m1 = __middle - __first; 23217a984708SDavid Chisnall const difference_type __m2 = __last - __middle; 23227a984708SDavid Chisnall if (__m1 == __m2) 23237a984708SDavid Chisnall { 23247a984708SDavid Chisnall _VSTD::swap_ranges(__first, __middle, __middle); 23257a984708SDavid Chisnall return __middle; 23267a984708SDavid Chisnall } 2327aed8d94eSDimitry Andric const difference_type __g = _VSTD::__algo_gcd(__m1, __m2); 23287a984708SDavid Chisnall for (_RandomAccessIterator __p = __first + __g; __p != __first;) 23297a984708SDavid Chisnall { 2330936e9439SDimitry Andric value_type __t(_VSTD::move(*--__p)); 23317a984708SDavid Chisnall _RandomAccessIterator __p1 = __p; 23327a984708SDavid Chisnall _RandomAccessIterator __p2 = __p1 + __m1; 23337a984708SDavid Chisnall do 23347a984708SDavid Chisnall { 2335936e9439SDimitry Andric *__p1 = _VSTD::move(*__p2); 23367a984708SDavid Chisnall __p1 = __p2; 23377a984708SDavid Chisnall const difference_type __d = __last - __p2; 23387a984708SDavid Chisnall if (__m1 < __d) 23397a984708SDavid Chisnall __p2 += __m1; 23407a984708SDavid Chisnall else 23417a984708SDavid Chisnall __p2 = __first + (__m1 - __d); 23427a984708SDavid Chisnall } while (__p2 != __p); 2343936e9439SDimitry Andric *__p1 = _VSTD::move(__t); 23447a984708SDavid Chisnall } 23457a984708SDavid Chisnall return __first + __m2; 23467a984708SDavid Chisnall} 23477a984708SDavid Chisnall 23487a984708SDavid Chisnalltemplate <class _ForwardIterator> 23497a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 23507a984708SDavid Chisnall_ForwardIterator 2351936e9439SDimitry Andric__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, 2352936e9439SDimitry Andric _VSTD::forward_iterator_tag) 2353936e9439SDimitry Andric{ 2354936e9439SDimitry Andric typedef typename _VSTD::iterator_traits<_ForwardIterator>::value_type value_type; 2355936e9439SDimitry Andric if (_VSTD::is_trivially_move_assignable<value_type>::value) 2356936e9439SDimitry Andric { 2357936e9439SDimitry Andric if (_VSTD::next(__first) == __middle) 2358936e9439SDimitry Andric return _VSTD::__rotate_left(__first, __last); 2359936e9439SDimitry Andric } 2360936e9439SDimitry Andric return _VSTD::__rotate_forward(__first, __middle, __last); 2361936e9439SDimitry Andric} 2362936e9439SDimitry Andric 2363936e9439SDimitry Andrictemplate <class _BidirectionalIterator> 2364936e9439SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2365936e9439SDimitry Andric_BidirectionalIterator 2366936e9439SDimitry Andric__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 2367936e9439SDimitry Andric _VSTD::bidirectional_iterator_tag) 2368936e9439SDimitry Andric{ 2369936e9439SDimitry Andric typedef typename _VSTD::iterator_traits<_BidirectionalIterator>::value_type value_type; 2370936e9439SDimitry Andric if (_VSTD::is_trivially_move_assignable<value_type>::value) 2371936e9439SDimitry Andric { 2372936e9439SDimitry Andric if (_VSTD::next(__first) == __middle) 2373936e9439SDimitry Andric return _VSTD::__rotate_left(__first, __last); 2374936e9439SDimitry Andric if (_VSTD::next(__middle) == __last) 2375936e9439SDimitry Andric return _VSTD::__rotate_right(__first, __last); 2376936e9439SDimitry Andric } 2377936e9439SDimitry Andric return _VSTD::__rotate_forward(__first, __middle, __last); 2378936e9439SDimitry Andric} 2379936e9439SDimitry Andric 2380936e9439SDimitry Andrictemplate <class _RandomAccessIterator> 2381936e9439SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2382936e9439SDimitry Andric_RandomAccessIterator 2383936e9439SDimitry Andric__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, 2384936e9439SDimitry Andric _VSTD::random_access_iterator_tag) 2385936e9439SDimitry Andric{ 2386936e9439SDimitry Andric typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::value_type value_type; 2387936e9439SDimitry Andric if (_VSTD::is_trivially_move_assignable<value_type>::value) 2388936e9439SDimitry Andric { 2389936e9439SDimitry Andric if (_VSTD::next(__first) == __middle) 2390936e9439SDimitry Andric return _VSTD::__rotate_left(__first, __last); 2391936e9439SDimitry Andric if (_VSTD::next(__middle) == __last) 2392936e9439SDimitry Andric return _VSTD::__rotate_right(__first, __last); 2393936e9439SDimitry Andric return _VSTD::__rotate_gcd(__first, __middle, __last); 2394936e9439SDimitry Andric } 2395936e9439SDimitry Andric return _VSTD::__rotate_forward(__first, __middle, __last); 2396936e9439SDimitry Andric} 2397936e9439SDimitry Andric 2398936e9439SDimitry Andrictemplate <class _ForwardIterator> 2399936e9439SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2400936e9439SDimitry Andric_ForwardIterator 24017a984708SDavid Chisnallrotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) 24027a984708SDavid Chisnall{ 2403936e9439SDimitry Andric if (__first == __middle) 2404936e9439SDimitry Andric return __last; 2405936e9439SDimitry Andric if (__middle == __last) 2406936e9439SDimitry Andric return __first; 24077a984708SDavid Chisnall return _VSTD::__rotate(__first, __middle, __last, 2408936e9439SDimitry Andric typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category()); 24097a984708SDavid Chisnall} 24107a984708SDavid Chisnall 24117a984708SDavid Chisnall// rotate_copy 24127a984708SDavid Chisnall 24137a984708SDavid Chisnalltemplate <class _ForwardIterator, class _OutputIterator> 24147a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 24157a984708SDavid Chisnall_OutputIterator 24167a984708SDavid Chisnallrotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) 24177a984708SDavid Chisnall{ 24187a984708SDavid Chisnall return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result)); 24197a984708SDavid Chisnall} 24207a984708SDavid Chisnall 24217a984708SDavid Chisnall// min_element 24227a984708SDavid Chisnall 24237a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Compare> 2424d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 24257a984708SDavid Chisnall_ForwardIterator 2426854fa44bSDimitry Andricmin_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 24277a984708SDavid Chisnall{ 2428*b5893f02SDimitry Andric static_assert(__is_forward_iterator<_ForwardIterator>::value, 2429*b5893f02SDimitry Andric "std::min_element requires a ForwardIterator"); 24307a984708SDavid Chisnall if (__first != __last) 24317a984708SDavid Chisnall { 24327a984708SDavid Chisnall _ForwardIterator __i = __first; 24337a984708SDavid Chisnall while (++__i != __last) 24347a984708SDavid Chisnall if (__comp(*__i, *__first)) 24357a984708SDavid Chisnall __first = __i; 24367a984708SDavid Chisnall } 24377a984708SDavid Chisnall return __first; 24387a984708SDavid Chisnall} 24397a984708SDavid Chisnall 24407a984708SDavid Chisnalltemplate <class _ForwardIterator> 2441854fa44bSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 24427a984708SDavid Chisnall_ForwardIterator 24437a984708SDavid Chisnallmin_element(_ForwardIterator __first, _ForwardIterator __last) 24447a984708SDavid Chisnall{ 2445854fa44bSDimitry Andric return _VSTD::min_element(__first, __last, 24467a984708SDavid Chisnall __less<typename iterator_traits<_ForwardIterator>::value_type>()); 24477a984708SDavid Chisnall} 24487a984708SDavid Chisnall 24497a984708SDavid Chisnall// min 24507a984708SDavid Chisnall 24517a984708SDavid Chisnalltemplate <class _Tp, class _Compare> 2452d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 24537a984708SDavid Chisnallconst _Tp& 24547a984708SDavid Chisnallmin(const _Tp& __a, const _Tp& __b, _Compare __comp) 24557a984708SDavid Chisnall{ 24567a984708SDavid Chisnall return __comp(__b, __a) ? __b : __a; 24577a984708SDavid Chisnall} 24587a984708SDavid Chisnall 24597a984708SDavid Chisnalltemplate <class _Tp> 2460d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 24617a984708SDavid Chisnallconst _Tp& 24627a984708SDavid Chisnallmin(const _Tp& __a, const _Tp& __b) 24637a984708SDavid Chisnall{ 24647a984708SDavid Chisnall return _VSTD::min(__a, __b, __less<_Tp>()); 24657a984708SDavid Chisnall} 24667a984708SDavid Chisnall 2467540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 24687a984708SDavid Chisnall 24697a984708SDavid Chisnalltemplate<class _Tp, class _Compare> 2470d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 24717a984708SDavid Chisnall_Tp 24727a984708SDavid Chisnallmin(initializer_list<_Tp> __t, _Compare __comp) 24737a984708SDavid Chisnall{ 2474854fa44bSDimitry Andric return *_VSTD::min_element(__t.begin(), __t.end(), __comp); 24757a984708SDavid Chisnall} 24767a984708SDavid Chisnall 24777a984708SDavid Chisnalltemplate<class _Tp> 2478d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 24797a984708SDavid Chisnall_Tp 24807a984708SDavid Chisnallmin(initializer_list<_Tp> __t) 24817a984708SDavid Chisnall{ 2482854fa44bSDimitry Andric return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>()); 24837a984708SDavid Chisnall} 24847a984708SDavid Chisnall 2485540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG 24867a984708SDavid Chisnall 24877a984708SDavid Chisnall// max_element 24887a984708SDavid Chisnall 24897a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Compare> 2490d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 24917a984708SDavid Chisnall_ForwardIterator 2492854fa44bSDimitry Andricmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 24937a984708SDavid Chisnall{ 2494*b5893f02SDimitry Andric static_assert(__is_forward_iterator<_ForwardIterator>::value, 2495*b5893f02SDimitry Andric "std::max_element requires a ForwardIterator"); 24967a984708SDavid Chisnall if (__first != __last) 24977a984708SDavid Chisnall { 24987a984708SDavid Chisnall _ForwardIterator __i = __first; 24997a984708SDavid Chisnall while (++__i != __last) 25007a984708SDavid Chisnall if (__comp(*__first, *__i)) 25017a984708SDavid Chisnall __first = __i; 25027a984708SDavid Chisnall } 25037a984708SDavid Chisnall return __first; 25047a984708SDavid Chisnall} 25057a984708SDavid Chisnall 2506d72607e9SDimitry Andric 25077a984708SDavid Chisnalltemplate <class _ForwardIterator> 2508854fa44bSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25097a984708SDavid Chisnall_ForwardIterator 25107a984708SDavid Chisnallmax_element(_ForwardIterator __first, _ForwardIterator __last) 25117a984708SDavid Chisnall{ 2512854fa44bSDimitry Andric return _VSTD::max_element(__first, __last, 25137a984708SDavid Chisnall __less<typename iterator_traits<_ForwardIterator>::value_type>()); 25147a984708SDavid Chisnall} 25157a984708SDavid Chisnall 25167a984708SDavid Chisnall// max 25177a984708SDavid Chisnall 25187a984708SDavid Chisnalltemplate <class _Tp, class _Compare> 2519d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25207a984708SDavid Chisnallconst _Tp& 25217a984708SDavid Chisnallmax(const _Tp& __a, const _Tp& __b, _Compare __comp) 25227a984708SDavid Chisnall{ 25237a984708SDavid Chisnall return __comp(__a, __b) ? __b : __a; 25247a984708SDavid Chisnall} 25257a984708SDavid Chisnall 25267a984708SDavid Chisnalltemplate <class _Tp> 2527d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25287a984708SDavid Chisnallconst _Tp& 25297a984708SDavid Chisnallmax(const _Tp& __a, const _Tp& __b) 25307a984708SDavid Chisnall{ 25317a984708SDavid Chisnall return _VSTD::max(__a, __b, __less<_Tp>()); 25327a984708SDavid Chisnall} 25337a984708SDavid Chisnall 2534540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 25357a984708SDavid Chisnall 25367a984708SDavid Chisnalltemplate<class _Tp, class _Compare> 2537d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25387a984708SDavid Chisnall_Tp 25397a984708SDavid Chisnallmax(initializer_list<_Tp> __t, _Compare __comp) 25407a984708SDavid Chisnall{ 2541854fa44bSDimitry Andric return *_VSTD::max_element(__t.begin(), __t.end(), __comp); 25427a984708SDavid Chisnall} 25437a984708SDavid Chisnall 25447a984708SDavid Chisnalltemplate<class _Tp> 2545d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 25467a984708SDavid Chisnall_Tp 25477a984708SDavid Chisnallmax(initializer_list<_Tp> __t) 25487a984708SDavid Chisnall{ 2549854fa44bSDimitry Andric return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>()); 25507a984708SDavid Chisnall} 25517a984708SDavid Chisnall 2552540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG 25537a984708SDavid Chisnall 25547c82a1ecSDimitry Andric#if _LIBCPP_STD_VER > 14 25557c82a1ecSDimitry Andric// clamp 25567c82a1ecSDimitry Andrictemplate<class _Tp, class _Compare> 25577c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 25587c82a1ecSDimitry Andricconst _Tp& 25597c82a1ecSDimitry Andricclamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) 25607c82a1ecSDimitry Andric{ 25617c82a1ecSDimitry Andric _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp"); 25627c82a1ecSDimitry Andric return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v; 25637c82a1ecSDimitry Andric 25647c82a1ecSDimitry Andric} 25657c82a1ecSDimitry Andric 25667c82a1ecSDimitry Andrictemplate<class _Tp> 25677c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 25687c82a1ecSDimitry Andricconst _Tp& 25697c82a1ecSDimitry Andricclamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) 25707c82a1ecSDimitry Andric{ 25717c82a1ecSDimitry Andric return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>()); 25727c82a1ecSDimitry Andric} 25737c82a1ecSDimitry Andric#endif 25747c82a1ecSDimitry Andric 25757a984708SDavid Chisnall// minmax_element 25767a984708SDavid Chisnall 25777a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Compare> 2578854fa44bSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 25797a984708SDavid Chisnallstd::pair<_ForwardIterator, _ForwardIterator> 25807a984708SDavid Chisnallminmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 25817a984708SDavid Chisnall{ 2582*b5893f02SDimitry Andric static_assert(__is_forward_iterator<_ForwardIterator>::value, 2583*b5893f02SDimitry Andric "std::minmax_element requires a ForwardIterator"); 25847a984708SDavid Chisnall std::pair<_ForwardIterator, _ForwardIterator> __result(__first, __first); 25857a984708SDavid Chisnall if (__first != __last) 25867a984708SDavid Chisnall { 25877a984708SDavid Chisnall if (++__first != __last) 25887a984708SDavid Chisnall { 25897a984708SDavid Chisnall if (__comp(*__first, *__result.first)) 25907a984708SDavid Chisnall __result.first = __first; 25917a984708SDavid Chisnall else 25927a984708SDavid Chisnall __result.second = __first; 25937a984708SDavid Chisnall while (++__first != __last) 25947a984708SDavid Chisnall { 25957a984708SDavid Chisnall _ForwardIterator __i = __first; 25967a984708SDavid Chisnall if (++__first == __last) 25977a984708SDavid Chisnall { 25987a984708SDavid Chisnall if (__comp(*__i, *__result.first)) 25997a984708SDavid Chisnall __result.first = __i; 26007a984708SDavid Chisnall else if (!__comp(*__i, *__result.second)) 26017a984708SDavid Chisnall __result.second = __i; 26027a984708SDavid Chisnall break; 26037a984708SDavid Chisnall } 26047a984708SDavid Chisnall else 26057a984708SDavid Chisnall { 26067a984708SDavid Chisnall if (__comp(*__first, *__i)) 26077a984708SDavid Chisnall { 26087a984708SDavid Chisnall if (__comp(*__first, *__result.first)) 26097a984708SDavid Chisnall __result.first = __first; 26107a984708SDavid Chisnall if (!__comp(*__i, *__result.second)) 26117a984708SDavid Chisnall __result.second = __i; 26127a984708SDavid Chisnall } 26137a984708SDavid Chisnall else 26147a984708SDavid Chisnall { 26157a984708SDavid Chisnall if (__comp(*__i, *__result.first)) 26167a984708SDavid Chisnall __result.first = __i; 26177a984708SDavid Chisnall if (!__comp(*__first, *__result.second)) 26187a984708SDavid Chisnall __result.second = __first; 26197a984708SDavid Chisnall } 26207a984708SDavid Chisnall } 26217a984708SDavid Chisnall } 26227a984708SDavid Chisnall } 26237a984708SDavid Chisnall } 26247a984708SDavid Chisnall return __result; 26257a984708SDavid Chisnall} 26267a984708SDavid Chisnall 26277a984708SDavid Chisnalltemplate <class _ForwardIterator> 2628854fa44bSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 26297a984708SDavid Chisnallstd::pair<_ForwardIterator, _ForwardIterator> 26307a984708SDavid Chisnallminmax_element(_ForwardIterator __first, _ForwardIterator __last) 26317a984708SDavid Chisnall{ 2632d72607e9SDimitry Andric return _VSTD::minmax_element(__first, __last, 2633d72607e9SDimitry Andric __less<typename iterator_traits<_ForwardIterator>::value_type>()); 26347a984708SDavid Chisnall} 26357a984708SDavid Chisnall 26367a984708SDavid Chisnall// minmax 26377a984708SDavid Chisnall 26387a984708SDavid Chisnalltemplate<class _Tp, class _Compare> 2639d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 26407a984708SDavid Chisnallpair<const _Tp&, const _Tp&> 26417a984708SDavid Chisnallminmax(const _Tp& __a, const _Tp& __b, _Compare __comp) 26427a984708SDavid Chisnall{ 26437a984708SDavid Chisnall return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) : 26447a984708SDavid Chisnall pair<const _Tp&, const _Tp&>(__a, __b); 26457a984708SDavid Chisnall} 26467a984708SDavid Chisnall 26477a984708SDavid Chisnalltemplate<class _Tp> 2648d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 26497a984708SDavid Chisnallpair<const _Tp&, const _Tp&> 26507a984708SDavid Chisnallminmax(const _Tp& __a, const _Tp& __b) 26517a984708SDavid Chisnall{ 26527a984708SDavid Chisnall return _VSTD::minmax(__a, __b, __less<_Tp>()); 26537a984708SDavid Chisnall} 26547a984708SDavid Chisnall 2655540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 26567a984708SDavid Chisnall 26577a984708SDavid Chisnalltemplate<class _Tp, class _Compare> 2658d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 26597a984708SDavid Chisnallpair<_Tp, _Tp> 26607a984708SDavid Chisnallminmax(initializer_list<_Tp> __t, _Compare __comp) 26617a984708SDavid Chisnall{ 2662d72607e9SDimitry Andric typedef typename initializer_list<_Tp>::const_iterator _Iter; 2663d72607e9SDimitry Andric _Iter __first = __t.begin(); 2664d72607e9SDimitry Andric _Iter __last = __t.end(); 2665d72607e9SDimitry Andric std::pair<_Tp, _Tp> __result(*__first, *__first); 2666d72607e9SDimitry Andric 2667d72607e9SDimitry Andric ++__first; 2668d72607e9SDimitry Andric if (__t.size() % 2 == 0) 2669d72607e9SDimitry Andric { 2670d72607e9SDimitry Andric if (__comp(*__first, __result.first)) 2671d72607e9SDimitry Andric __result.first = *__first; 2672d72607e9SDimitry Andric else 2673d72607e9SDimitry Andric __result.second = *__first; 2674d72607e9SDimitry Andric ++__first; 2675d72607e9SDimitry Andric } 2676d72607e9SDimitry Andric 2677d72607e9SDimitry Andric while (__first != __last) 2678d72607e9SDimitry Andric { 2679d72607e9SDimitry Andric _Tp __prev = *__first++; 2680854fa44bSDimitry Andric if (__comp(*__first, __prev)) { 2681854fa44bSDimitry Andric if ( __comp(*__first, __result.first)) __result.first = *__first; 2682854fa44bSDimitry Andric if (!__comp(__prev, __result.second)) __result.second = __prev; 2683d72607e9SDimitry Andric } 2684d72607e9SDimitry Andric else { 2685854fa44bSDimitry Andric if ( __comp(__prev, __result.first)) __result.first = __prev; 2686854fa44bSDimitry Andric if (!__comp(*__first, __result.second)) __result.second = *__first; 2687d72607e9SDimitry Andric } 2688d72607e9SDimitry Andric 2689d72607e9SDimitry Andric __first++; 2690d72607e9SDimitry Andric } 2691d72607e9SDimitry Andric return __result; 2692d72607e9SDimitry Andric} 2693d72607e9SDimitry Andric 2694d72607e9SDimitry Andrictemplate<class _Tp> 2695d72607e9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2696d72607e9SDimitry Andricpair<_Tp, _Tp> 2697d72607e9SDimitry Andricminmax(initializer_list<_Tp> __t) 2698d72607e9SDimitry Andric{ 2699d72607e9SDimitry Andric return _VSTD::minmax(__t, __less<_Tp>()); 27007a984708SDavid Chisnall} 27017a984708SDavid Chisnall 2702540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG 27037a984708SDavid Chisnall 27047a984708SDavid Chisnall// random_shuffle 27057a984708SDavid Chisnall 27067a984708SDavid Chisnall// __independent_bits_engine 27077a984708SDavid Chisnall 270894e3ee44SDavid Chisnalltemplate <unsigned long long _Xp, size_t _Rp> 27097a984708SDavid Chisnallstruct __log2_imp 27107a984708SDavid Chisnall{ 271194e3ee44SDavid Chisnall static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp 271294e3ee44SDavid Chisnall : __log2_imp<_Xp, _Rp - 1>::value; 27137a984708SDavid Chisnall}; 27147a984708SDavid Chisnall 271594e3ee44SDavid Chisnalltemplate <unsigned long long _Xp> 271694e3ee44SDavid Chisnallstruct __log2_imp<_Xp, 0> 27177a984708SDavid Chisnall{ 27187a984708SDavid Chisnall static const size_t value = 0; 27197a984708SDavid Chisnall}; 27207a984708SDavid Chisnall 272194e3ee44SDavid Chisnalltemplate <size_t _Rp> 272294e3ee44SDavid Chisnallstruct __log2_imp<0, _Rp> 27237a984708SDavid Chisnall{ 272494e3ee44SDavid Chisnall static const size_t value = _Rp + 1; 27257a984708SDavid Chisnall}; 27267a984708SDavid Chisnall 2727f9448bf3SDimitry Andrictemplate <class _UIntType, _UIntType _Xp> 27287a984708SDavid Chisnallstruct __log2 27297a984708SDavid Chisnall{ 273094e3ee44SDavid Chisnall static const size_t value = __log2_imp<_Xp, 2731f9448bf3SDimitry Andric sizeof(_UIntType) * __CHAR_BIT__ - 1>::value; 27327a984708SDavid Chisnall}; 27337a984708SDavid Chisnall 27347a984708SDavid Chisnalltemplate<class _Engine, class _UIntType> 27357a984708SDavid Chisnallclass __independent_bits_engine 27367a984708SDavid Chisnall{ 27377a984708SDavid Chisnallpublic: 27387a984708SDavid Chisnall // types 27397a984708SDavid Chisnall typedef _UIntType result_type; 27407a984708SDavid Chisnall 27417a984708SDavid Chisnallprivate: 27427a984708SDavid Chisnall typedef typename _Engine::result_type _Engine_result_type; 27437a984708SDavid Chisnall typedef typename conditional 27447a984708SDavid Chisnall < 27457a984708SDavid Chisnall sizeof(_Engine_result_type) <= sizeof(result_type), 27467a984708SDavid Chisnall result_type, 27477a984708SDavid Chisnall _Engine_result_type 27487a984708SDavid Chisnall >::type _Working_result_type; 27497a984708SDavid Chisnall 27507a984708SDavid Chisnall _Engine& __e_; 27517a984708SDavid Chisnall size_t __w_; 27527a984708SDavid Chisnall size_t __w0_; 27537a984708SDavid Chisnall size_t __n_; 27547a984708SDavid Chisnall size_t __n0_; 27557a984708SDavid Chisnall _Working_result_type __y0_; 27567a984708SDavid Chisnall _Working_result_type __y1_; 27577a984708SDavid Chisnall _Engine_result_type __mask0_; 27587a984708SDavid Chisnall _Engine_result_type __mask1_; 27597a984708SDavid Chisnall 2760540d2a8bSDimitry Andric#ifdef _LIBCPP_CXX03_LANG 276194e3ee44SDavid Chisnall static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min 27627a984708SDavid Chisnall + _Working_result_type(1); 2763b03f91a8SDavid Chisnall#else 2764b03f91a8SDavid Chisnall static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min() 2765b03f91a8SDavid Chisnall + _Working_result_type(1); 2766b03f91a8SDavid Chisnall#endif 2767b03f91a8SDavid Chisnall static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value; 2768b03f91a8SDavid Chisnall static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits; 2769b03f91a8SDavid Chisnall static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits; 27707a984708SDavid Chisnall 27717a984708SDavid Chisnallpublic: 27727a984708SDavid Chisnall // constructors and seeding functions 27737a984708SDavid Chisnall __independent_bits_engine(_Engine& __e, size_t __w); 27747a984708SDavid Chisnall 27757a984708SDavid Chisnall // generating functions 277694e3ee44SDavid Chisnall result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());} 27777a984708SDavid Chisnall 27787a984708SDavid Chisnallprivate: 27797a984708SDavid Chisnall result_type __eval(false_type); 27807a984708SDavid Chisnall result_type __eval(true_type); 27817a984708SDavid Chisnall}; 27827a984708SDavid Chisnall 27837a984708SDavid Chisnalltemplate<class _Engine, class _UIntType> 27847a984708SDavid Chisnall__independent_bits_engine<_Engine, _UIntType> 27857a984708SDavid Chisnall ::__independent_bits_engine(_Engine& __e, size_t __w) 27867a984708SDavid Chisnall : __e_(__e), 27877a984708SDavid Chisnall __w_(__w) 27887a984708SDavid Chisnall{ 27897a984708SDavid Chisnall __n_ = __w_ / __m + (__w_ % __m != 0); 27907a984708SDavid Chisnall __w0_ = __w_ / __n_; 279194e3ee44SDavid Chisnall if (_Rp == 0) 279294e3ee44SDavid Chisnall __y0_ = _Rp; 27937a984708SDavid Chisnall else if (__w0_ < _WDt) 279494e3ee44SDavid Chisnall __y0_ = (_Rp >> __w0_) << __w0_; 27957a984708SDavid Chisnall else 27967a984708SDavid Chisnall __y0_ = 0; 279794e3ee44SDavid Chisnall if (_Rp - __y0_ > __y0_ / __n_) 27987a984708SDavid Chisnall { 27997a984708SDavid Chisnall ++__n_; 28007a984708SDavid Chisnall __w0_ = __w_ / __n_; 28017a984708SDavid Chisnall if (__w0_ < _WDt) 280294e3ee44SDavid Chisnall __y0_ = (_Rp >> __w0_) << __w0_; 28037a984708SDavid Chisnall else 28047a984708SDavid Chisnall __y0_ = 0; 28057a984708SDavid Chisnall } 28067a984708SDavid Chisnall __n0_ = __n_ - __w_ % __n_; 28077a984708SDavid Chisnall if (__w0_ < _WDt - 1) 280894e3ee44SDavid Chisnall __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1); 28097a984708SDavid Chisnall else 28107a984708SDavid Chisnall __y1_ = 0; 28117a984708SDavid Chisnall __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) : 28127a984708SDavid Chisnall _Engine_result_type(0); 28137a984708SDavid Chisnall __mask1_ = __w0_ < _EDt - 1 ? 28147a984708SDavid Chisnall _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) : 28157a984708SDavid Chisnall _Engine_result_type(~0); 28167a984708SDavid Chisnall} 28177a984708SDavid Chisnall 28187a984708SDavid Chisnalltemplate<class _Engine, class _UIntType> 28197a984708SDavid Chisnallinline 28207a984708SDavid Chisnall_UIntType 28217a984708SDavid Chisnall__independent_bits_engine<_Engine, _UIntType>::__eval(false_type) 28227a984708SDavid Chisnall{ 28237a984708SDavid Chisnall return static_cast<result_type>(__e_() & __mask0_); 28247a984708SDavid Chisnall} 28257a984708SDavid Chisnall 28267a984708SDavid Chisnalltemplate<class _Engine, class _UIntType> 28277a984708SDavid Chisnall_UIntType 28287a984708SDavid Chisnall__independent_bits_engine<_Engine, _UIntType>::__eval(true_type) 28297a984708SDavid Chisnall{ 2830d4419f6fSDimitry Andric const size_t _WRt = numeric_limits<result_type>::digits; 283194e3ee44SDavid Chisnall result_type _Sp = 0; 28327a984708SDavid Chisnall for (size_t __k = 0; __k < __n0_; ++__k) 28337a984708SDavid Chisnall { 28347a984708SDavid Chisnall _Engine_result_type __u; 28357a984708SDavid Chisnall do 28367a984708SDavid Chisnall { 28377a984708SDavid Chisnall __u = __e_() - _Engine::min(); 28387a984708SDavid Chisnall } while (__u >= __y0_); 2839d4419f6fSDimitry Andric if (__w0_ < _WRt) 284094e3ee44SDavid Chisnall _Sp <<= __w0_; 28417a984708SDavid Chisnall else 284294e3ee44SDavid Chisnall _Sp = 0; 284394e3ee44SDavid Chisnall _Sp += __u & __mask0_; 28447a984708SDavid Chisnall } 28457a984708SDavid Chisnall for (size_t __k = __n0_; __k < __n_; ++__k) 28467a984708SDavid Chisnall { 28477a984708SDavid Chisnall _Engine_result_type __u; 28487a984708SDavid Chisnall do 28497a984708SDavid Chisnall { 28507a984708SDavid Chisnall __u = __e_() - _Engine::min(); 28517a984708SDavid Chisnall } while (__u >= __y1_); 2852d4419f6fSDimitry Andric if (__w0_ < _WRt - 1) 285394e3ee44SDavid Chisnall _Sp <<= __w0_ + 1; 28547a984708SDavid Chisnall else 285594e3ee44SDavid Chisnall _Sp = 0; 285694e3ee44SDavid Chisnall _Sp += __u & __mask1_; 28577a984708SDavid Chisnall } 285894e3ee44SDavid Chisnall return _Sp; 28597a984708SDavid Chisnall} 28607a984708SDavid Chisnall 28617a984708SDavid Chisnall// uniform_int_distribution 28627a984708SDavid Chisnall 28637a984708SDavid Chisnalltemplate<class _IntType = int> 28647a984708SDavid Chisnallclass uniform_int_distribution 28657a984708SDavid Chisnall{ 28667a984708SDavid Chisnallpublic: 28677a984708SDavid Chisnall // types 28687a984708SDavid Chisnall typedef _IntType result_type; 28697a984708SDavid Chisnall 28707a984708SDavid Chisnall class param_type 28717a984708SDavid Chisnall { 28727a984708SDavid Chisnall result_type __a_; 28737a984708SDavid Chisnall result_type __b_; 28747a984708SDavid Chisnall public: 28757a984708SDavid Chisnall typedef uniform_int_distribution distribution_type; 28767a984708SDavid Chisnall 28777a984708SDavid Chisnall explicit param_type(result_type __a = 0, 28787a984708SDavid Chisnall result_type __b = numeric_limits<result_type>::max()) 28797a984708SDavid Chisnall : __a_(__a), __b_(__b) {} 28807a984708SDavid Chisnall 28817a984708SDavid Chisnall result_type a() const {return __a_;} 28827a984708SDavid Chisnall result_type b() const {return __b_;} 28837a984708SDavid Chisnall 28847a984708SDavid Chisnall friend bool operator==(const param_type& __x, const param_type& __y) 28857a984708SDavid Chisnall {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} 28867a984708SDavid Chisnall friend bool operator!=(const param_type& __x, const param_type& __y) 28877a984708SDavid Chisnall {return !(__x == __y);} 28887a984708SDavid Chisnall }; 28897a984708SDavid Chisnall 28907a984708SDavid Chisnallprivate: 28917a984708SDavid Chisnall param_type __p_; 28927a984708SDavid Chisnall 28937a984708SDavid Chisnallpublic: 28947a984708SDavid Chisnall // constructors and reset functions 28957a984708SDavid Chisnall explicit uniform_int_distribution(result_type __a = 0, 28967a984708SDavid Chisnall result_type __b = numeric_limits<result_type>::max()) 28977a984708SDavid Chisnall : __p_(param_type(__a, __b)) {} 28987a984708SDavid Chisnall explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {} 28997a984708SDavid Chisnall void reset() {} 29007a984708SDavid Chisnall 29017a984708SDavid Chisnall // generating functions 29027a984708SDavid Chisnall template<class _URNG> result_type operator()(_URNG& __g) 29037a984708SDavid Chisnall {return (*this)(__g, __p_);} 29047a984708SDavid Chisnall template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); 29057a984708SDavid Chisnall 29067a984708SDavid Chisnall // property functions 29077a984708SDavid Chisnall result_type a() const {return __p_.a();} 29087a984708SDavid Chisnall result_type b() const {return __p_.b();} 29097a984708SDavid Chisnall 29107a984708SDavid Chisnall param_type param() const {return __p_;} 29117a984708SDavid Chisnall void param(const param_type& __p) {__p_ = __p;} 29127a984708SDavid Chisnall 29137a984708SDavid Chisnall result_type min() const {return a();} 29147a984708SDavid Chisnall result_type max() const {return b();} 29157a984708SDavid Chisnall 29167a984708SDavid Chisnall friend bool operator==(const uniform_int_distribution& __x, 29177a984708SDavid Chisnall const uniform_int_distribution& __y) 29187a984708SDavid Chisnall {return __x.__p_ == __y.__p_;} 29197a984708SDavid Chisnall friend bool operator!=(const uniform_int_distribution& __x, 29207a984708SDavid Chisnall const uniform_int_distribution& __y) 29217a984708SDavid Chisnall {return !(__x == __y);} 29227a984708SDavid Chisnall}; 29237a984708SDavid Chisnall 29247a984708SDavid Chisnalltemplate<class _IntType> 29257a984708SDavid Chisnalltemplate<class _URNG> 29267a984708SDavid Chisnalltypename uniform_int_distribution<_IntType>::result_type 29277a984708SDavid Chisnalluniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p) 2928*b5893f02SDimitry Andric_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 29297a984708SDavid Chisnall{ 29307a984708SDavid Chisnall typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t), 29317a984708SDavid Chisnall uint32_t, uint64_t>::type _UIntType; 2932*b5893f02SDimitry Andric const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1); 293394e3ee44SDavid Chisnall if (_Rp == 1) 29347a984708SDavid Chisnall return __p.a(); 29357a984708SDavid Chisnall const size_t _Dt = numeric_limits<_UIntType>::digits; 29367a984708SDavid Chisnall typedef __independent_bits_engine<_URNG, _UIntType> _Eng; 293794e3ee44SDavid Chisnall if (_Rp == 0) 29387a984708SDavid Chisnall return static_cast<result_type>(_Eng(__g, _Dt)()); 293994e3ee44SDavid Chisnall size_t __w = _Dt - __clz(_Rp) - 1; 29409729cf09SDimitry Andric if ((_Rp & (std::numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0) 29417a984708SDavid Chisnall ++__w; 29427a984708SDavid Chisnall _Eng __e(__g, __w); 29437a984708SDavid Chisnall _UIntType __u; 29447a984708SDavid Chisnall do 29457a984708SDavid Chisnall { 29467a984708SDavid Chisnall __u = __e(); 294794e3ee44SDavid Chisnall } while (__u >= _Rp); 29487a984708SDavid Chisnall return static_cast<result_type>(__u + __p.a()); 29497a984708SDavid Chisnall} 29507a984708SDavid Chisnall 2951540d2a8bSDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \ 2952540d2a8bSDimitry Andric || defined(_LIBCPP_BUILDING_LIBRARY) 29534f7ab58eSDimitry Andricclass _LIBCPP_TYPE_VIS __rs_default; 29547a984708SDavid Chisnall 29554f7ab58eSDimitry Andric_LIBCPP_FUNC_VIS __rs_default __rs_get(); 29567a984708SDavid Chisnall 29574f7ab58eSDimitry Andricclass _LIBCPP_TYPE_VIS __rs_default 29587a984708SDavid Chisnall{ 29597a984708SDavid Chisnall static unsigned __c_; 29607a984708SDavid Chisnall 29617a984708SDavid Chisnall __rs_default(); 29627a984708SDavid Chisnallpublic: 29631bf9f7c1SDimitry Andric typedef uint_fast32_t result_type; 29647a984708SDavid Chisnall 29657a984708SDavid Chisnall static const result_type _Min = 0; 29667a984708SDavid Chisnall static const result_type _Max = 0xFFFFFFFF; 29677a984708SDavid Chisnall 29687a984708SDavid Chisnall __rs_default(const __rs_default&); 29697a984708SDavid Chisnall ~__rs_default(); 29707a984708SDavid Chisnall 29717a984708SDavid Chisnall result_type operator()(); 29727a984708SDavid Chisnall 2973b03f91a8SDavid Chisnall static _LIBCPP_CONSTEXPR result_type min() {return _Min;} 2974b03f91a8SDavid Chisnall static _LIBCPP_CONSTEXPR result_type max() {return _Max;} 29757a984708SDavid Chisnall 29764f7ab58eSDimitry Andric friend _LIBCPP_FUNC_VIS __rs_default __rs_get(); 29777a984708SDavid Chisnall}; 29787a984708SDavid Chisnall 29794f7ab58eSDimitry Andric_LIBCPP_FUNC_VIS __rs_default __rs_get(); 29807a984708SDavid Chisnall 29817a984708SDavid Chisnalltemplate <class _RandomAccessIterator> 2982*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX14 void 29837a984708SDavid Chisnallrandom_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) 29847a984708SDavid Chisnall{ 29857a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 298694e3ee44SDavid Chisnall typedef uniform_int_distribution<ptrdiff_t> _Dp; 298794e3ee44SDavid Chisnall typedef typename _Dp::param_type _Pp; 29887a984708SDavid Chisnall difference_type __d = __last - __first; 29897a984708SDavid Chisnall if (__d > 1) 29907a984708SDavid Chisnall { 299194e3ee44SDavid Chisnall _Dp __uid; 29927a984708SDavid Chisnall __rs_default __g = __rs_get(); 29937a984708SDavid Chisnall for (--__last, --__d; __first < __last; ++__first, --__d) 29947a984708SDavid Chisnall { 299594e3ee44SDavid Chisnall difference_type __i = __uid(__g, _Pp(0, __d)); 29967a984708SDavid Chisnall if (__i != difference_type(0)) 29977a984708SDavid Chisnall swap(*__first, *(__first + __i)); 29987a984708SDavid Chisnall } 29997a984708SDavid Chisnall } 30007a984708SDavid Chisnall} 30017a984708SDavid Chisnall 30027a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _RandomNumberGenerator> 3003*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX14 void 30047a984708SDavid Chisnallrandom_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, 3005540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 30067a984708SDavid Chisnall _RandomNumberGenerator&& __rand) 30077a984708SDavid Chisnall#else 30087a984708SDavid Chisnall _RandomNumberGenerator& __rand) 30097a984708SDavid Chisnall#endif 30107a984708SDavid Chisnall{ 30117a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 30127a984708SDavid Chisnall difference_type __d = __last - __first; 30137a984708SDavid Chisnall if (__d > 1) 30147a984708SDavid Chisnall { 30157a984708SDavid Chisnall for (--__last; __first < __last; ++__first, --__d) 30167a984708SDavid Chisnall { 30177a984708SDavid Chisnall difference_type __i = __rand(__d); 3018*b5893f02SDimitry Andric if (__i != difference_type(0)) 30197a984708SDavid Chisnall swap(*__first, *(__first + __i)); 30207a984708SDavid Chisnall } 30217a984708SDavid Chisnall } 30227a984708SDavid Chisnall} 3023540d2a8bSDimitry Andric#endif 30247a984708SDavid Chisnall 3025aed8d94eSDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 3026aed8d94eSDimitry Andric class _UniformRandomNumberGenerator> 3027aed8d94eSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3028aed8d94eSDimitry Andric_SampleIterator __sample(_PopulationIterator __first, 3029b2c7081bSDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 3030aed8d94eSDimitry Andric _Distance __n, 3031aed8d94eSDimitry Andric _UniformRandomNumberGenerator & __g, 3032aed8d94eSDimitry Andric input_iterator_tag) { 3033aed8d94eSDimitry Andric 3034aed8d94eSDimitry Andric _Distance __k = 0; 3035aed8d94eSDimitry Andric for (; __first != __last && __k < __n; ++__first, (void)++__k) 3036b2c7081bSDimitry Andric __output_iter[__k] = *__first; 3037aed8d94eSDimitry Andric _Distance __sz = __k; 3038aed8d94eSDimitry Andric for (; __first != __last; ++__first, (void)++__k) { 3039aed8d94eSDimitry Andric _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g); 3040aed8d94eSDimitry Andric if (__r < __sz) 3041b2c7081bSDimitry Andric __output_iter[__r] = *__first; 3042aed8d94eSDimitry Andric } 3043b2c7081bSDimitry Andric return __output_iter + _VSTD::min(__n, __k); 3044aed8d94eSDimitry Andric} 3045aed8d94eSDimitry Andric 3046aed8d94eSDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 3047aed8d94eSDimitry Andric class _UniformRandomNumberGenerator> 3048aed8d94eSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3049aed8d94eSDimitry Andric_SampleIterator __sample(_PopulationIterator __first, 3050b2c7081bSDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 3051aed8d94eSDimitry Andric _Distance __n, 3052aed8d94eSDimitry Andric _UniformRandomNumberGenerator& __g, 3053aed8d94eSDimitry Andric forward_iterator_tag) { 3054aed8d94eSDimitry Andric _Distance __unsampled_sz = _VSTD::distance(__first, __last); 3055aed8d94eSDimitry Andric for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { 3056aed8d94eSDimitry Andric _Distance __r = 3057aed8d94eSDimitry Andric _VSTD::uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); 3058aed8d94eSDimitry Andric if (__r < __n) { 3059b2c7081bSDimitry Andric *__output_iter++ = *__first; 3060aed8d94eSDimitry Andric --__n; 3061aed8d94eSDimitry Andric } 3062aed8d94eSDimitry Andric } 3063b2c7081bSDimitry Andric return __output_iter; 3064aed8d94eSDimitry Andric} 3065aed8d94eSDimitry Andric 3066aed8d94eSDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 3067aed8d94eSDimitry Andric class _UniformRandomNumberGenerator> 3068aed8d94eSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3069aed8d94eSDimitry Andric_SampleIterator __sample(_PopulationIterator __first, 3070b2c7081bSDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 3071aed8d94eSDimitry Andric _Distance __n, _UniformRandomNumberGenerator& __g) { 3072aed8d94eSDimitry Andric typedef typename iterator_traits<_PopulationIterator>::iterator_category 3073aed8d94eSDimitry Andric _PopCategory; 3074aed8d94eSDimitry Andric typedef typename iterator_traits<_PopulationIterator>::difference_type 3075aed8d94eSDimitry Andric _Difference; 3076aed8d94eSDimitry Andric static_assert(__is_forward_iterator<_PopulationIterator>::value || 3077aed8d94eSDimitry Andric __is_random_access_iterator<_SampleIterator>::value, 3078aed8d94eSDimitry Andric "SampleIterator must meet the requirements of RandomAccessIterator"); 3079aed8d94eSDimitry Andric typedef typename common_type<_Distance, _Difference>::type _CommonType; 3080aed8d94eSDimitry Andric _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); 3081aed8d94eSDimitry Andric return _VSTD::__sample( 3082b2c7081bSDimitry Andric __first, __last, __output_iter, _CommonType(__n), 3083aed8d94eSDimitry Andric __g, _PopCategory()); 3084aed8d94eSDimitry Andric} 3085aed8d94eSDimitry Andric 3086aed8d94eSDimitry Andric#if _LIBCPP_STD_VER > 14 3087aed8d94eSDimitry Andrictemplate <class _PopulationIterator, class _SampleIterator, class _Distance, 3088aed8d94eSDimitry Andric class _UniformRandomNumberGenerator> 3089aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 3090aed8d94eSDimitry Andric_SampleIterator sample(_PopulationIterator __first, 3091b2c7081bSDimitry Andric _PopulationIterator __last, _SampleIterator __output_iter, 3092aed8d94eSDimitry Andric _Distance __n, _UniformRandomNumberGenerator&& __g) { 3093b2c7081bSDimitry Andric return _VSTD::__sample(__first, __last, __output_iter, __n, __g); 3094aed8d94eSDimitry Andric} 3095aed8d94eSDimitry Andric#endif // _LIBCPP_STD_VER > 14 3096aed8d94eSDimitry Andric 30977a984708SDavid Chisnalltemplate<class _RandomAccessIterator, class _UniformRandomNumberGenerator> 30987a984708SDavid Chisnall void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, 3099540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 31007a984708SDavid Chisnall _UniformRandomNumberGenerator&& __g) 31017a984708SDavid Chisnall#else 31027a984708SDavid Chisnall _UniformRandomNumberGenerator& __g) 31037a984708SDavid Chisnall#endif 31047a984708SDavid Chisnall{ 31057a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 310694e3ee44SDavid Chisnall typedef uniform_int_distribution<ptrdiff_t> _Dp; 310794e3ee44SDavid Chisnall typedef typename _Dp::param_type _Pp; 31087a984708SDavid Chisnall difference_type __d = __last - __first; 31097a984708SDavid Chisnall if (__d > 1) 31107a984708SDavid Chisnall { 311194e3ee44SDavid Chisnall _Dp __uid; 31127a984708SDavid Chisnall for (--__last, --__d; __first < __last; ++__first, --__d) 31137a984708SDavid Chisnall { 311494e3ee44SDavid Chisnall difference_type __i = __uid(__g, _Pp(0, __d)); 31157a984708SDavid Chisnall if (__i != difference_type(0)) 31167a984708SDavid Chisnall swap(*__first, *(__first + __i)); 31177a984708SDavid Chisnall } 31187a984708SDavid Chisnall } 31197a984708SDavid Chisnall} 31207a984708SDavid Chisnall 31217a984708SDavid Chisnalltemplate <class _InputIterator, class _Predicate> 31224ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 31237a984708SDavid Chisnallis_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) 31247a984708SDavid Chisnall{ 31257a984708SDavid Chisnall for (; __first != __last; ++__first) 31267a984708SDavid Chisnall if (!__pred(*__first)) 31277a984708SDavid Chisnall break; 3128854fa44bSDimitry Andric if ( __first == __last ) 3129854fa44bSDimitry Andric return true; 3130854fa44bSDimitry Andric ++__first; 31317a984708SDavid Chisnall for (; __first != __last; ++__first) 31327a984708SDavid Chisnall if (__pred(*__first)) 31337a984708SDavid Chisnall return false; 31347a984708SDavid Chisnall return true; 31357a984708SDavid Chisnall} 31367a984708SDavid Chisnall 31377a984708SDavid Chisnall// partition 31387a984708SDavid Chisnall 31397a984708SDavid Chisnalltemplate <class _Predicate, class _ForwardIterator> 31407a984708SDavid Chisnall_ForwardIterator 31417a984708SDavid Chisnall__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) 31427a984708SDavid Chisnall{ 31437a984708SDavid Chisnall while (true) 31447a984708SDavid Chisnall { 31457a984708SDavid Chisnall if (__first == __last) 31467a984708SDavid Chisnall return __first; 31477a984708SDavid Chisnall if (!__pred(*__first)) 31487a984708SDavid Chisnall break; 31497a984708SDavid Chisnall ++__first; 31507a984708SDavid Chisnall } 31517a984708SDavid Chisnall for (_ForwardIterator __p = __first; ++__p != __last;) 31527a984708SDavid Chisnall { 31537a984708SDavid Chisnall if (__pred(*__p)) 31547a984708SDavid Chisnall { 31557a984708SDavid Chisnall swap(*__first, *__p); 31567a984708SDavid Chisnall ++__first; 31577a984708SDavid Chisnall } 31587a984708SDavid Chisnall } 31597a984708SDavid Chisnall return __first; 31607a984708SDavid Chisnall} 31617a984708SDavid Chisnall 31627a984708SDavid Chisnalltemplate <class _Predicate, class _BidirectionalIterator> 31637a984708SDavid Chisnall_BidirectionalIterator 31647a984708SDavid Chisnall__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, 31657a984708SDavid Chisnall bidirectional_iterator_tag) 31667a984708SDavid Chisnall{ 31677a984708SDavid Chisnall while (true) 31687a984708SDavid Chisnall { 31697a984708SDavid Chisnall while (true) 31707a984708SDavid Chisnall { 31717a984708SDavid Chisnall if (__first == __last) 31727a984708SDavid Chisnall return __first; 31737a984708SDavid Chisnall if (!__pred(*__first)) 31747a984708SDavid Chisnall break; 31757a984708SDavid Chisnall ++__first; 31767a984708SDavid Chisnall } 31777a984708SDavid Chisnall do 31787a984708SDavid Chisnall { 31797a984708SDavid Chisnall if (__first == --__last) 31807a984708SDavid Chisnall return __first; 31817a984708SDavid Chisnall } while (!__pred(*__last)); 31827a984708SDavid Chisnall swap(*__first, *__last); 31837a984708SDavid Chisnall ++__first; 31847a984708SDavid Chisnall } 31857a984708SDavid Chisnall} 31867a984708SDavid Chisnall 31877a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Predicate> 31887a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 31897a984708SDavid Chisnall_ForwardIterator 31907a984708SDavid Chisnallpartition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 31917a984708SDavid Chisnall{ 31927a984708SDavid Chisnall return _VSTD::__partition<typename add_lvalue_reference<_Predicate>::type> 31937a984708SDavid Chisnall (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); 31947a984708SDavid Chisnall} 31957a984708SDavid Chisnall 31967a984708SDavid Chisnall// partition_copy 31977a984708SDavid Chisnall 31987a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator1, 31997a984708SDavid Chisnall class _OutputIterator2, class _Predicate> 32004ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_OutputIterator1, _OutputIterator2> 32017a984708SDavid Chisnallpartition_copy(_InputIterator __first, _InputIterator __last, 32027a984708SDavid Chisnall _OutputIterator1 __out_true, _OutputIterator2 __out_false, 32037a984708SDavid Chisnall _Predicate __pred) 32047a984708SDavid Chisnall{ 32057a984708SDavid Chisnall for (; __first != __last; ++__first) 32067a984708SDavid Chisnall { 32077a984708SDavid Chisnall if (__pred(*__first)) 32087a984708SDavid Chisnall { 32097a984708SDavid Chisnall *__out_true = *__first; 32107a984708SDavid Chisnall ++__out_true; 32117a984708SDavid Chisnall } 32127a984708SDavid Chisnall else 32137a984708SDavid Chisnall { 32147a984708SDavid Chisnall *__out_false = *__first; 32157a984708SDavid Chisnall ++__out_false; 32167a984708SDavid Chisnall } 32177a984708SDavid Chisnall } 32187a984708SDavid Chisnall return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); 32197a984708SDavid Chisnall} 32207a984708SDavid Chisnall 32217a984708SDavid Chisnall// partition_point 32227a984708SDavid Chisnall 32237a984708SDavid Chisnalltemplate<class _ForwardIterator, class _Predicate> 32244ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 32257a984708SDavid Chisnallpartition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 32267a984708SDavid Chisnall{ 32277a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 32287a984708SDavid Chisnall difference_type __len = _VSTD::distance(__first, __last); 32297a984708SDavid Chisnall while (__len != 0) 32307a984708SDavid Chisnall { 3231*b5893f02SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 32327a984708SDavid Chisnall _ForwardIterator __m = __first; 32337a984708SDavid Chisnall _VSTD::advance(__m, __l2); 32347a984708SDavid Chisnall if (__pred(*__m)) 32357a984708SDavid Chisnall { 32367a984708SDavid Chisnall __first = ++__m; 32377a984708SDavid Chisnall __len -= __l2 + 1; 32387a984708SDavid Chisnall } 32397a984708SDavid Chisnall else 32407a984708SDavid Chisnall __len = __l2; 32417a984708SDavid Chisnall } 32427a984708SDavid Chisnall return __first; 32437a984708SDavid Chisnall} 32447a984708SDavid Chisnall 32457a984708SDavid Chisnall// stable_partition 32467a984708SDavid Chisnall 32477a984708SDavid Chisnalltemplate <class _Predicate, class _ForwardIterator, class _Distance, class _Pair> 32487a984708SDavid Chisnall_ForwardIterator 32497a984708SDavid Chisnall__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, 32507a984708SDavid Chisnall _Distance __len, _Pair __p, forward_iterator_tag __fit) 32517a984708SDavid Chisnall{ 32527a984708SDavid Chisnall // *__first is known to be false 32537a984708SDavid Chisnall // __len >= 1 32547a984708SDavid Chisnall if (__len == 1) 32557a984708SDavid Chisnall return __first; 32567a984708SDavid Chisnall if (__len == 2) 32577a984708SDavid Chisnall { 32587a984708SDavid Chisnall _ForwardIterator __m = __first; 32597a984708SDavid Chisnall if (__pred(*++__m)) 32607a984708SDavid Chisnall { 32617a984708SDavid Chisnall swap(*__first, *__m); 32627a984708SDavid Chisnall return __m; 32637a984708SDavid Chisnall } 32647a984708SDavid Chisnall return __first; 32657a984708SDavid Chisnall } 32667a984708SDavid Chisnall if (__len <= __p.second) 32677a984708SDavid Chisnall { // The buffer is big enough to use 32687a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator>::value_type value_type; 32697a984708SDavid Chisnall __destruct_n __d(0); 32707a984708SDavid Chisnall unique_ptr<value_type, __destruct_n&> __h(__p.first, __d); 32717a984708SDavid Chisnall // Move the falses into the temporary buffer, and the trues to the front of the line 32727a984708SDavid Chisnall // Update __first to always point to the end of the trues 32737a984708SDavid Chisnall value_type* __t = __p.first; 32747a984708SDavid Chisnall ::new(__t) value_type(_VSTD::move(*__first)); 32757a984708SDavid Chisnall __d.__incr((value_type*)0); 32767a984708SDavid Chisnall ++__t; 32777a984708SDavid Chisnall _ForwardIterator __i = __first; 32787a984708SDavid Chisnall while (++__i != __last) 32797a984708SDavid Chisnall { 32807a984708SDavid Chisnall if (__pred(*__i)) 32817a984708SDavid Chisnall { 32827a984708SDavid Chisnall *__first = _VSTD::move(*__i); 32837a984708SDavid Chisnall ++__first; 32847a984708SDavid Chisnall } 32857a984708SDavid Chisnall else 32867a984708SDavid Chisnall { 32877a984708SDavid Chisnall ::new(__t) value_type(_VSTD::move(*__i)); 32887a984708SDavid Chisnall __d.__incr((value_type*)0); 32897a984708SDavid Chisnall ++__t; 32907a984708SDavid Chisnall } 32917a984708SDavid Chisnall } 32927a984708SDavid Chisnall // All trues now at start of range, all falses in buffer 32937a984708SDavid Chisnall // Move falses back into range, but don't mess up __first which points to first false 32947a984708SDavid Chisnall __i = __first; 32957a984708SDavid Chisnall for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i) 32967a984708SDavid Chisnall *__i = _VSTD::move(*__t2); 32977a984708SDavid Chisnall // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer 32987a984708SDavid Chisnall return __first; 32997a984708SDavid Chisnall } 33007a984708SDavid Chisnall // Else not enough buffer, do in place 33017a984708SDavid Chisnall // __len >= 3 33027a984708SDavid Chisnall _ForwardIterator __m = __first; 33037a984708SDavid Chisnall _Distance __len2 = __len / 2; // __len2 >= 2 33047a984708SDavid Chisnall _VSTD::advance(__m, __len2); 33057a984708SDavid Chisnall // recurse on [__first, __m), *__first know to be false 33067a984708SDavid Chisnall // F????????????????? 33077a984708SDavid Chisnall // f m l 33087a984708SDavid Chisnall typedef typename add_lvalue_reference<_Predicate>::type _PredRef; 33097a984708SDavid Chisnall _ForwardIterator __first_false = __stable_partition<_PredRef>(__first, __m, __pred, __len2, __p, __fit); 33107a984708SDavid Chisnall // TTTFFFFF?????????? 33117a984708SDavid Chisnall // f ff m l 33127a984708SDavid Chisnall // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true 33137a984708SDavid Chisnall _ForwardIterator __m1 = __m; 33147a984708SDavid Chisnall _ForwardIterator __second_false = __last; 33157a984708SDavid Chisnall _Distance __len_half = __len - __len2; 33167a984708SDavid Chisnall while (__pred(*__m1)) 33177a984708SDavid Chisnall { 33187a984708SDavid Chisnall if (++__m1 == __last) 33197a984708SDavid Chisnall goto __second_half_done; 33207a984708SDavid Chisnall --__len_half; 33217a984708SDavid Chisnall } 33227a984708SDavid Chisnall // TTTFFFFFTTTF?????? 33237a984708SDavid Chisnall // f ff m m1 l 33247a984708SDavid Chisnall __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __fit); 33257a984708SDavid Chisnall__second_half_done: 33267a984708SDavid Chisnall // TTTFFFFFTTTTTFFFFF 33277a984708SDavid Chisnall // f ff m sf l 33287a984708SDavid Chisnall return _VSTD::rotate(__first_false, __m, __second_false); 33297a984708SDavid Chisnall // TTTTTTTTFFFFFFFFFF 33307a984708SDavid Chisnall // | 33317a984708SDavid Chisnall} 33327a984708SDavid Chisnall 33337a984708SDavid Chisnallstruct __return_temporary_buffer 33347a984708SDavid Chisnall{ 33357a984708SDavid Chisnall template <class _Tp> 33367a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);} 33377a984708SDavid Chisnall}; 33387a984708SDavid Chisnall 33397a984708SDavid Chisnalltemplate <class _Predicate, class _ForwardIterator> 33407a984708SDavid Chisnall_ForwardIterator 33417a984708SDavid Chisnall__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, 33427a984708SDavid Chisnall forward_iterator_tag) 33437a984708SDavid Chisnall{ 33447a984708SDavid Chisnall const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment 33457a984708SDavid Chisnall // Either prove all true and return __first or point to first false 33467a984708SDavid Chisnall while (true) 33477a984708SDavid Chisnall { 33487a984708SDavid Chisnall if (__first == __last) 33497a984708SDavid Chisnall return __first; 33507a984708SDavid Chisnall if (!__pred(*__first)) 33517a984708SDavid Chisnall break; 33527a984708SDavid Chisnall ++__first; 33537a984708SDavid Chisnall } 33547a984708SDavid Chisnall // We now have a reduced range [__first, __last) 33557a984708SDavid Chisnall // *__first is known to be false 33567a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 33577a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator>::value_type value_type; 33587a984708SDavid Chisnall difference_type __len = _VSTD::distance(__first, __last); 33597a984708SDavid Chisnall pair<value_type*, ptrdiff_t> __p(0, 0); 33607a984708SDavid Chisnall unique_ptr<value_type, __return_temporary_buffer> __h; 33617a984708SDavid Chisnall if (__len >= __alloc_limit) 33627a984708SDavid Chisnall { 33637a984708SDavid Chisnall __p = _VSTD::get_temporary_buffer<value_type>(__len); 33647a984708SDavid Chisnall __h.reset(__p.first); 33657a984708SDavid Chisnall } 33667a984708SDavid Chisnall return __stable_partition<typename add_lvalue_reference<_Predicate>::type> 33677a984708SDavid Chisnall (__first, __last, __pred, __len, __p, forward_iterator_tag()); 33687a984708SDavid Chisnall} 33697a984708SDavid Chisnall 33707a984708SDavid Chisnalltemplate <class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair> 33717a984708SDavid Chisnall_BidirectionalIterator 33727a984708SDavid Chisnall__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, 33737a984708SDavid Chisnall _Distance __len, _Pair __p, bidirectional_iterator_tag __bit) 33747a984708SDavid Chisnall{ 33757a984708SDavid Chisnall // *__first is known to be false 33767a984708SDavid Chisnall // *__last is known to be true 33777a984708SDavid Chisnall // __len >= 2 33787a984708SDavid Chisnall if (__len == 2) 33797a984708SDavid Chisnall { 33807a984708SDavid Chisnall swap(*__first, *__last); 33817a984708SDavid Chisnall return __last; 33827a984708SDavid Chisnall } 33837a984708SDavid Chisnall if (__len == 3) 33847a984708SDavid Chisnall { 33857a984708SDavid Chisnall _BidirectionalIterator __m = __first; 33867a984708SDavid Chisnall if (__pred(*++__m)) 33877a984708SDavid Chisnall { 33887a984708SDavid Chisnall swap(*__first, *__m); 33897a984708SDavid Chisnall swap(*__m, *__last); 33907a984708SDavid Chisnall return __last; 33917a984708SDavid Chisnall } 33927a984708SDavid Chisnall swap(*__m, *__last); 33937a984708SDavid Chisnall swap(*__first, *__m); 33947a984708SDavid Chisnall return __m; 33957a984708SDavid Chisnall } 33967a984708SDavid Chisnall if (__len <= __p.second) 33977a984708SDavid Chisnall { // The buffer is big enough to use 33987a984708SDavid Chisnall typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 33997a984708SDavid Chisnall __destruct_n __d(0); 34007a984708SDavid Chisnall unique_ptr<value_type, __destruct_n&> __h(__p.first, __d); 34017a984708SDavid Chisnall // Move the falses into the temporary buffer, and the trues to the front of the line 34027a984708SDavid Chisnall // Update __first to always point to the end of the trues 34037a984708SDavid Chisnall value_type* __t = __p.first; 34047a984708SDavid Chisnall ::new(__t) value_type(_VSTD::move(*__first)); 34057a984708SDavid Chisnall __d.__incr((value_type*)0); 34067a984708SDavid Chisnall ++__t; 34077a984708SDavid Chisnall _BidirectionalIterator __i = __first; 34087a984708SDavid Chisnall while (++__i != __last) 34097a984708SDavid Chisnall { 34107a984708SDavid Chisnall if (__pred(*__i)) 34117a984708SDavid Chisnall { 34127a984708SDavid Chisnall *__first = _VSTD::move(*__i); 34137a984708SDavid Chisnall ++__first; 34147a984708SDavid Chisnall } 34157a984708SDavid Chisnall else 34167a984708SDavid Chisnall { 34177a984708SDavid Chisnall ::new(__t) value_type(_VSTD::move(*__i)); 34187a984708SDavid Chisnall __d.__incr((value_type*)0); 34197a984708SDavid Chisnall ++__t; 34207a984708SDavid Chisnall } 34217a984708SDavid Chisnall } 34227a984708SDavid Chisnall // move *__last, known to be true 34237a984708SDavid Chisnall *__first = _VSTD::move(*__i); 34247a984708SDavid Chisnall __i = ++__first; 34257a984708SDavid Chisnall // All trues now at start of range, all falses in buffer 34267a984708SDavid Chisnall // Move falses back into range, but don't mess up __first which points to first false 34277a984708SDavid Chisnall for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i) 34287a984708SDavid Chisnall *__i = _VSTD::move(*__t2); 34297a984708SDavid Chisnall // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer 34307a984708SDavid Chisnall return __first; 34317a984708SDavid Chisnall } 34327a984708SDavid Chisnall // Else not enough buffer, do in place 34337a984708SDavid Chisnall // __len >= 4 34347a984708SDavid Chisnall _BidirectionalIterator __m = __first; 34357a984708SDavid Chisnall _Distance __len2 = __len / 2; // __len2 >= 2 34367a984708SDavid Chisnall _VSTD::advance(__m, __len2); 34377a984708SDavid Chisnall // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false 34387a984708SDavid Chisnall // F????????????????T 34397a984708SDavid Chisnall // f m l 34407a984708SDavid Chisnall _BidirectionalIterator __m1 = __m; 34417a984708SDavid Chisnall _BidirectionalIterator __first_false = __first; 34427a984708SDavid Chisnall _Distance __len_half = __len2; 34437a984708SDavid Chisnall while (!__pred(*--__m1)) 34447a984708SDavid Chisnall { 34457a984708SDavid Chisnall if (__m1 == __first) 34467a984708SDavid Chisnall goto __first_half_done; 34477a984708SDavid Chisnall --__len_half; 34487a984708SDavid Chisnall } 34497a984708SDavid Chisnall // F???TFFF?????????T 34507a984708SDavid Chisnall // f m1 m l 34517a984708SDavid Chisnall typedef typename add_lvalue_reference<_Predicate>::type _PredRef; 34527a984708SDavid Chisnall __first_false = __stable_partition<_PredRef>(__first, __m1, __pred, __len_half, __p, __bit); 34537a984708SDavid Chisnall__first_half_done: 34547a984708SDavid Chisnall // TTTFFFFF?????????T 34557a984708SDavid Chisnall // f ff m l 34567a984708SDavid Chisnall // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true 34577a984708SDavid Chisnall __m1 = __m; 34587a984708SDavid Chisnall _BidirectionalIterator __second_false = __last; 34597a984708SDavid Chisnall ++__second_false; 34607a984708SDavid Chisnall __len_half = __len - __len2; 34617a984708SDavid Chisnall while (__pred(*__m1)) 34627a984708SDavid Chisnall { 34637a984708SDavid Chisnall if (++__m1 == __last) 34647a984708SDavid Chisnall goto __second_half_done; 34657a984708SDavid Chisnall --__len_half; 34667a984708SDavid Chisnall } 34677a984708SDavid Chisnall // TTTFFFFFTTTF?????T 34687a984708SDavid Chisnall // f ff m m1 l 34697a984708SDavid Chisnall __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __bit); 34707a984708SDavid Chisnall__second_half_done: 34717a984708SDavid Chisnall // TTTFFFFFTTTTTFFFFF 34727a984708SDavid Chisnall // f ff m sf l 34737a984708SDavid Chisnall return _VSTD::rotate(__first_false, __m, __second_false); 34747a984708SDavid Chisnall // TTTTTTTTFFFFFFFFFF 34757a984708SDavid Chisnall // | 34767a984708SDavid Chisnall} 34777a984708SDavid Chisnall 34787a984708SDavid Chisnalltemplate <class _Predicate, class _BidirectionalIterator> 34797a984708SDavid Chisnall_BidirectionalIterator 34807a984708SDavid Chisnall__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, 34817a984708SDavid Chisnall bidirectional_iterator_tag) 34827a984708SDavid Chisnall{ 34837a984708SDavid Chisnall typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; 34847a984708SDavid Chisnall typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 34857a984708SDavid Chisnall const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment 34867a984708SDavid Chisnall // Either prove all true and return __first or point to first false 34877a984708SDavid Chisnall while (true) 34887a984708SDavid Chisnall { 34897a984708SDavid Chisnall if (__first == __last) 34907a984708SDavid Chisnall return __first; 34917a984708SDavid Chisnall if (!__pred(*__first)) 34927a984708SDavid Chisnall break; 34937a984708SDavid Chisnall ++__first; 34947a984708SDavid Chisnall } 34957a984708SDavid Chisnall // __first points to first false, everything prior to __first is already set. 34967a984708SDavid Chisnall // Either prove [__first, __last) is all false and return __first, or point __last to last true 34977a984708SDavid Chisnall do 34987a984708SDavid Chisnall { 34997a984708SDavid Chisnall if (__first == --__last) 35007a984708SDavid Chisnall return __first; 35017a984708SDavid Chisnall } while (!__pred(*__last)); 35027a984708SDavid Chisnall // We now have a reduced range [__first, __last] 35037a984708SDavid Chisnall // *__first is known to be false 35047a984708SDavid Chisnall // *__last is known to be true 35057a984708SDavid Chisnall // __len >= 2 35067a984708SDavid Chisnall difference_type __len = _VSTD::distance(__first, __last) + 1; 35077a984708SDavid Chisnall pair<value_type*, ptrdiff_t> __p(0, 0); 35087a984708SDavid Chisnall unique_ptr<value_type, __return_temporary_buffer> __h; 35097a984708SDavid Chisnall if (__len >= __alloc_limit) 35107a984708SDavid Chisnall { 35117a984708SDavid Chisnall __p = _VSTD::get_temporary_buffer<value_type>(__len); 35127a984708SDavid Chisnall __h.reset(__p.first); 35137a984708SDavid Chisnall } 35147a984708SDavid Chisnall return __stable_partition<typename add_lvalue_reference<_Predicate>::type> 35157a984708SDavid Chisnall (__first, __last, __pred, __len, __p, bidirectional_iterator_tag()); 35167a984708SDavid Chisnall} 35177a984708SDavid Chisnall 35187a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Predicate> 35197a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 35207a984708SDavid Chisnall_ForwardIterator 35217a984708SDavid Chisnallstable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 35227a984708SDavid Chisnall{ 35237a984708SDavid Chisnall return __stable_partition<typename add_lvalue_reference<_Predicate>::type> 35247a984708SDavid Chisnall (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); 35257a984708SDavid Chisnall} 35267a984708SDavid Chisnall 35277a984708SDavid Chisnall// is_sorted_until 35287a984708SDavid Chisnall 35297a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Compare> 35304ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 35317a984708SDavid Chisnallis_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 35327a984708SDavid Chisnall{ 35337a984708SDavid Chisnall if (__first != __last) 35347a984708SDavid Chisnall { 35357a984708SDavid Chisnall _ForwardIterator __i = __first; 35367a984708SDavid Chisnall while (++__i != __last) 35377a984708SDavid Chisnall { 35387a984708SDavid Chisnall if (__comp(*__i, *__first)) 35397a984708SDavid Chisnall return __i; 35407a984708SDavid Chisnall __first = __i; 35417a984708SDavid Chisnall } 35427a984708SDavid Chisnall } 35437a984708SDavid Chisnall return __last; 35447a984708SDavid Chisnall} 35457a984708SDavid Chisnall 35467a984708SDavid Chisnalltemplate<class _ForwardIterator> 35474ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 35487a984708SDavid Chisnall_ForwardIterator 35497a984708SDavid Chisnallis_sorted_until(_ForwardIterator __first, _ForwardIterator __last) 35507a984708SDavid Chisnall{ 35517a984708SDavid Chisnall return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>()); 35527a984708SDavid Chisnall} 35537a984708SDavid Chisnall 35547a984708SDavid Chisnall// is_sorted 35557a984708SDavid Chisnall 35567a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Compare> 35574ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 35587a984708SDavid Chisnallbool 35597a984708SDavid Chisnallis_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 35607a984708SDavid Chisnall{ 35617a984708SDavid Chisnall return _VSTD::is_sorted_until(__first, __last, __comp) == __last; 35627a984708SDavid Chisnall} 35637a984708SDavid Chisnall 35647a984708SDavid Chisnalltemplate<class _ForwardIterator> 35654ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 35667a984708SDavid Chisnallbool 35677a984708SDavid Chisnallis_sorted(_ForwardIterator __first, _ForwardIterator __last) 35687a984708SDavid Chisnall{ 35697a984708SDavid Chisnall return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>()); 35707a984708SDavid Chisnall} 35717a984708SDavid Chisnall 35727a984708SDavid Chisnall// sort 35737a984708SDavid Chisnall 35747a984708SDavid Chisnall// stable, 2-3 compares, 0-2 swaps 35757a984708SDavid Chisnall 35767a984708SDavid Chisnalltemplate <class _Compare, class _ForwardIterator> 35777a984708SDavid Chisnallunsigned 35787a984708SDavid Chisnall__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c) 35797a984708SDavid Chisnall{ 35807a984708SDavid Chisnall unsigned __r = 0; 35817a984708SDavid Chisnall if (!__c(*__y, *__x)) // if x <= y 35827a984708SDavid Chisnall { 35837a984708SDavid Chisnall if (!__c(*__z, *__y)) // if y <= z 35847a984708SDavid Chisnall return __r; // x <= y && y <= z 35857a984708SDavid Chisnall // x <= y && y > z 35867a984708SDavid Chisnall swap(*__y, *__z); // x <= z && y < z 35877a984708SDavid Chisnall __r = 1; 35887a984708SDavid Chisnall if (__c(*__y, *__x)) // if x > y 35897a984708SDavid Chisnall { 35907a984708SDavid Chisnall swap(*__x, *__y); // x < y && y <= z 35917a984708SDavid Chisnall __r = 2; 35927a984708SDavid Chisnall } 35937a984708SDavid Chisnall return __r; // x <= y && y < z 35947a984708SDavid Chisnall } 35957a984708SDavid Chisnall if (__c(*__z, *__y)) // x > y, if y > z 35967a984708SDavid Chisnall { 35977a984708SDavid Chisnall swap(*__x, *__z); // x < y && y < z 35987a984708SDavid Chisnall __r = 1; 35997a984708SDavid Chisnall return __r; 36007a984708SDavid Chisnall } 36017a984708SDavid Chisnall swap(*__x, *__y); // x > y && y <= z 36027a984708SDavid Chisnall __r = 1; // x < y && x <= z 36037a984708SDavid Chisnall if (__c(*__z, *__y)) // if y > z 36047a984708SDavid Chisnall { 36057a984708SDavid Chisnall swap(*__y, *__z); // x <= y && y < z 36067a984708SDavid Chisnall __r = 2; 36077a984708SDavid Chisnall } 36087a984708SDavid Chisnall return __r; 36097a984708SDavid Chisnall} // x <= y && y <= z 36107a984708SDavid Chisnall 36117a984708SDavid Chisnall// stable, 3-6 compares, 0-5 swaps 36127a984708SDavid Chisnall 36137a984708SDavid Chisnalltemplate <class _Compare, class _ForwardIterator> 36147a984708SDavid Chisnallunsigned 36157a984708SDavid Chisnall__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, 36167a984708SDavid Chisnall _ForwardIterator __x4, _Compare __c) 36177a984708SDavid Chisnall{ 36187a984708SDavid Chisnall unsigned __r = __sort3<_Compare>(__x1, __x2, __x3, __c); 36197a984708SDavid Chisnall if (__c(*__x4, *__x3)) 36207a984708SDavid Chisnall { 36217a984708SDavid Chisnall swap(*__x3, *__x4); 36227a984708SDavid Chisnall ++__r; 36237a984708SDavid Chisnall if (__c(*__x3, *__x2)) 36247a984708SDavid Chisnall { 36257a984708SDavid Chisnall swap(*__x2, *__x3); 36267a984708SDavid Chisnall ++__r; 36277a984708SDavid Chisnall if (__c(*__x2, *__x1)) 36287a984708SDavid Chisnall { 36297a984708SDavid Chisnall swap(*__x1, *__x2); 36307a984708SDavid Chisnall ++__r; 36317a984708SDavid Chisnall } 36327a984708SDavid Chisnall } 36337a984708SDavid Chisnall } 36347a984708SDavid Chisnall return __r; 36357a984708SDavid Chisnall} 36367a984708SDavid Chisnall 36377a984708SDavid Chisnall// stable, 4-10 compares, 0-9 swaps 36387a984708SDavid Chisnall 36397a984708SDavid Chisnalltemplate <class _Compare, class _ForwardIterator> 3640*b5893f02SDimitry Andric_LIBCPP_HIDDEN 36417a984708SDavid Chisnallunsigned 36427a984708SDavid Chisnall__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, 36437a984708SDavid Chisnall _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c) 36447a984708SDavid Chisnall{ 36457a984708SDavid Chisnall unsigned __r = __sort4<_Compare>(__x1, __x2, __x3, __x4, __c); 36467a984708SDavid Chisnall if (__c(*__x5, *__x4)) 36477a984708SDavid Chisnall { 36487a984708SDavid Chisnall swap(*__x4, *__x5); 36497a984708SDavid Chisnall ++__r; 36507a984708SDavid Chisnall if (__c(*__x4, *__x3)) 36517a984708SDavid Chisnall { 36527a984708SDavid Chisnall swap(*__x3, *__x4); 36537a984708SDavid Chisnall ++__r; 36547a984708SDavid Chisnall if (__c(*__x3, *__x2)) 36557a984708SDavid Chisnall { 36567a984708SDavid Chisnall swap(*__x2, *__x3); 36577a984708SDavid Chisnall ++__r; 36587a984708SDavid Chisnall if (__c(*__x2, *__x1)) 36597a984708SDavid Chisnall { 36607a984708SDavid Chisnall swap(*__x1, *__x2); 36617a984708SDavid Chisnall ++__r; 36627a984708SDavid Chisnall } 36637a984708SDavid Chisnall } 36647a984708SDavid Chisnall } 36657a984708SDavid Chisnall } 36667a984708SDavid Chisnall return __r; 36677a984708SDavid Chisnall} 36687a984708SDavid Chisnall 36697a984708SDavid Chisnall// Assumes size > 0 36707a984708SDavid Chisnalltemplate <class _Compare, class _BirdirectionalIterator> 36717a984708SDavid Chisnallvoid 36727a984708SDavid Chisnall__selection_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp) 36737a984708SDavid Chisnall{ 36747a984708SDavid Chisnall _BirdirectionalIterator __lm1 = __last; 36757a984708SDavid Chisnall for (--__lm1; __first != __lm1; ++__first) 36767a984708SDavid Chisnall { 36777a984708SDavid Chisnall _BirdirectionalIterator __i = _VSTD::min_element<_BirdirectionalIterator, 36787a984708SDavid Chisnall typename add_lvalue_reference<_Compare>::type> 36797a984708SDavid Chisnall (__first, __last, __comp); 36807a984708SDavid Chisnall if (__i != __first) 36817a984708SDavid Chisnall swap(*__first, *__i); 36827a984708SDavid Chisnall } 36837a984708SDavid Chisnall} 36847a984708SDavid Chisnall 36857a984708SDavid Chisnalltemplate <class _Compare, class _BirdirectionalIterator> 36867a984708SDavid Chisnallvoid 36877a984708SDavid Chisnall__insertion_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp) 36887a984708SDavid Chisnall{ 36897a984708SDavid Chisnall typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type; 36907a984708SDavid Chisnall if (__first != __last) 36917a984708SDavid Chisnall { 36927a984708SDavid Chisnall _BirdirectionalIterator __i = __first; 36937a984708SDavid Chisnall for (++__i; __i != __last; ++__i) 36947a984708SDavid Chisnall { 36957a984708SDavid Chisnall _BirdirectionalIterator __j = __i; 36967a984708SDavid Chisnall value_type __t(_VSTD::move(*__j)); 36977a984708SDavid Chisnall for (_BirdirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j) 36987a984708SDavid Chisnall *__j = _VSTD::move(*__k); 36997a984708SDavid Chisnall *__j = _VSTD::move(__t); 37007a984708SDavid Chisnall } 37017a984708SDavid Chisnall } 37027a984708SDavid Chisnall} 37037a984708SDavid Chisnall 37047a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 37057a984708SDavid Chisnallvoid 37067a984708SDavid Chisnall__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 37077a984708SDavid Chisnall{ 37087a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 37097a984708SDavid Chisnall _RandomAccessIterator __j = __first+2; 37107a984708SDavid Chisnall __sort3<_Compare>(__first, __first+1, __j, __comp); 37117a984708SDavid Chisnall for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) 37127a984708SDavid Chisnall { 37137a984708SDavid Chisnall if (__comp(*__i, *__j)) 37147a984708SDavid Chisnall { 37157a984708SDavid Chisnall value_type __t(_VSTD::move(*__i)); 37167a984708SDavid Chisnall _RandomAccessIterator __k = __j; 37177a984708SDavid Chisnall __j = __i; 37187a984708SDavid Chisnall do 37197a984708SDavid Chisnall { 37207a984708SDavid Chisnall *__j = _VSTD::move(*__k); 37217a984708SDavid Chisnall __j = __k; 37227a984708SDavid Chisnall } while (__j != __first && __comp(__t, *--__k)); 37237a984708SDavid Chisnall *__j = _VSTD::move(__t); 37247a984708SDavid Chisnall } 37257a984708SDavid Chisnall __j = __i; 37267a984708SDavid Chisnall } 37277a984708SDavid Chisnall} 37287a984708SDavid Chisnall 37297a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 37307a984708SDavid Chisnallbool 37317a984708SDavid Chisnall__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 37327a984708SDavid Chisnall{ 37337a984708SDavid Chisnall switch (__last - __first) 37347a984708SDavid Chisnall { 37357a984708SDavid Chisnall case 0: 37367a984708SDavid Chisnall case 1: 37377a984708SDavid Chisnall return true; 37387a984708SDavid Chisnall case 2: 37397a984708SDavid Chisnall if (__comp(*--__last, *__first)) 37407a984708SDavid Chisnall swap(*__first, *__last); 37417a984708SDavid Chisnall return true; 37427a984708SDavid Chisnall case 3: 37437a984708SDavid Chisnall _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); 37447a984708SDavid Chisnall return true; 37457a984708SDavid Chisnall case 4: 37467a984708SDavid Chisnall _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); 37477a984708SDavid Chisnall return true; 37487a984708SDavid Chisnall case 5: 37497a984708SDavid Chisnall _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); 37507a984708SDavid Chisnall return true; 37517a984708SDavid Chisnall } 37527a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 37537a984708SDavid Chisnall _RandomAccessIterator __j = __first+2; 37547a984708SDavid Chisnall __sort3<_Compare>(__first, __first+1, __j, __comp); 37557a984708SDavid Chisnall const unsigned __limit = 8; 37567a984708SDavid Chisnall unsigned __count = 0; 37577a984708SDavid Chisnall for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) 37587a984708SDavid Chisnall { 37597a984708SDavid Chisnall if (__comp(*__i, *__j)) 37607a984708SDavid Chisnall { 37617a984708SDavid Chisnall value_type __t(_VSTD::move(*__i)); 37627a984708SDavid Chisnall _RandomAccessIterator __k = __j; 37637a984708SDavid Chisnall __j = __i; 37647a984708SDavid Chisnall do 37657a984708SDavid Chisnall { 37667a984708SDavid Chisnall *__j = _VSTD::move(*__k); 37677a984708SDavid Chisnall __j = __k; 37687a984708SDavid Chisnall } while (__j != __first && __comp(__t, *--__k)); 37697a984708SDavid Chisnall *__j = _VSTD::move(__t); 37707a984708SDavid Chisnall if (++__count == __limit) 37717a984708SDavid Chisnall return ++__i == __last; 37727a984708SDavid Chisnall } 37737a984708SDavid Chisnall __j = __i; 37747a984708SDavid Chisnall } 37757a984708SDavid Chisnall return true; 37767a984708SDavid Chisnall} 37777a984708SDavid Chisnall 37787a984708SDavid Chisnalltemplate <class _Compare, class _BirdirectionalIterator> 37797a984708SDavid Chisnallvoid 37807a984708SDavid Chisnall__insertion_sort_move(_BirdirectionalIterator __first1, _BirdirectionalIterator __last1, 37817a984708SDavid Chisnall typename iterator_traits<_BirdirectionalIterator>::value_type* __first2, _Compare __comp) 37827a984708SDavid Chisnall{ 37837a984708SDavid Chisnall typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type; 37847a984708SDavid Chisnall if (__first1 != __last1) 37857a984708SDavid Chisnall { 37867a984708SDavid Chisnall __destruct_n __d(0); 37877a984708SDavid Chisnall unique_ptr<value_type, __destruct_n&> __h(__first2, __d); 37887a984708SDavid Chisnall value_type* __last2 = __first2; 37897a984708SDavid Chisnall ::new(__last2) value_type(_VSTD::move(*__first1)); 37907a984708SDavid Chisnall __d.__incr((value_type*)0); 37917a984708SDavid Chisnall for (++__last2; ++__first1 != __last1; ++__last2) 37927a984708SDavid Chisnall { 37937a984708SDavid Chisnall value_type* __j2 = __last2; 37947a984708SDavid Chisnall value_type* __i2 = __j2; 37957a984708SDavid Chisnall if (__comp(*__first1, *--__i2)) 37967a984708SDavid Chisnall { 37977a984708SDavid Chisnall ::new(__j2) value_type(_VSTD::move(*__i2)); 37987a984708SDavid Chisnall __d.__incr((value_type*)0); 37997a984708SDavid Chisnall for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2) 38007a984708SDavid Chisnall *__j2 = _VSTD::move(*__i2); 38017a984708SDavid Chisnall *__j2 = _VSTD::move(*__first1); 38027a984708SDavid Chisnall } 38037a984708SDavid Chisnall else 38047a984708SDavid Chisnall { 38057a984708SDavid Chisnall ::new(__j2) value_type(_VSTD::move(*__first1)); 38067a984708SDavid Chisnall __d.__incr((value_type*)0); 38077a984708SDavid Chisnall } 38087a984708SDavid Chisnall } 38097a984708SDavid Chisnall __h.release(); 38107a984708SDavid Chisnall } 38117a984708SDavid Chisnall} 38127a984708SDavid Chisnall 38137a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 38147a984708SDavid Chisnallvoid 38157a984708SDavid Chisnall__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 38167a984708SDavid Chisnall{ 38177a984708SDavid Chisnall // _Compare is known to be a reference type 38187a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 38197a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 38207a984708SDavid Chisnall const difference_type __limit = is_trivially_copy_constructible<value_type>::value && 38217a984708SDavid Chisnall is_trivially_copy_assignable<value_type>::value ? 30 : 6; 38227a984708SDavid Chisnall while (true) 38237a984708SDavid Chisnall { 38247a984708SDavid Chisnall __restart: 38257a984708SDavid Chisnall difference_type __len = __last - __first; 38267a984708SDavid Chisnall switch (__len) 38277a984708SDavid Chisnall { 38287a984708SDavid Chisnall case 0: 38297a984708SDavid Chisnall case 1: 38307a984708SDavid Chisnall return; 38317a984708SDavid Chisnall case 2: 38327a984708SDavid Chisnall if (__comp(*--__last, *__first)) 38337a984708SDavid Chisnall swap(*__first, *__last); 38347a984708SDavid Chisnall return; 38357a984708SDavid Chisnall case 3: 38367a984708SDavid Chisnall _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); 38377a984708SDavid Chisnall return; 38387a984708SDavid Chisnall case 4: 38397a984708SDavid Chisnall _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); 38407a984708SDavid Chisnall return; 38417a984708SDavid Chisnall case 5: 38427a984708SDavid Chisnall _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); 38437a984708SDavid Chisnall return; 38447a984708SDavid Chisnall } 38457a984708SDavid Chisnall if (__len <= __limit) 38467a984708SDavid Chisnall { 38477a984708SDavid Chisnall _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp); 38487a984708SDavid Chisnall return; 38497a984708SDavid Chisnall } 38507a984708SDavid Chisnall // __len > 5 38517a984708SDavid Chisnall _RandomAccessIterator __m = __first; 38527a984708SDavid Chisnall _RandomAccessIterator __lm1 = __last; 38537a984708SDavid Chisnall --__lm1; 38547a984708SDavid Chisnall unsigned __n_swaps; 38557a984708SDavid Chisnall { 38567a984708SDavid Chisnall difference_type __delta; 38577a984708SDavid Chisnall if (__len >= 1000) 38587a984708SDavid Chisnall { 38597a984708SDavid Chisnall __delta = __len/2; 38607a984708SDavid Chisnall __m += __delta; 38617a984708SDavid Chisnall __delta /= 2; 38627a984708SDavid Chisnall __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp); 38637a984708SDavid Chisnall } 38647a984708SDavid Chisnall else 38657a984708SDavid Chisnall { 38667a984708SDavid Chisnall __delta = __len/2; 38677a984708SDavid Chisnall __m += __delta; 38687a984708SDavid Chisnall __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp); 38697a984708SDavid Chisnall } 38707a984708SDavid Chisnall } 38717a984708SDavid Chisnall // *__m is median 38727a984708SDavid Chisnall // partition [__first, __m) < *__m and *__m <= [__m, __last) 38737a984708SDavid Chisnall // (this inhibits tossing elements equivalent to __m around unnecessarily) 38747a984708SDavid Chisnall _RandomAccessIterator __i = __first; 38757a984708SDavid Chisnall _RandomAccessIterator __j = __lm1; 38767a984708SDavid Chisnall // j points beyond range to be tested, *__m is known to be <= *__lm1 38777a984708SDavid Chisnall // The search going up is known to be guarded but the search coming down isn't. 38787a984708SDavid Chisnall // Prime the downward search with a guard. 38797a984708SDavid Chisnall if (!__comp(*__i, *__m)) // if *__first == *__m 38807a984708SDavid Chisnall { 38817a984708SDavid Chisnall // *__first == *__m, *__first doesn't go in first part 38827a984708SDavid Chisnall // manually guard downward moving __j against __i 38837a984708SDavid Chisnall while (true) 38847a984708SDavid Chisnall { 38857a984708SDavid Chisnall if (__i == --__j) 38867a984708SDavid Chisnall { 38877a984708SDavid Chisnall // *__first == *__m, *__m <= all other elements 38887a984708SDavid Chisnall // Parition instead into [__first, __i) == *__first and *__first < [__i, __last) 38897a984708SDavid Chisnall ++__i; // __first + 1 38907a984708SDavid Chisnall __j = __last; 38917a984708SDavid Chisnall if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1) 38927a984708SDavid Chisnall { 38937a984708SDavid Chisnall while (true) 38947a984708SDavid Chisnall { 38957a984708SDavid Chisnall if (__i == __j) 38967a984708SDavid Chisnall return; // [__first, __last) all equivalent elements 38977a984708SDavid Chisnall if (__comp(*__first, *__i)) 38987a984708SDavid Chisnall { 38997a984708SDavid Chisnall swap(*__i, *__j); 39007a984708SDavid Chisnall ++__n_swaps; 39017a984708SDavid Chisnall ++__i; 39027a984708SDavid Chisnall break; 39037a984708SDavid Chisnall } 39047a984708SDavid Chisnall ++__i; 39057a984708SDavid Chisnall } 39067a984708SDavid Chisnall } 39077a984708SDavid Chisnall // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 39087a984708SDavid Chisnall if (__i == __j) 39097a984708SDavid Chisnall return; 39107a984708SDavid Chisnall while (true) 39117a984708SDavid Chisnall { 39127a984708SDavid Chisnall while (!__comp(*__first, *__i)) 39137a984708SDavid Chisnall ++__i; 39147a984708SDavid Chisnall while (__comp(*__first, *--__j)) 39157a984708SDavid Chisnall ; 39167a984708SDavid Chisnall if (__i >= __j) 39177a984708SDavid Chisnall break; 39187a984708SDavid Chisnall swap(*__i, *__j); 39197a984708SDavid Chisnall ++__n_swaps; 39207a984708SDavid Chisnall ++__i; 39217a984708SDavid Chisnall } 39227a984708SDavid Chisnall // [__first, __i) == *__first and *__first < [__i, __last) 39237a984708SDavid Chisnall // The first part is sorted, sort the secod part 39247a984708SDavid Chisnall // _VSTD::__sort<_Compare>(__i, __last, __comp); 39257a984708SDavid Chisnall __first = __i; 39267a984708SDavid Chisnall goto __restart; 39277a984708SDavid Chisnall } 39287a984708SDavid Chisnall if (__comp(*__j, *__m)) 39297a984708SDavid Chisnall { 39307a984708SDavid Chisnall swap(*__i, *__j); 39317a984708SDavid Chisnall ++__n_swaps; 39327a984708SDavid Chisnall break; // found guard for downward moving __j, now use unguarded partition 39337a984708SDavid Chisnall } 39347a984708SDavid Chisnall } 39357a984708SDavid Chisnall } 39367a984708SDavid Chisnall // It is known that *__i < *__m 39377a984708SDavid Chisnall ++__i; 39387a984708SDavid Chisnall // j points beyond range to be tested, *__m is known to be <= *__lm1 39397a984708SDavid Chisnall // if not yet partitioned... 39407a984708SDavid Chisnall if (__i < __j) 39417a984708SDavid Chisnall { 39427a984708SDavid Chisnall // known that *(__i - 1) < *__m 39437a984708SDavid Chisnall // known that __i <= __m 39447a984708SDavid Chisnall while (true) 39457a984708SDavid Chisnall { 39467a984708SDavid Chisnall // __m still guards upward moving __i 39477a984708SDavid Chisnall while (__comp(*__i, *__m)) 39487a984708SDavid Chisnall ++__i; 39497a984708SDavid Chisnall // It is now known that a guard exists for downward moving __j 39507a984708SDavid Chisnall while (!__comp(*--__j, *__m)) 39517a984708SDavid Chisnall ; 39527a984708SDavid Chisnall if (__i > __j) 39537a984708SDavid Chisnall break; 39547a984708SDavid Chisnall swap(*__i, *__j); 39557a984708SDavid Chisnall ++__n_swaps; 39567a984708SDavid Chisnall // It is known that __m != __j 39577a984708SDavid Chisnall // If __m just moved, follow it 39587a984708SDavid Chisnall if (__m == __i) 39597a984708SDavid Chisnall __m = __j; 39607a984708SDavid Chisnall ++__i; 39617a984708SDavid Chisnall } 39627a984708SDavid Chisnall } 39637a984708SDavid Chisnall // [__first, __i) < *__m and *__m <= [__i, __last) 39647a984708SDavid Chisnall if (__i != __m && __comp(*__m, *__i)) 39657a984708SDavid Chisnall { 39667a984708SDavid Chisnall swap(*__i, *__m); 39677a984708SDavid Chisnall ++__n_swaps; 39687a984708SDavid Chisnall } 39697a984708SDavid Chisnall // [__first, __i) < *__i and *__i <= [__i+1, __last) 39707a984708SDavid Chisnall // If we were given a perfect partition, see if insertion sort is quick... 39717a984708SDavid Chisnall if (__n_swaps == 0) 39727a984708SDavid Chisnall { 39737a984708SDavid Chisnall bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp); 39747a984708SDavid Chisnall if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp)) 39757a984708SDavid Chisnall { 39767a984708SDavid Chisnall if (__fs) 39777a984708SDavid Chisnall return; 39787a984708SDavid Chisnall __last = __i; 39797a984708SDavid Chisnall continue; 39807a984708SDavid Chisnall } 39817a984708SDavid Chisnall else 39827a984708SDavid Chisnall { 39837a984708SDavid Chisnall if (__fs) 39847a984708SDavid Chisnall { 39857a984708SDavid Chisnall __first = ++__i; 39867a984708SDavid Chisnall continue; 39877a984708SDavid Chisnall } 39887a984708SDavid Chisnall } 39897a984708SDavid Chisnall } 39907a984708SDavid Chisnall // sort smaller range with recursive call and larger with tail recursion elimination 39917a984708SDavid Chisnall if (__i - __first < __last - __i) 39927a984708SDavid Chisnall { 39937a984708SDavid Chisnall _VSTD::__sort<_Compare>(__first, __i, __comp); 39947a984708SDavid Chisnall // _VSTD::__sort<_Compare>(__i+1, __last, __comp); 39957a984708SDavid Chisnall __first = ++__i; 39967a984708SDavid Chisnall } 39977a984708SDavid Chisnall else 39987a984708SDavid Chisnall { 39997a984708SDavid Chisnall _VSTD::__sort<_Compare>(__i+1, __last, __comp); 40007a984708SDavid Chisnall // _VSTD::__sort<_Compare>(__first, __i, __comp); 40017a984708SDavid Chisnall __last = __i; 40027a984708SDavid Chisnall } 40037a984708SDavid Chisnall } 40047a984708SDavid Chisnall} 40057a984708SDavid Chisnall 40067a984708SDavid Chisnall// This forwarder keeps the top call and the recursive calls using the same instantiation, forcing a reference _Compare 40077a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _Compare> 40087a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 40097a984708SDavid Chisnallvoid 40107a984708SDavid Chisnallsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 40117a984708SDavid Chisnall{ 40124f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 40137a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 40147a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 40157a984708SDavid Chisnall __sort<_Comp_ref>(__first, __last, __c); 40164f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 40177a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 40187a984708SDavid Chisnall __sort<_Comp_ref>(__first, __last, __comp); 40194f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 40207a984708SDavid Chisnall} 40217a984708SDavid Chisnall 40227a984708SDavid Chisnalltemplate <class _RandomAccessIterator> 40237a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 40247a984708SDavid Chisnallvoid 40257a984708SDavid Chisnallsort(_RandomAccessIterator __first, _RandomAccessIterator __last) 40267a984708SDavid Chisnall{ 40277a984708SDavid Chisnall _VSTD::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 40287a984708SDavid Chisnall} 40297a984708SDavid Chisnall 40307a984708SDavid Chisnalltemplate <class _Tp> 40317a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 40327a984708SDavid Chisnallvoid 40337a984708SDavid Chisnallsort(_Tp** __first, _Tp** __last) 40347a984708SDavid Chisnall{ 40357a984708SDavid Chisnall _VSTD::sort((size_t*)__first, (size_t*)__last, __less<size_t>()); 40367a984708SDavid Chisnall} 40377a984708SDavid Chisnall 40387a984708SDavid Chisnalltemplate <class _Tp> 40397a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 40407a984708SDavid Chisnallvoid 40417a984708SDavid Chisnallsort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last) 40427a984708SDavid Chisnall{ 40437a984708SDavid Chisnall _VSTD::sort(__first.base(), __last.base()); 40447a984708SDavid Chisnall} 40457a984708SDavid Chisnall 40467a984708SDavid Chisnalltemplate <class _Tp, class _Compare> 40477a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 40487a984708SDavid Chisnallvoid 40497a984708SDavid Chisnallsort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last, _Compare __comp) 40507a984708SDavid Chisnall{ 40517a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 40527a984708SDavid Chisnall _VSTD::sort<_Tp*, _Comp_ref>(__first.base(), __last.base(), __comp); 40537a984708SDavid Chisnall} 40547a984708SDavid Chisnall 40554f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&)) 40564f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&)) 40574f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&)) 40584f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&)) 40594f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&)) 40604f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&)) 40614f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&)) 40624f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&)) 40634f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&)) 40644f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&)) 40654f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&)) 40664f7ab58eSDimitry 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>&)) 40674f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&)) 40684f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&)) 40694f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&)) 40707a984708SDavid Chisnall 40714f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&)) 40724f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&)) 40734f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&)) 40744f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&)) 40754f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&)) 40764f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&)) 40774f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&)) 40784f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&)) 40794f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&)) 40804f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&)) 40814f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&)) 40824f7ab58eSDimitry 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>&)) 40834f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&)) 40844f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&)) 40854f7ab58eSDimitry Andric_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&)) 40867a984708SDavid Chisnall 40874f7ab58eSDimitry 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>&)) 40887a984708SDavid Chisnall 40897a984708SDavid Chisnall// lower_bound 40907a984708SDavid Chisnall 40917a984708SDavid Chisnalltemplate <class _Compare, class _ForwardIterator, class _Tp> 40924ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 40937a984708SDavid Chisnall__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 40947a984708SDavid Chisnall{ 40957a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 40967a984708SDavid Chisnall difference_type __len = _VSTD::distance(__first, __last); 40977a984708SDavid Chisnall while (__len != 0) 40987a984708SDavid Chisnall { 4099*b5893f02SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 41007a984708SDavid Chisnall _ForwardIterator __m = __first; 41017a984708SDavid Chisnall _VSTD::advance(__m, __l2); 41027a984708SDavid Chisnall if (__comp(*__m, __value_)) 41037a984708SDavid Chisnall { 41047a984708SDavid Chisnall __first = ++__m; 41057a984708SDavid Chisnall __len -= __l2 + 1; 41067a984708SDavid Chisnall } 41077a984708SDavid Chisnall else 41087a984708SDavid Chisnall __len = __l2; 41097a984708SDavid Chisnall } 41107a984708SDavid Chisnall return __first; 41117a984708SDavid Chisnall} 41127a984708SDavid Chisnall 41137a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp, class _Compare> 41144ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 41157a984708SDavid Chisnall_ForwardIterator 41167a984708SDavid Chisnalllower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 41177a984708SDavid Chisnall{ 41187a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 41197a984708SDavid Chisnall return __lower_bound<_Comp_ref>(__first, __last, __value_, __comp); 41207a984708SDavid Chisnall} 41217a984708SDavid Chisnall 41227a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp> 41234ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 41247a984708SDavid Chisnall_ForwardIterator 41257a984708SDavid Chisnalllower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 41267a984708SDavid Chisnall{ 41277a984708SDavid Chisnall return _VSTD::lower_bound(__first, __last, __value_, 41287a984708SDavid Chisnall __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); 41297a984708SDavid Chisnall} 41307a984708SDavid Chisnall 41317a984708SDavid Chisnall// upper_bound 41327a984708SDavid Chisnall 41337a984708SDavid Chisnalltemplate <class _Compare, class _ForwardIterator, class _Tp> 41344ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 41357a984708SDavid Chisnall__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 41367a984708SDavid Chisnall{ 41377a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 41387a984708SDavid Chisnall difference_type __len = _VSTD::distance(__first, __last); 41397a984708SDavid Chisnall while (__len != 0) 41407a984708SDavid Chisnall { 4141*b5893f02SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 41427a984708SDavid Chisnall _ForwardIterator __m = __first; 41437a984708SDavid Chisnall _VSTD::advance(__m, __l2); 41447a984708SDavid Chisnall if (__comp(__value_, *__m)) 41457a984708SDavid Chisnall __len = __l2; 41467a984708SDavid Chisnall else 41477a984708SDavid Chisnall { 41487a984708SDavid Chisnall __first = ++__m; 41497a984708SDavid Chisnall __len -= __l2 + 1; 41507a984708SDavid Chisnall } 41517a984708SDavid Chisnall } 41527a984708SDavid Chisnall return __first; 41537a984708SDavid Chisnall} 41547a984708SDavid Chisnall 41557a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp, class _Compare> 41564ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 41577a984708SDavid Chisnall_ForwardIterator 41587a984708SDavid Chisnallupper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 41597a984708SDavid Chisnall{ 41607a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 41617a984708SDavid Chisnall return __upper_bound<_Comp_ref>(__first, __last, __value_, __comp); 41627a984708SDavid Chisnall} 41637a984708SDavid Chisnall 41647a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp> 41654ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 41667a984708SDavid Chisnall_ForwardIterator 41677a984708SDavid Chisnallupper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 41687a984708SDavid Chisnall{ 41697a984708SDavid Chisnall return _VSTD::upper_bound(__first, __last, __value_, 41707a984708SDavid Chisnall __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); 41717a984708SDavid Chisnall} 41727a984708SDavid Chisnall 41737a984708SDavid Chisnall// equal_range 41747a984708SDavid Chisnall 41757a984708SDavid Chisnalltemplate <class _Compare, class _ForwardIterator, class _Tp> 41764ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> 41777a984708SDavid Chisnall__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 41787a984708SDavid Chisnall{ 41797a984708SDavid Chisnall typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; 41807a984708SDavid Chisnall difference_type __len = _VSTD::distance(__first, __last); 41817a984708SDavid Chisnall while (__len != 0) 41827a984708SDavid Chisnall { 4183*b5893f02SDimitry Andric difference_type __l2 = _VSTD::__half_positive(__len); 41847a984708SDavid Chisnall _ForwardIterator __m = __first; 41857a984708SDavid Chisnall _VSTD::advance(__m, __l2); 41867a984708SDavid Chisnall if (__comp(*__m, __value_)) 41877a984708SDavid Chisnall { 41887a984708SDavid Chisnall __first = ++__m; 41897a984708SDavid Chisnall __len -= __l2 + 1; 41907a984708SDavid Chisnall } 41917a984708SDavid Chisnall else if (__comp(__value_, *__m)) 41927a984708SDavid Chisnall { 41937a984708SDavid Chisnall __last = __m; 41947a984708SDavid Chisnall __len = __l2; 41957a984708SDavid Chisnall } 41967a984708SDavid Chisnall else 41977a984708SDavid Chisnall { 41987a984708SDavid Chisnall _ForwardIterator __mp1 = __m; 41997a984708SDavid Chisnall return pair<_ForwardIterator, _ForwardIterator> 42007a984708SDavid Chisnall ( 42017a984708SDavid Chisnall __lower_bound<_Compare>(__first, __m, __value_, __comp), 42027a984708SDavid Chisnall __upper_bound<_Compare>(++__mp1, __last, __value_, __comp) 42037a984708SDavid Chisnall ); 42047a984708SDavid Chisnall } 42057a984708SDavid Chisnall } 42067a984708SDavid Chisnall return pair<_ForwardIterator, _ForwardIterator>(__first, __first); 42077a984708SDavid Chisnall} 42087a984708SDavid Chisnall 42097a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp, class _Compare> 42104ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 42117a984708SDavid Chisnallpair<_ForwardIterator, _ForwardIterator> 42127a984708SDavid Chisnallequal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 42137a984708SDavid Chisnall{ 42144f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 42157a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 42167a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 42177a984708SDavid Chisnall return __equal_range<_Comp_ref>(__first, __last, __value_, __c); 42184f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 42197a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 42207a984708SDavid Chisnall return __equal_range<_Comp_ref>(__first, __last, __value_, __comp); 42214f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 42227a984708SDavid Chisnall} 42237a984708SDavid Chisnall 42247a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp> 42254ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 42267a984708SDavid Chisnallpair<_ForwardIterator, _ForwardIterator> 42277a984708SDavid Chisnallequal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 42287a984708SDavid Chisnall{ 42297a984708SDavid Chisnall return _VSTD::equal_range(__first, __last, __value_, 42307a984708SDavid Chisnall __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); 42317a984708SDavid Chisnall} 42327a984708SDavid Chisnall 42337a984708SDavid Chisnall// binary_search 42347a984708SDavid Chisnall 42357a984708SDavid Chisnalltemplate <class _Compare, class _ForwardIterator, class _Tp> 42364ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 42377a984708SDavid Chisnallbool 42387a984708SDavid Chisnall__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 42397a984708SDavid Chisnall{ 42407a984708SDavid Chisnall __first = __lower_bound<_Compare>(__first, __last, __value_, __comp); 42417a984708SDavid Chisnall return __first != __last && !__comp(__value_, *__first); 42427a984708SDavid Chisnall} 42437a984708SDavid Chisnall 42447a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp, class _Compare> 42454ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 42467a984708SDavid Chisnallbool 42477a984708SDavid Chisnallbinary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) 42487a984708SDavid Chisnall{ 42494f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 42507a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 42517a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 42527a984708SDavid Chisnall return __binary_search<_Comp_ref>(__first, __last, __value_, __c); 42534f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 42547a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 42557a984708SDavid Chisnall return __binary_search<_Comp_ref>(__first, __last, __value_, __comp); 42564f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 42577a984708SDavid Chisnall} 42587a984708SDavid Chisnall 42597a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp> 42604ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 42617a984708SDavid Chisnallbool 42627a984708SDavid Chisnallbinary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) 42637a984708SDavid Chisnall{ 42647a984708SDavid Chisnall return _VSTD::binary_search(__first, __last, __value_, 42657a984708SDavid Chisnall __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); 42667a984708SDavid Chisnall} 42677a984708SDavid Chisnall 42687a984708SDavid Chisnall// merge 42697a984708SDavid Chisnall 42707a984708SDavid Chisnalltemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 42717a984708SDavid Chisnall_OutputIterator 42727a984708SDavid Chisnall__merge(_InputIterator1 __first1, _InputIterator1 __last1, 42737a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 42747a984708SDavid Chisnall{ 42757a984708SDavid Chisnall for (; __first1 != __last1; ++__result) 42767a984708SDavid Chisnall { 42777a984708SDavid Chisnall if (__first2 == __last2) 42787a984708SDavid Chisnall return _VSTD::copy(__first1, __last1, __result); 42797a984708SDavid Chisnall if (__comp(*__first2, *__first1)) 42807a984708SDavid Chisnall { 42817a984708SDavid Chisnall *__result = *__first2; 42827a984708SDavid Chisnall ++__first2; 42837a984708SDavid Chisnall } 42847a984708SDavid Chisnall else 42857a984708SDavid Chisnall { 42867a984708SDavid Chisnall *__result = *__first1; 42877a984708SDavid Chisnall ++__first1; 42887a984708SDavid Chisnall } 42897a984708SDavid Chisnall } 42907a984708SDavid Chisnall return _VSTD::copy(__first2, __last2, __result); 42917a984708SDavid Chisnall} 42927a984708SDavid Chisnall 42937a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 42947a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 42957a984708SDavid Chisnall_OutputIterator 42967a984708SDavid Chisnallmerge(_InputIterator1 __first1, _InputIterator1 __last1, 42977a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 42987a984708SDavid Chisnall{ 42994f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 43007a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 43017a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 43027a984708SDavid Chisnall return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); 43034f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 43047a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 43057a984708SDavid Chisnall return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 43064f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 43077a984708SDavid Chisnall} 43087a984708SDavid Chisnall 43097a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 43107a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 43117a984708SDavid Chisnall_OutputIterator 43127a984708SDavid Chisnallmerge(_InputIterator1 __first1, _InputIterator1 __last1, 43137a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 43147a984708SDavid Chisnall{ 43157a984708SDavid Chisnall typedef typename iterator_traits<_InputIterator1>::value_type __v1; 43167a984708SDavid Chisnall typedef typename iterator_traits<_InputIterator2>::value_type __v2; 43177a984708SDavid Chisnall return merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>()); 43187a984708SDavid Chisnall} 43197a984708SDavid Chisnall 43207a984708SDavid Chisnall// inplace_merge 43217a984708SDavid Chisnall 4322854fa44bSDimitry Andrictemplate <class _Compare, class _InputIterator1, class _InputIterator2, 4323854fa44bSDimitry Andric class _OutputIterator> 4324854fa44bSDimitry Andricvoid __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1, 4325854fa44bSDimitry Andric _InputIterator2 __first2, _InputIterator2 __last2, 4326854fa44bSDimitry Andric _OutputIterator __result, _Compare __comp) 4327854fa44bSDimitry Andric{ 4328854fa44bSDimitry Andric for (; __first1 != __last1; ++__result) 4329854fa44bSDimitry Andric { 4330854fa44bSDimitry Andric if (__first2 == __last2) 4331854fa44bSDimitry Andric { 4332854fa44bSDimitry Andric _VSTD::move(__first1, __last1, __result); 4333854fa44bSDimitry Andric return; 4334854fa44bSDimitry Andric } 4335854fa44bSDimitry Andric 4336854fa44bSDimitry Andric if (__comp(*__first2, *__first1)) 4337854fa44bSDimitry Andric { 4338854fa44bSDimitry Andric *__result = _VSTD::move(*__first2); 4339854fa44bSDimitry Andric ++__first2; 4340854fa44bSDimitry Andric } 4341854fa44bSDimitry Andric else 4342854fa44bSDimitry Andric { 4343854fa44bSDimitry Andric *__result = _VSTD::move(*__first1); 4344854fa44bSDimitry Andric ++__first1; 4345854fa44bSDimitry Andric } 4346854fa44bSDimitry Andric } 4347854fa44bSDimitry Andric // __first2 through __last2 are already in the right spot. 4348854fa44bSDimitry Andric} 4349854fa44bSDimitry Andric 43507a984708SDavid Chisnalltemplate <class _Compare, class _BidirectionalIterator> 43517a984708SDavid Chisnallvoid 43527a984708SDavid Chisnall__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 43537a984708SDavid Chisnall _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, 43547a984708SDavid Chisnall typename iterator_traits<_BidirectionalIterator>::difference_type __len2, 43557a984708SDavid Chisnall typename iterator_traits<_BidirectionalIterator>::value_type* __buff) 43567a984708SDavid Chisnall{ 43577a984708SDavid Chisnall typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 43587a984708SDavid Chisnall __destruct_n __d(0); 43597a984708SDavid Chisnall unique_ptr<value_type, __destruct_n&> __h2(__buff, __d); 43607a984708SDavid Chisnall if (__len1 <= __len2) 43617a984708SDavid Chisnall { 43627a984708SDavid Chisnall value_type* __p = __buff; 4363d72607e9SDimitry Andric for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), (void) ++__i, ++__p) 43647a984708SDavid Chisnall ::new(__p) value_type(_VSTD::move(*__i)); 4365854fa44bSDimitry Andric __half_inplace_merge(__buff, __p, __middle, __last, __first, __comp); 43667a984708SDavid Chisnall } 43677a984708SDavid Chisnall else 43687a984708SDavid Chisnall { 43697a984708SDavid Chisnall value_type* __p = __buff; 4370d72607e9SDimitry Andric for (_BidirectionalIterator __i = __middle; __i != __last; __d.__incr((value_type*)0), (void) ++__i, ++__p) 43717a984708SDavid Chisnall ::new(__p) value_type(_VSTD::move(*__i)); 43727a984708SDavid Chisnall typedef reverse_iterator<_BidirectionalIterator> _RBi; 43737a984708SDavid Chisnall typedef reverse_iterator<value_type*> _Rv; 4374854fa44bSDimitry Andric __half_inplace_merge(_Rv(__p), _Rv(__buff), 4375854fa44bSDimitry Andric _RBi(__middle), _RBi(__first), 4376b2c7081bSDimitry Andric _RBi(__last), __invert<_Compare>(__comp)); 43777a984708SDavid Chisnall } 43787a984708SDavid Chisnall} 43797a984708SDavid Chisnall 43807a984708SDavid Chisnalltemplate <class _Compare, class _BidirectionalIterator> 43817a984708SDavid Chisnallvoid 43827a984708SDavid Chisnall__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 43837a984708SDavid Chisnall _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, 43847a984708SDavid Chisnall typename iterator_traits<_BidirectionalIterator>::difference_type __len2, 43857a984708SDavid Chisnall typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size) 43867a984708SDavid Chisnall{ 43877a984708SDavid Chisnall typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; 43887a984708SDavid Chisnall while (true) 43897a984708SDavid Chisnall { 43907a984708SDavid Chisnall // if __middle == __last, we're done 43917a984708SDavid Chisnall if (__len2 == 0) 43927a984708SDavid Chisnall return; 4393854fa44bSDimitry Andric if (__len1 <= __buff_size || __len2 <= __buff_size) 4394854fa44bSDimitry Andric return __buffered_inplace_merge<_Compare> 4395854fa44bSDimitry Andric (__first, __middle, __last, __comp, __len1, __len2, __buff); 43967a984708SDavid Chisnall // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 4397d72607e9SDimitry Andric for (; true; ++__first, (void) --__len1) 43987a984708SDavid Chisnall { 43997a984708SDavid Chisnall if (__len1 == 0) 44007a984708SDavid Chisnall return; 44017a984708SDavid Chisnall if (__comp(*__middle, *__first)) 44027a984708SDavid Chisnall break; 44037a984708SDavid Chisnall } 44047a984708SDavid Chisnall // __first < __middle < __last 44057a984708SDavid Chisnall // *__first > *__middle 44067a984708SDavid Chisnall // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that 44077a984708SDavid Chisnall // all elements in: 44087a984708SDavid Chisnall // [__first, __m1) <= [__middle, __m2) 44097a984708SDavid Chisnall // [__middle, __m2) < [__m1, __middle) 44107a984708SDavid Chisnall // [__m1, __middle) <= [__m2, __last) 44117a984708SDavid Chisnall // and __m1 or __m2 is in the middle of its range 44127a984708SDavid Chisnall _BidirectionalIterator __m1; // "median" of [__first, __middle) 44137a984708SDavid Chisnall _BidirectionalIterator __m2; // "median" of [__middle, __last) 44147a984708SDavid Chisnall difference_type __len11; // distance(__first, __m1) 44157a984708SDavid Chisnall difference_type __len21; // distance(__middle, __m2) 44167a984708SDavid Chisnall // binary search smaller range 44177a984708SDavid Chisnall if (__len1 < __len2) 44187a984708SDavid Chisnall { // __len >= 1, __len2 >= 2 44197a984708SDavid Chisnall __len21 = __len2 / 2; 44207a984708SDavid Chisnall __m2 = __middle; 44217a984708SDavid Chisnall _VSTD::advance(__m2, __len21); 44227a984708SDavid Chisnall __m1 = __upper_bound<_Compare>(__first, __middle, *__m2, __comp); 44237a984708SDavid Chisnall __len11 = _VSTD::distance(__first, __m1); 44247a984708SDavid Chisnall } 44257a984708SDavid Chisnall else 44267a984708SDavid Chisnall { 44277a984708SDavid Chisnall if (__len1 == 1) 44287a984708SDavid Chisnall { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 44297a984708SDavid Chisnall // It is known *__first > *__middle 44307a984708SDavid Chisnall swap(*__first, *__middle); 44317a984708SDavid Chisnall return; 44327a984708SDavid Chisnall } 44337a984708SDavid Chisnall // __len1 >= 2, __len2 >= 1 44347a984708SDavid Chisnall __len11 = __len1 / 2; 44357a984708SDavid Chisnall __m1 = __first; 44367a984708SDavid Chisnall _VSTD::advance(__m1, __len11); 44377a984708SDavid Chisnall __m2 = __lower_bound<_Compare>(__middle, __last, *__m1, __comp); 44387a984708SDavid Chisnall __len21 = _VSTD::distance(__middle, __m2); 44397a984708SDavid Chisnall } 44407a984708SDavid Chisnall difference_type __len12 = __len1 - __len11; // distance(__m1, __middle) 44417a984708SDavid Chisnall difference_type __len22 = __len2 - __len21; // distance(__m2, __last) 44427a984708SDavid Chisnall // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) 44437a984708SDavid Chisnall // swap middle two partitions 44447a984708SDavid Chisnall __middle = _VSTD::rotate(__m1, __middle, __m2); 44457a984708SDavid Chisnall // __len12 and __len21 now have swapped meanings 44467a984708SDavid Chisnall // merge smaller range with recurisve call and larger with tail recursion elimination 44477a984708SDavid Chisnall if (__len11 + __len21 < __len12 + __len22) 44487a984708SDavid Chisnall { 44497a984708SDavid Chisnall __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); 44507a984708SDavid Chisnall// __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); 44517a984708SDavid Chisnall __first = __middle; 44527a984708SDavid Chisnall __middle = __m2; 44537a984708SDavid Chisnall __len1 = __len12; 44547a984708SDavid Chisnall __len2 = __len22; 44557a984708SDavid Chisnall } 44567a984708SDavid Chisnall else 44577a984708SDavid Chisnall { 44587a984708SDavid Chisnall __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); 44597a984708SDavid Chisnall// __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); 44607a984708SDavid Chisnall __last = __middle; 44617a984708SDavid Chisnall __middle = __m1; 44627a984708SDavid Chisnall __len1 = __len11; 44637a984708SDavid Chisnall __len2 = __len21; 44647a984708SDavid Chisnall } 44657a984708SDavid Chisnall } 44667a984708SDavid Chisnall} 44677a984708SDavid Chisnall 44687a984708SDavid Chisnalltemplate <class _BidirectionalIterator, class _Compare> 44697a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 44707a984708SDavid Chisnallvoid 44717a984708SDavid Chisnallinplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, 44727a984708SDavid Chisnall _Compare __comp) 44737a984708SDavid Chisnall{ 44747a984708SDavid Chisnall typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; 44757a984708SDavid Chisnall typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; 44767a984708SDavid Chisnall difference_type __len1 = _VSTD::distance(__first, __middle); 44777a984708SDavid Chisnall difference_type __len2 = _VSTD::distance(__middle, __last); 44787a984708SDavid Chisnall difference_type __buf_size = _VSTD::min(__len1, __len2); 4479854fa44bSDimitry Andric pair<value_type*, ptrdiff_t> __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size); 4480854fa44bSDimitry Andric unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first); 4481854fa44bSDimitry Andric 44824f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 44837a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 44847a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 44857a984708SDavid Chisnall return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __c, __len1, __len2, 44867a984708SDavid Chisnall __buf.first, __buf.second); 44874f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 44887a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 44897a984708SDavid Chisnall return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2, 44907a984708SDavid Chisnall __buf.first, __buf.second); 44914f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 44927a984708SDavid Chisnall} 44937a984708SDavid Chisnall 44947a984708SDavid Chisnalltemplate <class _BidirectionalIterator> 44957a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 44967a984708SDavid Chisnallvoid 44977a984708SDavid Chisnallinplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) 44987a984708SDavid Chisnall{ 44997a984708SDavid Chisnall _VSTD::inplace_merge(__first, __middle, __last, 45007a984708SDavid Chisnall __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); 45017a984708SDavid Chisnall} 45027a984708SDavid Chisnall 45037a984708SDavid Chisnall// stable_sort 45047a984708SDavid Chisnall 45057a984708SDavid Chisnalltemplate <class _Compare, class _InputIterator1, class _InputIterator2> 45067a984708SDavid Chisnallvoid 45077a984708SDavid Chisnall__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, 45087a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, 45097a984708SDavid Chisnall typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp) 45107a984708SDavid Chisnall{ 45117a984708SDavid Chisnall typedef typename iterator_traits<_InputIterator1>::value_type value_type; 45127a984708SDavid Chisnall __destruct_n __d(0); 45137a984708SDavid Chisnall unique_ptr<value_type, __destruct_n&> __h(__result, __d); 45147a984708SDavid Chisnall for (; true; ++__result) 45157a984708SDavid Chisnall { 45167a984708SDavid Chisnall if (__first1 == __last1) 45177a984708SDavid Chisnall { 45187a984708SDavid Chisnall for (; __first2 != __last2; ++__first2, ++__result, __d.__incr((value_type*)0)) 45197a984708SDavid Chisnall ::new (__result) value_type(_VSTD::move(*__first2)); 45207a984708SDavid Chisnall __h.release(); 45217a984708SDavid Chisnall return; 45227a984708SDavid Chisnall } 45237a984708SDavid Chisnall if (__first2 == __last2) 45247a984708SDavid Chisnall { 45257a984708SDavid Chisnall for (; __first1 != __last1; ++__first1, ++__result, __d.__incr((value_type*)0)) 45267a984708SDavid Chisnall ::new (__result) value_type(_VSTD::move(*__first1)); 45277a984708SDavid Chisnall __h.release(); 45287a984708SDavid Chisnall return; 45297a984708SDavid Chisnall } 45307a984708SDavid Chisnall if (__comp(*__first2, *__first1)) 45317a984708SDavid Chisnall { 45327a984708SDavid Chisnall ::new (__result) value_type(_VSTD::move(*__first2)); 45337a984708SDavid Chisnall __d.__incr((value_type*)0); 45347a984708SDavid Chisnall ++__first2; 45357a984708SDavid Chisnall } 45367a984708SDavid Chisnall else 45377a984708SDavid Chisnall { 45387a984708SDavid Chisnall ::new (__result) value_type(_VSTD::move(*__first1)); 45397a984708SDavid Chisnall __d.__incr((value_type*)0); 45407a984708SDavid Chisnall ++__first1; 45417a984708SDavid Chisnall } 45427a984708SDavid Chisnall } 45437a984708SDavid Chisnall} 45447a984708SDavid Chisnall 45457a984708SDavid Chisnalltemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 45467a984708SDavid Chisnallvoid 45477a984708SDavid Chisnall__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, 45487a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, 45497a984708SDavid Chisnall _OutputIterator __result, _Compare __comp) 45507a984708SDavid Chisnall{ 45517a984708SDavid Chisnall for (; __first1 != __last1; ++__result) 45527a984708SDavid Chisnall { 45537a984708SDavid Chisnall if (__first2 == __last2) 45547a984708SDavid Chisnall { 45557a984708SDavid Chisnall for (; __first1 != __last1; ++__first1, ++__result) 45567a984708SDavid Chisnall *__result = _VSTD::move(*__first1); 45577a984708SDavid Chisnall return; 45587a984708SDavid Chisnall } 45597a984708SDavid Chisnall if (__comp(*__first2, *__first1)) 45607a984708SDavid Chisnall { 45617a984708SDavid Chisnall *__result = _VSTD::move(*__first2); 45627a984708SDavid Chisnall ++__first2; 45637a984708SDavid Chisnall } 45647a984708SDavid Chisnall else 45657a984708SDavid Chisnall { 45667a984708SDavid Chisnall *__result = _VSTD::move(*__first1); 45677a984708SDavid Chisnall ++__first1; 45687a984708SDavid Chisnall } 45697a984708SDavid Chisnall } 45707a984708SDavid Chisnall for (; __first2 != __last2; ++__first2, ++__result) 45717a984708SDavid Chisnall *__result = _VSTD::move(*__first2); 45727a984708SDavid Chisnall} 45737a984708SDavid Chisnall 45747a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 45757a984708SDavid Chisnallvoid 45767a984708SDavid Chisnall__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 45777a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator>::difference_type __len, 45787a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size); 45797a984708SDavid Chisnall 45807a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 45817a984708SDavid Chisnallvoid 45827a984708SDavid Chisnall__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp, 45837a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator>::difference_type __len, 45847a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator>::value_type* __first2) 45857a984708SDavid Chisnall{ 45867a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 45877a984708SDavid Chisnall switch (__len) 45887a984708SDavid Chisnall { 45897a984708SDavid Chisnall case 0: 45907a984708SDavid Chisnall return; 45917a984708SDavid Chisnall case 1: 45927a984708SDavid Chisnall ::new(__first2) value_type(_VSTD::move(*__first1)); 45937a984708SDavid Chisnall return; 45947a984708SDavid Chisnall case 2: 45957a984708SDavid Chisnall __destruct_n __d(0); 45967a984708SDavid Chisnall unique_ptr<value_type, __destruct_n&> __h2(__first2, __d); 45977a984708SDavid Chisnall if (__comp(*--__last1, *__first1)) 45987a984708SDavid Chisnall { 45997a984708SDavid Chisnall ::new(__first2) value_type(_VSTD::move(*__last1)); 46007a984708SDavid Chisnall __d.__incr((value_type*)0); 46017a984708SDavid Chisnall ++__first2; 46027a984708SDavid Chisnall ::new(__first2) value_type(_VSTD::move(*__first1)); 46037a984708SDavid Chisnall } 46047a984708SDavid Chisnall else 46057a984708SDavid Chisnall { 46067a984708SDavid Chisnall ::new(__first2) value_type(_VSTD::move(*__first1)); 46077a984708SDavid Chisnall __d.__incr((value_type*)0); 46087a984708SDavid Chisnall ++__first2; 46097a984708SDavid Chisnall ::new(__first2) value_type(_VSTD::move(*__last1)); 46107a984708SDavid Chisnall } 46117a984708SDavid Chisnall __h2.release(); 46127a984708SDavid Chisnall return; 46137a984708SDavid Chisnall } 46147a984708SDavid Chisnall if (__len <= 8) 46157a984708SDavid Chisnall { 46167a984708SDavid Chisnall __insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp); 46177a984708SDavid Chisnall return; 46187a984708SDavid Chisnall } 46197a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; 46207a984708SDavid Chisnall _RandomAccessIterator __m = __first1 + __l2; 46217a984708SDavid Chisnall __stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2); 46227a984708SDavid Chisnall __stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); 46237a984708SDavid Chisnall __merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp); 46247a984708SDavid Chisnall} 46257a984708SDavid Chisnall 46267a984708SDavid Chisnalltemplate <class _Tp> 46277a984708SDavid Chisnallstruct __stable_sort_switch 46287a984708SDavid Chisnall{ 46297a984708SDavid Chisnall static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value; 46307a984708SDavid Chisnall}; 46317a984708SDavid Chisnall 46327a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 46337a984708SDavid Chisnallvoid 46347a984708SDavid Chisnall__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 46357a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator>::difference_type __len, 46367a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size) 46377a984708SDavid Chisnall{ 46387a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 46397a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 46407a984708SDavid Chisnall switch (__len) 46417a984708SDavid Chisnall { 46427a984708SDavid Chisnall case 0: 46437a984708SDavid Chisnall case 1: 46447a984708SDavid Chisnall return; 46457a984708SDavid Chisnall case 2: 46467a984708SDavid Chisnall if (__comp(*--__last, *__first)) 46477a984708SDavid Chisnall swap(*__first, *__last); 46487a984708SDavid Chisnall return; 46497a984708SDavid Chisnall } 46507a984708SDavid Chisnall if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value)) 46517a984708SDavid Chisnall { 46527a984708SDavid Chisnall __insertion_sort<_Compare>(__first, __last, __comp); 46537a984708SDavid Chisnall return; 46547a984708SDavid Chisnall } 46557a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; 46567a984708SDavid Chisnall _RandomAccessIterator __m = __first + __l2; 46577a984708SDavid Chisnall if (__len <= __buff_size) 46587a984708SDavid Chisnall { 46597a984708SDavid Chisnall __destruct_n __d(0); 46607a984708SDavid Chisnall unique_ptr<value_type, __destruct_n&> __h2(__buff, __d); 46617a984708SDavid Chisnall __stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff); 46627a984708SDavid Chisnall __d.__set(__l2, (value_type*)0); 46637a984708SDavid Chisnall __stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); 46647a984708SDavid Chisnall __d.__set(__len, (value_type*)0); 46657a984708SDavid Chisnall __merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); 46667a984708SDavid Chisnall// __merge<_Compare>(move_iterator<value_type*>(__buff), 46677a984708SDavid Chisnall// move_iterator<value_type*>(__buff + __l2), 46687a984708SDavid Chisnall// move_iterator<_RandomAccessIterator>(__buff + __l2), 46697a984708SDavid Chisnall// move_iterator<_RandomAccessIterator>(__buff + __len), 46707a984708SDavid Chisnall// __first, __comp); 46717a984708SDavid Chisnall return; 46727a984708SDavid Chisnall } 46737a984708SDavid Chisnall __stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size); 46747a984708SDavid Chisnall __stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); 46757a984708SDavid Chisnall __inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); 46767a984708SDavid Chisnall} 46777a984708SDavid Chisnall 46787a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _Compare> 46797a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 46807a984708SDavid Chisnallvoid 46817a984708SDavid Chisnallstable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 46827a984708SDavid Chisnall{ 46837a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 46847a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 46857a984708SDavid Chisnall difference_type __len = __last - __first; 46867a984708SDavid Chisnall pair<value_type*, ptrdiff_t> __buf(0, 0); 46877a984708SDavid Chisnall unique_ptr<value_type, __return_temporary_buffer> __h; 46887a984708SDavid Chisnall if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) 46897a984708SDavid Chisnall { 46907a984708SDavid Chisnall __buf = _VSTD::get_temporary_buffer<value_type>(__len); 46917a984708SDavid Chisnall __h.reset(__buf.first); 46927a984708SDavid Chisnall } 46934f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 46947a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 46957a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 46967a984708SDavid Chisnall __stable_sort<_Comp_ref>(__first, __last, __c, __len, __buf.first, __buf.second); 46974f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 46987a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 46997a984708SDavid Chisnall __stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second); 47004f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 47017a984708SDavid Chisnall} 47027a984708SDavid Chisnall 47037a984708SDavid Chisnalltemplate <class _RandomAccessIterator> 47047a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 47057a984708SDavid Chisnallvoid 47067a984708SDavid Chisnallstable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) 47077a984708SDavid Chisnall{ 47087a984708SDavid Chisnall _VSTD::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 47097a984708SDavid Chisnall} 47107a984708SDavid Chisnall 47117a984708SDavid Chisnall// is_heap_until 47127a984708SDavid Chisnall 47137a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _Compare> 47144ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator 47157a984708SDavid Chisnallis_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 47167a984708SDavid Chisnall{ 47177a984708SDavid Chisnall typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::difference_type difference_type; 47187a984708SDavid Chisnall difference_type __len = __last - __first; 47197a984708SDavid Chisnall difference_type __p = 0; 47207a984708SDavid Chisnall difference_type __c = 1; 47217a984708SDavid Chisnall _RandomAccessIterator __pp = __first; 47227a984708SDavid Chisnall while (__c < __len) 47237a984708SDavid Chisnall { 47247a984708SDavid Chisnall _RandomAccessIterator __cp = __first + __c; 47257a984708SDavid Chisnall if (__comp(*__pp, *__cp)) 47267a984708SDavid Chisnall return __cp; 47277a984708SDavid Chisnall ++__c; 47287a984708SDavid Chisnall ++__cp; 47297a984708SDavid Chisnall if (__c == __len) 47307a984708SDavid Chisnall return __last; 47317a984708SDavid Chisnall if (__comp(*__pp, *__cp)) 47327a984708SDavid Chisnall return __cp; 47337a984708SDavid Chisnall ++__p; 47347a984708SDavid Chisnall ++__pp; 47357a984708SDavid Chisnall __c = 2 * __p + 1; 47367a984708SDavid Chisnall } 47377a984708SDavid Chisnall return __last; 47387a984708SDavid Chisnall} 47397a984708SDavid Chisnall 47407a984708SDavid Chisnalltemplate<class _RandomAccessIterator> 47414ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 47427a984708SDavid Chisnall_RandomAccessIterator 47437a984708SDavid Chisnallis_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) 47447a984708SDavid Chisnall{ 47457a984708SDavid Chisnall return _VSTD::is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 47467a984708SDavid Chisnall} 47477a984708SDavid Chisnall 47487a984708SDavid Chisnall// is_heap 47497a984708SDavid Chisnall 47507a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _Compare> 47514ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 47527a984708SDavid Chisnallbool 47537a984708SDavid Chisnallis_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 47547a984708SDavid Chisnall{ 47557a984708SDavid Chisnall return _VSTD::is_heap_until(__first, __last, __comp) == __last; 47567a984708SDavid Chisnall} 47577a984708SDavid Chisnall 47587a984708SDavid Chisnalltemplate<class _RandomAccessIterator> 47594ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 47607a984708SDavid Chisnallbool 47617a984708SDavid Chisnallis_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 47627a984708SDavid Chisnall{ 47637a984708SDavid Chisnall return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 47647a984708SDavid Chisnall} 47657a984708SDavid Chisnall 47667a984708SDavid Chisnall// push_heap 47677a984708SDavid Chisnall 47687a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 47697a984708SDavid Chisnallvoid 4770d72607e9SDimitry Andric__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 47717a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator>::difference_type __len) 47727a984708SDavid Chisnall{ 47737a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 47747a984708SDavid Chisnall if (__len > 1) 47757a984708SDavid Chisnall { 47767a984708SDavid Chisnall __len = (__len - 2) / 2; 47777a984708SDavid Chisnall _RandomAccessIterator __ptr = __first + __len; 47787a984708SDavid Chisnall if (__comp(*__ptr, *--__last)) 47797a984708SDavid Chisnall { 47807a984708SDavid Chisnall value_type __t(_VSTD::move(*__last)); 47817a984708SDavid Chisnall do 47827a984708SDavid Chisnall { 47837a984708SDavid Chisnall *__last = _VSTD::move(*__ptr); 47847a984708SDavid Chisnall __last = __ptr; 47857a984708SDavid Chisnall if (__len == 0) 47867a984708SDavid Chisnall break; 47877a984708SDavid Chisnall __len = (__len - 1) / 2; 47887a984708SDavid Chisnall __ptr = __first + __len; 47897a984708SDavid Chisnall } while (__comp(*__ptr, __t)); 47907a984708SDavid Chisnall *__last = _VSTD::move(__t); 47917a984708SDavid Chisnall } 47927a984708SDavid Chisnall } 47937a984708SDavid Chisnall} 47947a984708SDavid Chisnall 47957a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _Compare> 47967a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 47977a984708SDavid Chisnallvoid 47987a984708SDavid Chisnallpush_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 47997a984708SDavid Chisnall{ 48004f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 48017a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 48027a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 4803d72607e9SDimitry Andric __sift_up<_Comp_ref>(__first, __last, __c, __last - __first); 48044f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 48057a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 4806d72607e9SDimitry Andric __sift_up<_Comp_ref>(__first, __last, __comp, __last - __first); 48074f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 48087a984708SDavid Chisnall} 48097a984708SDavid Chisnall 48107a984708SDavid Chisnalltemplate <class _RandomAccessIterator> 48117a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 48127a984708SDavid Chisnallvoid 48137a984708SDavid Chisnallpush_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 48147a984708SDavid Chisnall{ 48157a984708SDavid Chisnall _VSTD::push_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 48167a984708SDavid Chisnall} 48177a984708SDavid Chisnall 48187a984708SDavid Chisnall// pop_heap 48197a984708SDavid Chisnall 48207a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 4821d72607e9SDimitry Andricvoid 4822aed8d94eSDimitry Andric__sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, 4823aed8d94eSDimitry Andric _Compare __comp, 4824d72607e9SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len, 4825d72607e9SDimitry Andric _RandomAccessIterator __start) 4826d72607e9SDimitry Andric{ 4827d72607e9SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 4828d72607e9SDimitry Andric typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; 4829d72607e9SDimitry Andric // left-child of __start is at 2 * __start + 1 4830d72607e9SDimitry Andric // right-child of __start is at 2 * __start + 2 4831d72607e9SDimitry Andric difference_type __child = __start - __first; 4832d72607e9SDimitry Andric 4833d72607e9SDimitry Andric if (__len < 2 || (__len - 2) / 2 < __child) 4834d72607e9SDimitry Andric return; 4835d72607e9SDimitry Andric 4836d72607e9SDimitry Andric __child = 2 * __child + 1; 4837d72607e9SDimitry Andric _RandomAccessIterator __child_i = __first + __child; 4838d72607e9SDimitry Andric 4839d72607e9SDimitry Andric if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { 4840d72607e9SDimitry Andric // right-child exists and is greater than left-child 4841d72607e9SDimitry Andric ++__child_i; 4842d72607e9SDimitry Andric ++__child; 4843d72607e9SDimitry Andric } 4844d72607e9SDimitry Andric 4845d72607e9SDimitry Andric // check if we are in heap-order 4846d72607e9SDimitry Andric if (__comp(*__child_i, *__start)) 4847d72607e9SDimitry Andric // we are, __start is larger than it's largest child 4848d72607e9SDimitry Andric return; 4849d72607e9SDimitry Andric 4850d72607e9SDimitry Andric value_type __top(_VSTD::move(*__start)); 4851d72607e9SDimitry Andric do 4852d72607e9SDimitry Andric { 4853d72607e9SDimitry Andric // we are not in heap-order, swap the parent with it's largest child 4854d72607e9SDimitry Andric *__start = _VSTD::move(*__child_i); 4855d72607e9SDimitry Andric __start = __child_i; 4856d72607e9SDimitry Andric 4857d72607e9SDimitry Andric if ((__len - 2) / 2 < __child) 4858d72607e9SDimitry Andric break; 4859d72607e9SDimitry Andric 4860d72607e9SDimitry Andric // recompute the child based off of the updated parent 4861d72607e9SDimitry Andric __child = 2 * __child + 1; 4862d72607e9SDimitry Andric __child_i = __first + __child; 4863d72607e9SDimitry Andric 4864d72607e9SDimitry Andric if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { 4865d72607e9SDimitry Andric // right-child exists and is greater than left-child 4866d72607e9SDimitry Andric ++__child_i; 4867d72607e9SDimitry Andric ++__child; 4868d72607e9SDimitry Andric } 4869d72607e9SDimitry Andric 4870d72607e9SDimitry Andric // check if we are in heap-order 4871d72607e9SDimitry Andric } while (!__comp(*__child_i, __top)); 4872d72607e9SDimitry Andric *__start = _VSTD::move(__top); 4873d72607e9SDimitry Andric} 4874d72607e9SDimitry Andric 4875d72607e9SDimitry Andrictemplate <class _Compare, class _RandomAccessIterator> 48767a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 48777a984708SDavid Chisnallvoid 48787a984708SDavid Chisnall__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, 48797a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator>::difference_type __len) 48807a984708SDavid Chisnall{ 48817a984708SDavid Chisnall if (__len > 1) 48827a984708SDavid Chisnall { 48837a984708SDavid Chisnall swap(*__first, *--__last); 4884d72607e9SDimitry Andric __sift_down<_Compare>(__first, __last, __comp, __len - 1, __first); 48857a984708SDavid Chisnall } 48867a984708SDavid Chisnall} 48877a984708SDavid Chisnall 48887a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _Compare> 48897a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 48907a984708SDavid Chisnallvoid 48917a984708SDavid Chisnallpop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 48927a984708SDavid Chisnall{ 48934f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 48947a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 48957a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 48967a984708SDavid Chisnall __pop_heap<_Comp_ref>(__first, __last, __c, __last - __first); 48974f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 48987a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 48997a984708SDavid Chisnall __pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first); 49004f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 49017a984708SDavid Chisnall} 49027a984708SDavid Chisnall 49037a984708SDavid Chisnalltemplate <class _RandomAccessIterator> 49047a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 49057a984708SDavid Chisnallvoid 49067a984708SDavid Chisnallpop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 49077a984708SDavid Chisnall{ 49087a984708SDavid Chisnall _VSTD::pop_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 49097a984708SDavid Chisnall} 49107a984708SDavid Chisnall 49117a984708SDavid Chisnall// make_heap 49127a984708SDavid Chisnall 49137a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 49147a984708SDavid Chisnallvoid 49157a984708SDavid Chisnall__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 49167a984708SDavid Chisnall{ 49177a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 49187a984708SDavid Chisnall difference_type __n = __last - __first; 49197a984708SDavid Chisnall if (__n > 1) 49207a984708SDavid Chisnall { 4921d72607e9SDimitry Andric // start from the first parent, there is no need to consider children 4922d72607e9SDimitry Andric for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) 4923d72607e9SDimitry Andric { 4924d72607e9SDimitry Andric __sift_down<_Compare>(__first, __last, __comp, __n, __first + __start); 4925d72607e9SDimitry Andric } 49267a984708SDavid Chisnall } 49277a984708SDavid Chisnall} 49287a984708SDavid Chisnall 49297a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _Compare> 49307a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 49317a984708SDavid Chisnallvoid 49327a984708SDavid Chisnallmake_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 49337a984708SDavid Chisnall{ 49344f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 49357a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 49367a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 49377a984708SDavid Chisnall __make_heap<_Comp_ref>(__first, __last, __c); 49384f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 49397a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 49407a984708SDavid Chisnall __make_heap<_Comp_ref>(__first, __last, __comp); 49414f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 49427a984708SDavid Chisnall} 49437a984708SDavid Chisnall 49447a984708SDavid Chisnalltemplate <class _RandomAccessIterator> 49457a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 49467a984708SDavid Chisnallvoid 49477a984708SDavid Chisnallmake_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 49487a984708SDavid Chisnall{ 49497a984708SDavid Chisnall _VSTD::make_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 49507a984708SDavid Chisnall} 49517a984708SDavid Chisnall 49527a984708SDavid Chisnall// sort_heap 49537a984708SDavid Chisnall 49547a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 49557a984708SDavid Chisnallvoid 49567a984708SDavid Chisnall__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 49577a984708SDavid Chisnall{ 49587a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 49597a984708SDavid Chisnall for (difference_type __n = __last - __first; __n > 1; --__last, --__n) 49607a984708SDavid Chisnall __pop_heap<_Compare>(__first, __last, __comp, __n); 49617a984708SDavid Chisnall} 49627a984708SDavid Chisnall 49637a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _Compare> 49647a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 49657a984708SDavid Chisnallvoid 49667a984708SDavid Chisnallsort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 49677a984708SDavid Chisnall{ 49684f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 49697a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 49707a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 49717a984708SDavid Chisnall __sort_heap<_Comp_ref>(__first, __last, __c); 49724f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 49737a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 49747a984708SDavid Chisnall __sort_heap<_Comp_ref>(__first, __last, __comp); 49754f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 49767a984708SDavid Chisnall} 49777a984708SDavid Chisnall 49787a984708SDavid Chisnalltemplate <class _RandomAccessIterator> 49797a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 49807a984708SDavid Chisnallvoid 49817a984708SDavid Chisnallsort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 49827a984708SDavid Chisnall{ 49837a984708SDavid Chisnall _VSTD::sort_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 49847a984708SDavid Chisnall} 49857a984708SDavid Chisnall 49867a984708SDavid Chisnall// partial_sort 49877a984708SDavid Chisnall 49887a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 49897a984708SDavid Chisnallvoid 49907a984708SDavid Chisnall__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, 49917a984708SDavid Chisnall _Compare __comp) 49927a984708SDavid Chisnall{ 49937a984708SDavid Chisnall __make_heap<_Compare>(__first, __middle, __comp); 49947a984708SDavid Chisnall typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; 49957a984708SDavid Chisnall for (_RandomAccessIterator __i = __middle; __i != __last; ++__i) 49967a984708SDavid Chisnall { 49977a984708SDavid Chisnall if (__comp(*__i, *__first)) 49987a984708SDavid Chisnall { 49997a984708SDavid Chisnall swap(*__i, *__first); 5000d72607e9SDimitry Andric __sift_down<_Compare>(__first, __middle, __comp, __len, __first); 50017a984708SDavid Chisnall } 50027a984708SDavid Chisnall } 50037a984708SDavid Chisnall __sort_heap<_Compare>(__first, __middle, __comp); 50047a984708SDavid Chisnall} 50057a984708SDavid Chisnall 50067a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _Compare> 50077a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 50087a984708SDavid Chisnallvoid 50097a984708SDavid Chisnallpartial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, 50107a984708SDavid Chisnall _Compare __comp) 50117a984708SDavid Chisnall{ 50124f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 50137a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 50147a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 50157a984708SDavid Chisnall __partial_sort<_Comp_ref>(__first, __middle, __last, __c); 50164f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 50177a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 50187a984708SDavid Chisnall __partial_sort<_Comp_ref>(__first, __middle, __last, __comp); 50194f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 50207a984708SDavid Chisnall} 50217a984708SDavid Chisnall 50227a984708SDavid Chisnalltemplate <class _RandomAccessIterator> 50237a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 50247a984708SDavid Chisnallvoid 50257a984708SDavid Chisnallpartial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) 50267a984708SDavid Chisnall{ 50277a984708SDavid Chisnall _VSTD::partial_sort(__first, __middle, __last, 50287a984708SDavid Chisnall __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 50297a984708SDavid Chisnall} 50307a984708SDavid Chisnall 50317a984708SDavid Chisnall// partial_sort_copy 50327a984708SDavid Chisnall 50337a984708SDavid Chisnalltemplate <class _Compare, class _InputIterator, class _RandomAccessIterator> 50347a984708SDavid Chisnall_RandomAccessIterator 50357a984708SDavid Chisnall__partial_sort_copy(_InputIterator __first, _InputIterator __last, 50367a984708SDavid Chisnall _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) 50377a984708SDavid Chisnall{ 50387a984708SDavid Chisnall _RandomAccessIterator __r = __result_first; 50397a984708SDavid Chisnall if (__r != __result_last) 50407a984708SDavid Chisnall { 5041d72607e9SDimitry Andric for (; __first != __last && __r != __result_last; (void) ++__first, ++__r) 50427a984708SDavid Chisnall *__r = *__first; 50437a984708SDavid Chisnall __make_heap<_Compare>(__result_first, __r, __comp); 5044d72607e9SDimitry Andric typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; 50457a984708SDavid Chisnall for (; __first != __last; ++__first) 50467a984708SDavid Chisnall if (__comp(*__first, *__result_first)) 50477a984708SDavid Chisnall { 50487a984708SDavid Chisnall *__result_first = *__first; 5049d72607e9SDimitry Andric __sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first); 50507a984708SDavid Chisnall } 50517a984708SDavid Chisnall __sort_heap<_Compare>(__result_first, __r, __comp); 50527a984708SDavid Chisnall } 50537a984708SDavid Chisnall return __r; 50547a984708SDavid Chisnall} 50557a984708SDavid Chisnall 50567a984708SDavid Chisnalltemplate <class _InputIterator, class _RandomAccessIterator, class _Compare> 50577a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 50587a984708SDavid Chisnall_RandomAccessIterator 50597a984708SDavid Chisnallpartial_sort_copy(_InputIterator __first, _InputIterator __last, 50607a984708SDavid Chisnall _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) 50617a984708SDavid Chisnall{ 50624f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 50637a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 50647a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 50657a984708SDavid Chisnall return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __c); 50664f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 50677a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 50687a984708SDavid Chisnall return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp); 50694f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 50707a984708SDavid Chisnall} 50717a984708SDavid Chisnall 50727a984708SDavid Chisnalltemplate <class _InputIterator, class _RandomAccessIterator> 50737a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 50747a984708SDavid Chisnall_RandomAccessIterator 50757a984708SDavid Chisnallpartial_sort_copy(_InputIterator __first, _InputIterator __last, 50767a984708SDavid Chisnall _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) 50777a984708SDavid Chisnall{ 50787a984708SDavid Chisnall return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, 50797a984708SDavid Chisnall __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 50807a984708SDavid Chisnall} 50817a984708SDavid Chisnall 50827a984708SDavid Chisnall// nth_element 50837a984708SDavid Chisnall 50847a984708SDavid Chisnalltemplate <class _Compare, class _RandomAccessIterator> 50857a984708SDavid Chisnallvoid 50867a984708SDavid Chisnall__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) 50877a984708SDavid Chisnall{ 50887a984708SDavid Chisnall // _Compare is known to be a reference type 50897a984708SDavid Chisnall typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; 50907a984708SDavid Chisnall const difference_type __limit = 7; 50917a984708SDavid Chisnall while (true) 50927a984708SDavid Chisnall { 50937a984708SDavid Chisnall __restart: 509494e3ee44SDavid Chisnall if (__nth == __last) 509594e3ee44SDavid Chisnall return; 50967a984708SDavid Chisnall difference_type __len = __last - __first; 50977a984708SDavid Chisnall switch (__len) 50987a984708SDavid Chisnall { 50997a984708SDavid Chisnall case 0: 51007a984708SDavid Chisnall case 1: 51017a984708SDavid Chisnall return; 51027a984708SDavid Chisnall case 2: 51037a984708SDavid Chisnall if (__comp(*--__last, *__first)) 51047a984708SDavid Chisnall swap(*__first, *__last); 51057a984708SDavid Chisnall return; 51067a984708SDavid Chisnall case 3: 51077a984708SDavid Chisnall { 51087a984708SDavid Chisnall _RandomAccessIterator __m = __first; 51097a984708SDavid Chisnall _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp); 51107a984708SDavid Chisnall return; 51117a984708SDavid Chisnall } 51127a984708SDavid Chisnall } 51137a984708SDavid Chisnall if (__len <= __limit) 51147a984708SDavid Chisnall { 51157a984708SDavid Chisnall __selection_sort<_Compare>(__first, __last, __comp); 51167a984708SDavid Chisnall return; 51177a984708SDavid Chisnall } 51187a984708SDavid Chisnall // __len > __limit >= 3 51197a984708SDavid Chisnall _RandomAccessIterator __m = __first + __len/2; 51207a984708SDavid Chisnall _RandomAccessIterator __lm1 = __last; 51217a984708SDavid Chisnall unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp); 51227a984708SDavid Chisnall // *__m is median 51237a984708SDavid Chisnall // partition [__first, __m) < *__m and *__m <= [__m, __last) 51247a984708SDavid Chisnall // (this inhibits tossing elements equivalent to __m around unnecessarily) 51257a984708SDavid Chisnall _RandomAccessIterator __i = __first; 51267a984708SDavid Chisnall _RandomAccessIterator __j = __lm1; 51277a984708SDavid Chisnall // j points beyond range to be tested, *__lm1 is known to be <= *__m 51287a984708SDavid Chisnall // The search going up is known to be guarded but the search coming down isn't. 51297a984708SDavid Chisnall // Prime the downward search with a guard. 51307a984708SDavid Chisnall if (!__comp(*__i, *__m)) // if *__first == *__m 51317a984708SDavid Chisnall { 51327a984708SDavid Chisnall // *__first == *__m, *__first doesn't go in first part 51337a984708SDavid Chisnall // manually guard downward moving __j against __i 51347a984708SDavid Chisnall while (true) 51357a984708SDavid Chisnall { 51367a984708SDavid Chisnall if (__i == --__j) 51377a984708SDavid Chisnall { 51387a984708SDavid Chisnall // *__first == *__m, *__m <= all other elements 51397a984708SDavid Chisnall // Parition instead into [__first, __i) == *__first and *__first < [__i, __last) 51407a984708SDavid Chisnall ++__i; // __first + 1 51417a984708SDavid Chisnall __j = __last; 51427a984708SDavid Chisnall if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1) 51437a984708SDavid Chisnall { 51447a984708SDavid Chisnall while (true) 51457a984708SDavid Chisnall { 51467a984708SDavid Chisnall if (__i == __j) 51477a984708SDavid Chisnall return; // [__first, __last) all equivalent elements 51487a984708SDavid Chisnall if (__comp(*__first, *__i)) 51497a984708SDavid Chisnall { 51507a984708SDavid Chisnall swap(*__i, *__j); 51517a984708SDavid Chisnall ++__n_swaps; 51527a984708SDavid Chisnall ++__i; 51537a984708SDavid Chisnall break; 51547a984708SDavid Chisnall } 51557a984708SDavid Chisnall ++__i; 51567a984708SDavid Chisnall } 51577a984708SDavid Chisnall } 51587a984708SDavid Chisnall // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 51597a984708SDavid Chisnall if (__i == __j) 51607a984708SDavid Chisnall return; 51617a984708SDavid Chisnall while (true) 51627a984708SDavid Chisnall { 51637a984708SDavid Chisnall while (!__comp(*__first, *__i)) 51647a984708SDavid Chisnall ++__i; 51657a984708SDavid Chisnall while (__comp(*__first, *--__j)) 51667a984708SDavid Chisnall ; 51677a984708SDavid Chisnall if (__i >= __j) 51687a984708SDavid Chisnall break; 51697a984708SDavid Chisnall swap(*__i, *__j); 51707a984708SDavid Chisnall ++__n_swaps; 51717a984708SDavid Chisnall ++__i; 51727a984708SDavid Chisnall } 51737a984708SDavid Chisnall // [__first, __i) == *__first and *__first < [__i, __last) 51747a984708SDavid Chisnall // The first part is sorted, 51757a984708SDavid Chisnall if (__nth < __i) 51767a984708SDavid Chisnall return; 51777a984708SDavid Chisnall // __nth_element the secod part 51787a984708SDavid Chisnall // __nth_element<_Compare>(__i, __nth, __last, __comp); 51797a984708SDavid Chisnall __first = __i; 51807a984708SDavid Chisnall goto __restart; 51817a984708SDavid Chisnall } 51827a984708SDavid Chisnall if (__comp(*__j, *__m)) 51837a984708SDavid Chisnall { 51847a984708SDavid Chisnall swap(*__i, *__j); 51857a984708SDavid Chisnall ++__n_swaps; 51867a984708SDavid Chisnall break; // found guard for downward moving __j, now use unguarded partition 51877a984708SDavid Chisnall } 51887a984708SDavid Chisnall } 51897a984708SDavid Chisnall } 51907a984708SDavid Chisnall ++__i; 51917a984708SDavid Chisnall // j points beyond range to be tested, *__lm1 is known to be <= *__m 51927a984708SDavid Chisnall // if not yet partitioned... 51937a984708SDavid Chisnall if (__i < __j) 51947a984708SDavid Chisnall { 51957a984708SDavid Chisnall // known that *(__i - 1) < *__m 51967a984708SDavid Chisnall while (true) 51977a984708SDavid Chisnall { 51987a984708SDavid Chisnall // __m still guards upward moving __i 51997a984708SDavid Chisnall while (__comp(*__i, *__m)) 52007a984708SDavid Chisnall ++__i; 52017a984708SDavid Chisnall // It is now known that a guard exists for downward moving __j 52027a984708SDavid Chisnall while (!__comp(*--__j, *__m)) 52037a984708SDavid Chisnall ; 52047a984708SDavid Chisnall if (__i >= __j) 52057a984708SDavid Chisnall break; 52067a984708SDavid Chisnall swap(*__i, *__j); 52077a984708SDavid Chisnall ++__n_swaps; 52087a984708SDavid Chisnall // It is known that __m != __j 52097a984708SDavid Chisnall // If __m just moved, follow it 52107a984708SDavid Chisnall if (__m == __i) 52117a984708SDavid Chisnall __m = __j; 52127a984708SDavid Chisnall ++__i; 52137a984708SDavid Chisnall } 52147a984708SDavid Chisnall } 52157a984708SDavid Chisnall // [__first, __i) < *__m and *__m <= [__i, __last) 52167a984708SDavid Chisnall if (__i != __m && __comp(*__m, *__i)) 52177a984708SDavid Chisnall { 52187a984708SDavid Chisnall swap(*__i, *__m); 52197a984708SDavid Chisnall ++__n_swaps; 52207a984708SDavid Chisnall } 52217a984708SDavid Chisnall // [__first, __i) < *__i and *__i <= [__i+1, __last) 52227a984708SDavid Chisnall if (__nth == __i) 52237a984708SDavid Chisnall return; 52247a984708SDavid Chisnall if (__n_swaps == 0) 52257a984708SDavid Chisnall { 52267a984708SDavid Chisnall // We were given a perfectly partitioned sequence. Coincidence? 52277a984708SDavid Chisnall if (__nth < __i) 52287a984708SDavid Chisnall { 52297a984708SDavid Chisnall // Check for [__first, __i) already sorted 52307a984708SDavid Chisnall __j = __m = __first; 52317a984708SDavid Chisnall while (++__j != __i) 52327a984708SDavid Chisnall { 52337a984708SDavid Chisnall if (__comp(*__j, *__m)) 52347a984708SDavid Chisnall // not yet sorted, so sort 52357a984708SDavid Chisnall goto not_sorted; 52367a984708SDavid Chisnall __m = __j; 52377a984708SDavid Chisnall } 52387a984708SDavid Chisnall // [__first, __i) sorted 52397a984708SDavid Chisnall return; 52407a984708SDavid Chisnall } 52417a984708SDavid Chisnall else 52427a984708SDavid Chisnall { 52437a984708SDavid Chisnall // Check for [__i, __last) already sorted 52447a984708SDavid Chisnall __j = __m = __i; 52457a984708SDavid Chisnall while (++__j != __last) 52467a984708SDavid Chisnall { 52477a984708SDavid Chisnall if (__comp(*__j, *__m)) 52487a984708SDavid Chisnall // not yet sorted, so sort 52497a984708SDavid Chisnall goto not_sorted; 52507a984708SDavid Chisnall __m = __j; 52517a984708SDavid Chisnall } 52527a984708SDavid Chisnall // [__i, __last) sorted 52537a984708SDavid Chisnall return; 52547a984708SDavid Chisnall } 52557a984708SDavid Chisnall } 52567a984708SDavid Chisnallnot_sorted: 52577a984708SDavid Chisnall // __nth_element on range containing __nth 52587a984708SDavid Chisnall if (__nth < __i) 52597a984708SDavid Chisnall { 52607a984708SDavid Chisnall // __nth_element<_Compare>(__first, __nth, __i, __comp); 52617a984708SDavid Chisnall __last = __i; 52627a984708SDavid Chisnall } 52637a984708SDavid Chisnall else 52647a984708SDavid Chisnall { 52657a984708SDavid Chisnall // __nth_element<_Compare>(__i+1, __nth, __last, __comp); 52667a984708SDavid Chisnall __first = ++__i; 52677a984708SDavid Chisnall } 52687a984708SDavid Chisnall } 52697a984708SDavid Chisnall} 52707a984708SDavid Chisnall 52717a984708SDavid Chisnalltemplate <class _RandomAccessIterator, class _Compare> 52727a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 52737a984708SDavid Chisnallvoid 52747a984708SDavid Chisnallnth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) 52757a984708SDavid Chisnall{ 52764f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 52777a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 52787a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 52797a984708SDavid Chisnall __nth_element<_Comp_ref>(__first, __nth, __last, __c); 52804f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 52817a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 52827a984708SDavid Chisnall __nth_element<_Comp_ref>(__first, __nth, __last, __comp); 52834f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 52847a984708SDavid Chisnall} 52857a984708SDavid Chisnall 52867a984708SDavid Chisnalltemplate <class _RandomAccessIterator> 52877a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 52887a984708SDavid Chisnallvoid 52897a984708SDavid Chisnallnth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) 52907a984708SDavid Chisnall{ 52917a984708SDavid Chisnall _VSTD::nth_element(__first, __nth, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 52927a984708SDavid Chisnall} 52937a984708SDavid Chisnall 52947a984708SDavid Chisnall// includes 52957a984708SDavid Chisnall 52967a984708SDavid Chisnalltemplate <class _Compare, class _InputIterator1, class _InputIterator2> 52974ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 52987a984708SDavid Chisnall__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, 52997a984708SDavid Chisnall _Compare __comp) 53007a984708SDavid Chisnall{ 53017a984708SDavid Chisnall for (; __first2 != __last2; ++__first1) 53027a984708SDavid Chisnall { 53037a984708SDavid Chisnall if (__first1 == __last1 || __comp(*__first2, *__first1)) 53047a984708SDavid Chisnall return false; 53057a984708SDavid Chisnall if (!__comp(*__first1, *__first2)) 53067a984708SDavid Chisnall ++__first2; 53077a984708SDavid Chisnall } 53087a984708SDavid Chisnall return true; 53097a984708SDavid Chisnall} 53107a984708SDavid Chisnall 53117a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _Compare> 53124ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 53137a984708SDavid Chisnallbool 53147a984708SDavid Chisnallincludes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, 53157a984708SDavid Chisnall _Compare __comp) 53167a984708SDavid Chisnall{ 53174f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 53187a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 53197a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 53207a984708SDavid Chisnall return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __c); 53214f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 53227a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 53237a984708SDavid Chisnall return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); 53244f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 53257a984708SDavid Chisnall} 53267a984708SDavid Chisnall 53277a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2> 53284ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 53297a984708SDavid Chisnallbool 53307a984708SDavid Chisnallincludes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) 53317a984708SDavid Chisnall{ 53327a984708SDavid Chisnall return _VSTD::includes(__first1, __last1, __first2, __last2, 53337a984708SDavid Chisnall __less<typename iterator_traits<_InputIterator1>::value_type, 53347a984708SDavid Chisnall typename iterator_traits<_InputIterator2>::value_type>()); 53357a984708SDavid Chisnall} 53367a984708SDavid Chisnall 53377a984708SDavid Chisnall// set_union 53387a984708SDavid Chisnall 53397a984708SDavid Chisnalltemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 53407a984708SDavid Chisnall_OutputIterator 53417a984708SDavid Chisnall__set_union(_InputIterator1 __first1, _InputIterator1 __last1, 53427a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 53437a984708SDavid Chisnall{ 53447a984708SDavid Chisnall for (; __first1 != __last1; ++__result) 53457a984708SDavid Chisnall { 53467a984708SDavid Chisnall if (__first2 == __last2) 53477a984708SDavid Chisnall return _VSTD::copy(__first1, __last1, __result); 53487a984708SDavid Chisnall if (__comp(*__first2, *__first1)) 53497a984708SDavid Chisnall { 53507a984708SDavid Chisnall *__result = *__first2; 53517a984708SDavid Chisnall ++__first2; 53527a984708SDavid Chisnall } 53537a984708SDavid Chisnall else 53547a984708SDavid Chisnall { 53557a984708SDavid Chisnall if (!__comp(*__first1, *__first2)) 53567a984708SDavid Chisnall ++__first2; 5357b2c7081bSDimitry Andric *__result = *__first1; 53587a984708SDavid Chisnall ++__first1; 53597a984708SDavid Chisnall } 53607a984708SDavid Chisnall } 53617a984708SDavid Chisnall return _VSTD::copy(__first2, __last2, __result); 53627a984708SDavid Chisnall} 53637a984708SDavid Chisnall 53647a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 53657a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 53667a984708SDavid Chisnall_OutputIterator 53677a984708SDavid Chisnallset_union(_InputIterator1 __first1, _InputIterator1 __last1, 53687a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 53697a984708SDavid Chisnall{ 53704f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 53717a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 53727a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 53737a984708SDavid Chisnall return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); 53744f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 53757a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 53767a984708SDavid Chisnall return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 53774f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 53787a984708SDavid Chisnall} 53797a984708SDavid Chisnall 53807a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 53817a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 53827a984708SDavid Chisnall_OutputIterator 53837a984708SDavid Chisnallset_union(_InputIterator1 __first1, _InputIterator1 __last1, 53847a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 53857a984708SDavid Chisnall{ 53867a984708SDavid Chisnall return _VSTD::set_union(__first1, __last1, __first2, __last2, __result, 53877a984708SDavid Chisnall __less<typename iterator_traits<_InputIterator1>::value_type, 53887a984708SDavid Chisnall typename iterator_traits<_InputIterator2>::value_type>()); 53897a984708SDavid Chisnall} 53907a984708SDavid Chisnall 53917a984708SDavid Chisnall// set_intersection 53927a984708SDavid Chisnall 53937a984708SDavid Chisnalltemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 53944ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 53957a984708SDavid Chisnall__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 53967a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 53977a984708SDavid Chisnall{ 53987a984708SDavid Chisnall while (__first1 != __last1 && __first2 != __last2) 53997a984708SDavid Chisnall { 54007a984708SDavid Chisnall if (__comp(*__first1, *__first2)) 54017a984708SDavid Chisnall ++__first1; 54027a984708SDavid Chisnall else 54037a984708SDavid Chisnall { 54047a984708SDavid Chisnall if (!__comp(*__first2, *__first1)) 54057a984708SDavid Chisnall { 54067a984708SDavid Chisnall *__result = *__first1; 54077a984708SDavid Chisnall ++__result; 54087a984708SDavid Chisnall ++__first1; 54097a984708SDavid Chisnall } 54107a984708SDavid Chisnall ++__first2; 54117a984708SDavid Chisnall } 54127a984708SDavid Chisnall } 54137a984708SDavid Chisnall return __result; 54147a984708SDavid Chisnall} 54157a984708SDavid Chisnall 54167a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 54174ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 54187a984708SDavid Chisnall_OutputIterator 54197a984708SDavid Chisnallset_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 54207a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 54217a984708SDavid Chisnall{ 54224f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 54237a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 54247a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 54257a984708SDavid Chisnall return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); 54264f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 54277a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 54287a984708SDavid Chisnall return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 54294f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 54307a984708SDavid Chisnall} 54317a984708SDavid Chisnall 54327a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 54334ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 54347a984708SDavid Chisnall_OutputIterator 54357a984708SDavid Chisnallset_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 54367a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 54377a984708SDavid Chisnall{ 54387a984708SDavid Chisnall return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result, 54397a984708SDavid Chisnall __less<typename iterator_traits<_InputIterator1>::value_type, 54407a984708SDavid Chisnall typename iterator_traits<_InputIterator2>::value_type>()); 54417a984708SDavid Chisnall} 54427a984708SDavid Chisnall 54437a984708SDavid Chisnall// set_difference 54447a984708SDavid Chisnall 54457a984708SDavid Chisnalltemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 54467a984708SDavid Chisnall_OutputIterator 54477a984708SDavid Chisnall__set_difference(_InputIterator1 __first1, _InputIterator1 __last1, 54487a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 54497a984708SDavid Chisnall{ 54507a984708SDavid Chisnall while (__first1 != __last1) 54517a984708SDavid Chisnall { 54527a984708SDavid Chisnall if (__first2 == __last2) 54537a984708SDavid Chisnall return _VSTD::copy(__first1, __last1, __result); 54547a984708SDavid Chisnall if (__comp(*__first1, *__first2)) 54557a984708SDavid Chisnall { 54567a984708SDavid Chisnall *__result = *__first1; 54577a984708SDavid Chisnall ++__result; 54587a984708SDavid Chisnall ++__first1; 54597a984708SDavid Chisnall } 54607a984708SDavid Chisnall else 54617a984708SDavid Chisnall { 54627a984708SDavid Chisnall if (!__comp(*__first2, *__first1)) 54637a984708SDavid Chisnall ++__first1; 54647a984708SDavid Chisnall ++__first2; 54657a984708SDavid Chisnall } 54667a984708SDavid Chisnall } 54677a984708SDavid Chisnall return __result; 54687a984708SDavid Chisnall} 54697a984708SDavid Chisnall 54707a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 54717a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 54727a984708SDavid Chisnall_OutputIterator 54737a984708SDavid Chisnallset_difference(_InputIterator1 __first1, _InputIterator1 __last1, 54747a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 54757a984708SDavid Chisnall{ 54764f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 54777a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 54787a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 54797a984708SDavid Chisnall return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); 54804f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 54817a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 54827a984708SDavid Chisnall return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 54834f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 54847a984708SDavid Chisnall} 54857a984708SDavid Chisnall 54867a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 54877a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 54887a984708SDavid Chisnall_OutputIterator 54897a984708SDavid Chisnallset_difference(_InputIterator1 __first1, _InputIterator1 __last1, 54907a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 54917a984708SDavid Chisnall{ 54927a984708SDavid Chisnall return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result, 54937a984708SDavid Chisnall __less<typename iterator_traits<_InputIterator1>::value_type, 54947a984708SDavid Chisnall typename iterator_traits<_InputIterator2>::value_type>()); 54957a984708SDavid Chisnall} 54967a984708SDavid Chisnall 54977a984708SDavid Chisnall// set_symmetric_difference 54987a984708SDavid Chisnall 54997a984708SDavid Chisnalltemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> 55007a984708SDavid Chisnall_OutputIterator 55017a984708SDavid Chisnall__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 55027a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 55037a984708SDavid Chisnall{ 55047a984708SDavid Chisnall while (__first1 != __last1) 55057a984708SDavid Chisnall { 55067a984708SDavid Chisnall if (__first2 == __last2) 55077a984708SDavid Chisnall return _VSTD::copy(__first1, __last1, __result); 55087a984708SDavid Chisnall if (__comp(*__first1, *__first2)) 55097a984708SDavid Chisnall { 55107a984708SDavid Chisnall *__result = *__first1; 55117a984708SDavid Chisnall ++__result; 55127a984708SDavid Chisnall ++__first1; 55137a984708SDavid Chisnall } 55147a984708SDavid Chisnall else 55157a984708SDavid Chisnall { 55167a984708SDavid Chisnall if (__comp(*__first2, *__first1)) 55177a984708SDavid Chisnall { 55187a984708SDavid Chisnall *__result = *__first2; 55197a984708SDavid Chisnall ++__result; 55207a984708SDavid Chisnall } 55217a984708SDavid Chisnall else 55227a984708SDavid Chisnall ++__first1; 55237a984708SDavid Chisnall ++__first2; 55247a984708SDavid Chisnall } 55257a984708SDavid Chisnall } 55267a984708SDavid Chisnall return _VSTD::copy(__first2, __last2, __result); 55277a984708SDavid Chisnall} 55287a984708SDavid Chisnall 55297a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 55307a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 55317a984708SDavid Chisnall_OutputIterator 55327a984708SDavid Chisnallset_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 55337a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) 55347a984708SDavid Chisnall{ 55354f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 55367a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 55377a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 55387a984708SDavid Chisnall return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); 55394f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 55407a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 55417a984708SDavid Chisnall return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); 55424f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 55437a984708SDavid Chisnall} 55447a984708SDavid Chisnall 55457a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator> 55467a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 55477a984708SDavid Chisnall_OutputIterator 55487a984708SDavid Chisnallset_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 55497a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) 55507a984708SDavid Chisnall{ 55517a984708SDavid Chisnall return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, 55527a984708SDavid Chisnall __less<typename iterator_traits<_InputIterator1>::value_type, 55537a984708SDavid Chisnall typename iterator_traits<_InputIterator2>::value_type>()); 55547a984708SDavid Chisnall} 55557a984708SDavid Chisnall 55567a984708SDavid Chisnall// lexicographical_compare 55577a984708SDavid Chisnall 55587a984708SDavid Chisnalltemplate <class _Compare, class _InputIterator1, class _InputIterator2> 55594ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool 55607a984708SDavid Chisnall__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, 55617a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) 55627a984708SDavid Chisnall{ 5563d72607e9SDimitry Andric for (; __first2 != __last2; ++__first1, (void) ++__first2) 55647a984708SDavid Chisnall { 55657a984708SDavid Chisnall if (__first1 == __last1 || __comp(*__first1, *__first2)) 55667a984708SDavid Chisnall return true; 55677a984708SDavid Chisnall if (__comp(*__first2, *__first1)) 55687a984708SDavid Chisnall return false; 55697a984708SDavid Chisnall } 55707a984708SDavid Chisnall return false; 55717a984708SDavid Chisnall} 55727a984708SDavid Chisnall 55737a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _Compare> 55744ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 55757a984708SDavid Chisnallbool 55767a984708SDavid Chisnalllexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, 55777a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) 55787a984708SDavid Chisnall{ 55794f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 55807a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 55817a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 55827a984708SDavid Chisnall return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __c); 55834f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 55847a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 55857a984708SDavid Chisnall return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); 55864f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 55877a984708SDavid Chisnall} 55887a984708SDavid Chisnall 55897a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2> 55904ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 55917a984708SDavid Chisnallbool 55927a984708SDavid Chisnalllexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, 55937a984708SDavid Chisnall _InputIterator2 __first2, _InputIterator2 __last2) 55947a984708SDavid Chisnall{ 55957a984708SDavid Chisnall return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, 55967a984708SDavid Chisnall __less<typename iterator_traits<_InputIterator1>::value_type, 55977a984708SDavid Chisnall typename iterator_traits<_InputIterator2>::value_type>()); 55987a984708SDavid Chisnall} 55997a984708SDavid Chisnall 56007a984708SDavid Chisnall// next_permutation 56017a984708SDavid Chisnall 56027a984708SDavid Chisnalltemplate <class _Compare, class _BidirectionalIterator> 56037a984708SDavid Chisnallbool 56047a984708SDavid Chisnall__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 56057a984708SDavid Chisnall{ 56067a984708SDavid Chisnall _BidirectionalIterator __i = __last; 56077a984708SDavid Chisnall if (__first == __last || __first == --__i) 56087a984708SDavid Chisnall return false; 56097a984708SDavid Chisnall while (true) 56107a984708SDavid Chisnall { 56117a984708SDavid Chisnall _BidirectionalIterator __ip1 = __i; 56127a984708SDavid Chisnall if (__comp(*--__i, *__ip1)) 56137a984708SDavid Chisnall { 56147a984708SDavid Chisnall _BidirectionalIterator __j = __last; 56157a984708SDavid Chisnall while (!__comp(*__i, *--__j)) 56167a984708SDavid Chisnall ; 56177a984708SDavid Chisnall swap(*__i, *__j); 56187a984708SDavid Chisnall _VSTD::reverse(__ip1, __last); 56197a984708SDavid Chisnall return true; 56207a984708SDavid Chisnall } 56217a984708SDavid Chisnall if (__i == __first) 56227a984708SDavid Chisnall { 56237a984708SDavid Chisnall _VSTD::reverse(__first, __last); 56247a984708SDavid Chisnall return false; 56257a984708SDavid Chisnall } 56267a984708SDavid Chisnall } 56277a984708SDavid Chisnall} 56287a984708SDavid Chisnall 56297a984708SDavid Chisnalltemplate <class _BidirectionalIterator, class _Compare> 56307a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 56317a984708SDavid Chisnallbool 56327a984708SDavid Chisnallnext_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 56337a984708SDavid Chisnall{ 56344f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 56357a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 56367a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 56377a984708SDavid Chisnall return __next_permutation<_Comp_ref>(__first, __last, __c); 56384f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 56397a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 56407a984708SDavid Chisnall return __next_permutation<_Comp_ref>(__first, __last, __comp); 56414f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 56427a984708SDavid Chisnall} 56437a984708SDavid Chisnall 56447a984708SDavid Chisnalltemplate <class _BidirectionalIterator> 56457a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 56467a984708SDavid Chisnallbool 56477a984708SDavid Chisnallnext_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) 56487a984708SDavid Chisnall{ 56497a984708SDavid Chisnall return _VSTD::next_permutation(__first, __last, 56507a984708SDavid Chisnall __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); 56517a984708SDavid Chisnall} 56527a984708SDavid Chisnall 56537a984708SDavid Chisnall// prev_permutation 56547a984708SDavid Chisnall 56557a984708SDavid Chisnalltemplate <class _Compare, class _BidirectionalIterator> 56567a984708SDavid Chisnallbool 56577a984708SDavid Chisnall__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 56587a984708SDavid Chisnall{ 56597a984708SDavid Chisnall _BidirectionalIterator __i = __last; 56607a984708SDavid Chisnall if (__first == __last || __first == --__i) 56617a984708SDavid Chisnall return false; 56627a984708SDavid Chisnall while (true) 56637a984708SDavid Chisnall { 56647a984708SDavid Chisnall _BidirectionalIterator __ip1 = __i; 56657a984708SDavid Chisnall if (__comp(*__ip1, *--__i)) 56667a984708SDavid Chisnall { 56677a984708SDavid Chisnall _BidirectionalIterator __j = __last; 56687a984708SDavid Chisnall while (!__comp(*--__j, *__i)) 56697a984708SDavid Chisnall ; 56707a984708SDavid Chisnall swap(*__i, *__j); 56717a984708SDavid Chisnall _VSTD::reverse(__ip1, __last); 56727a984708SDavid Chisnall return true; 56737a984708SDavid Chisnall } 56747a984708SDavid Chisnall if (__i == __first) 56757a984708SDavid Chisnall { 56767a984708SDavid Chisnall _VSTD::reverse(__first, __last); 56777a984708SDavid Chisnall return false; 56787a984708SDavid Chisnall } 56797a984708SDavid Chisnall } 56807a984708SDavid Chisnall} 56817a984708SDavid Chisnall 56827a984708SDavid Chisnalltemplate <class _BidirectionalIterator, class _Compare> 56837a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 56847a984708SDavid Chisnallbool 56857a984708SDavid Chisnallprev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) 56867a984708SDavid Chisnall{ 56874f7ab58eSDimitry Andric#ifdef _LIBCPP_DEBUG 56887a984708SDavid Chisnall typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; 56897a984708SDavid Chisnall __debug_less<_Compare> __c(__comp); 56907a984708SDavid Chisnall return __prev_permutation<_Comp_ref>(__first, __last, __c); 56914f7ab58eSDimitry Andric#else // _LIBCPP_DEBUG 56927a984708SDavid Chisnall typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; 56937a984708SDavid Chisnall return __prev_permutation<_Comp_ref>(__first, __last, __comp); 56944f7ab58eSDimitry Andric#endif // _LIBCPP_DEBUG 56957a984708SDavid Chisnall} 56967a984708SDavid Chisnall 56977a984708SDavid Chisnalltemplate <class _BidirectionalIterator> 56987a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 56997a984708SDavid Chisnallbool 57007a984708SDavid Chisnallprev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) 57017a984708SDavid Chisnall{ 57027a984708SDavid Chisnall return _VSTD::prev_permutation(__first, __last, 57037a984708SDavid Chisnall __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); 57047a984708SDavid Chisnall} 57057a984708SDavid Chisnall 57067a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD 57077a984708SDavid Chisnall 5708f9448bf3SDimitry Andric_LIBCPP_POP_MACROS 5709f9448bf3SDimitry Andric 57107a984708SDavid Chisnall#endif // _LIBCPP_ALGORITHM 5711