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