// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef _LIBCPP_ALGORITHM #define _LIBCPP_ALGORITHM /* algorithm synopsis #include namespace std { namespace ranges { template struct in_in_result; // since C++20 template struct in_in_out_result; // since C++20 } template constexpr bool // constexpr in C++20 all_of(InputIterator first, InputIterator last, Predicate pred); template constexpr bool // constexpr in C++20 any_of(InputIterator first, InputIterator last, Predicate pred); template constexpr bool // constexpr in C++20 none_of(InputIterator first, InputIterator last, Predicate pred); template constexpr Function // constexpr in C++20 for_each(InputIterator first, InputIterator last, Function f); template constexpr InputIterator // constexpr in C++20 for_each_n(InputIterator first, Size n, Function f); // C++17 template constexpr InputIterator // constexpr in C++20 find(InputIterator first, InputIterator last, const T& value); template constexpr InputIterator // constexpr in C++20 find_if(InputIterator first, InputIterator last, Predicate pred); template constexpr InputIterator // constexpr in C++20 find_if_not(InputIterator first, InputIterator last, Predicate pred); template constexpr ForwardIterator1 // constexpr in C++20 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template constexpr ForwardIterator1 // constexpr in C++20 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); template constexpr ForwardIterator1 // constexpr in C++20 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template constexpr ForwardIterator1 // constexpr in C++20 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); template constexpr ForwardIterator // constexpr in C++20 adjacent_find(ForwardIterator first, ForwardIterator last); template constexpr ForwardIterator // constexpr in C++20 adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); template constexpr typename iterator_traits::difference_type // constexpr in C++20 count(InputIterator first, InputIterator last, const T& value); template constexpr typename iterator_traits::difference_type // constexpr in C++20 count_if(InputIterator first, InputIterator last, Predicate pred); template constexpr pair // constexpr in C++20 mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); template constexpr pair // constexpr in C++20 mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); // **C++14** template constexpr pair // constexpr in C++20 mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); template constexpr pair // constexpr in C++20 mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); // **C++14** template constexpr bool // constexpr in C++20 equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); template constexpr bool // constexpr in C++20 equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); // **C++14** template constexpr bool // constexpr in C++20 equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); template constexpr bool // constexpr in C++20 equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); // **C++14** template constexpr bool // constexpr in C++20 is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); template constexpr bool // constexpr in C++20 is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); // **C++14** template constexpr bool // constexpr in C++20 is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred); template constexpr bool // constexpr in C++20 is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); // **C++14** template constexpr ForwardIterator1 // constexpr in C++20 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template constexpr ForwardIterator1 // constexpr in C++20 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); template constexpr ForwardIterator // constexpr in C++20 search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value); template constexpr ForwardIterator // constexpr in C++20 search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value, BinaryPredicate pred); template constexpr OutputIterator // constexpr in C++20 copy(InputIterator first, InputIterator last, OutputIterator result); template constexpr OutputIterator // constexpr in C++20 copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); template constexpr OutputIterator // constexpr in C++20 copy_n(InputIterator first, Size n, OutputIterator result); template constexpr BidirectionalIterator2 // constexpr in C++20 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result); template constexpr ForwardIterator2 // constexpr in C++20 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); template constexpr void // constexpr in C++20 iter_swap(ForwardIterator1 a, ForwardIterator2 b); template constexpr OutputIterator // constexpr in C++20 transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op); template constexpr OutputIterator // constexpr in C++20 transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op); template constexpr void // constexpr in C++20 replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); template constexpr void // constexpr in C++20 replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value); template constexpr OutputIterator // constexpr in C++20 replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value); template constexpr OutputIterator // constexpr in C++20 replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value); template constexpr void // constexpr in C++20 fill(ForwardIterator first, ForwardIterator last, const T& value); template constexpr OutputIterator // constexpr in C++20 fill_n(OutputIterator first, Size n, const T& value); template constexpr void // constexpr in C++20 generate(ForwardIterator first, ForwardIterator last, Generator gen); template constexpr OutputIterator // constexpr in C++20 generate_n(OutputIterator first, Size n, Generator gen); template constexpr ForwardIterator // constexpr in C++20 remove(ForwardIterator first, ForwardIterator last, const T& value); template constexpr ForwardIterator // constexpr in C++20 remove_if(ForwardIterator first, ForwardIterator last, Predicate pred); template constexpr OutputIterator // constexpr in C++20 remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value); template constexpr OutputIterator // constexpr in C++20 remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); template constexpr ForwardIterator // constexpr in C++20 unique(ForwardIterator first, ForwardIterator last); template constexpr ForwardIterator // constexpr in C++20 unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); template constexpr OutputIterator // constexpr in C++20 unique_copy(InputIterator first, InputIterator last, OutputIterator result); template constexpr OutputIterator // constexpr in C++20 unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); template constexpr void // constexpr in C++20 reverse(BidirectionalIterator first, BidirectionalIterator last); template constexpr OutputIterator // constexpr in C++20 reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result); template constexpr ForwardIterator // constexpr in C++20 rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last); template constexpr OutputIterator // constexpr in C++20 rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result); template void random_shuffle(RandomAccessIterator first, RandomAccessIterator last); // deprecated in C++14, removed in C++17 template void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& rand); // deprecated in C++14, removed in C++17 template SampleIterator sample(PopulationIterator first, PopulationIterator last, SampleIterator out, Distance n, UniformRandomBitGenerator&& g); // C++17 template void shuffle(RandomAccessIterator first, RandomAccessIterator last, UniformRandomNumberGenerator&& g); template constexpr ForwardIterator shift_left(ForwardIterator first, ForwardIterator last, typename iterator_traits::difference_type n); // C++20 template constexpr ForwardIterator shift_right(ForwardIterator first, ForwardIterator last, typename iterator_traits::difference_type n); // C++20 template constexpr bool // constexpr in C++20 is_partitioned(InputIterator first, InputIterator last, Predicate pred); template constexpr ForwardIterator // constexpr in C++20 partition(ForwardIterator first, ForwardIterator last, Predicate pred); template constexpr pair // constexpr in C++20 partition_copy(InputIterator first, InputIterator last, OutputIterator1 out_true, OutputIterator2 out_false, Predicate pred); template ForwardIterator stable_partition(ForwardIterator first, ForwardIterator last, Predicate pred); template constexpr ForwardIterator // constexpr in C++20 partition_point(ForwardIterator first, ForwardIterator last, Predicate pred); template constexpr bool // constexpr in C++20 is_sorted(ForwardIterator first, ForwardIterator last); template constexpr bool // constexpr in C++20 is_sorted(ForwardIterator first, ForwardIterator last, Compare comp); template constexpr ForwardIterator // constexpr in C++20 is_sorted_until(ForwardIterator first, ForwardIterator last); template constexpr ForwardIterator // constexpr in C++20 is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp); template constexpr void // constexpr in C++20 sort(RandomAccessIterator first, RandomAccessIterator last); template constexpr void // constexpr in C++20 sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template void stable_sort(RandomAccessIterator first, RandomAccessIterator last); template void stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template constexpr void // constexpr in C++20 partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); template constexpr void // constexpr in C++20 partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); template constexpr RandomAccessIterator // constexpr in C++20 partial_sort_copy(InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last); template constexpr RandomAccessIterator // constexpr in C++20 partial_sort_copy(InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp); template constexpr void // constexpr in C++20 nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); template constexpr void // constexpr in C++20 nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); template constexpr ForwardIterator // constexpr in C++20 lower_bound(ForwardIterator first, ForwardIterator last, const T& value); template constexpr ForwardIterator // constexpr in C++20 lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); template constexpr ForwardIterator // constexpr in C++20 upper_bound(ForwardIterator first, ForwardIterator last, const T& value); template constexpr ForwardIterator // constexpr in C++20 upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); template constexpr pair // constexpr in C++20 equal_range(ForwardIterator first, ForwardIterator last, const T& value); template constexpr pair // constexpr in C++20 equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); template constexpr bool // constexpr in C++20 binary_search(ForwardIterator first, ForwardIterator last, const T& value); template constexpr bool // constexpr in C++20 binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); template constexpr OutputIterator // constexpr in C++20 merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template constexpr OutputIterator // constexpr in C++20 merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); template void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); template constexpr bool // constexpr in C++20 includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template constexpr bool // constexpr in C++20 includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); template constexpr OutputIterator // constexpr in C++20 set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template constexpr OutputIterator // constexpr in C++20 set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template constexpr OutputIterator // constexpr in C++20 set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template constexpr OutputIterator // constexpr in C++20 set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template constexpr OutputIterator // constexpr in C++20 set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template constexpr OutputIterator // constexpr in C++20 set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template constexpr OutputIterator // constexpr in C++20 set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template constexpr OutputIterator // constexpr in C++20 set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template constexpr void // constexpr in C++20 push_heap(RandomAccessIterator first, RandomAccessIterator last); template constexpr void // constexpr in C++20 push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template constexpr void // constexpr in C++20 pop_heap(RandomAccessIterator first, RandomAccessIterator last); template constexpr void // constexpr in C++20 pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template constexpr void // constexpr in C++20 make_heap(RandomAccessIterator first, RandomAccessIterator last); template constexpr void // constexpr in C++20 make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template constexpr void // constexpr in C++20 sort_heap(RandomAccessIterator first, RandomAccessIterator last); template constexpr void // constexpr in C++20 sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template constexpr bool // constexpr in C++20 is_heap(RandomAccessIterator first, RandomAccessiterator last); template constexpr bool // constexpr in C++20 is_heap(RandomAccessIterator first, RandomAccessiterator last, Compare comp); template constexpr RandomAccessIterator // constexpr in C++20 is_heap_until(RandomAccessIterator first, RandomAccessiterator last); template constexpr RandomAccessIterator // constexpr in C++20 is_heap_until(RandomAccessIterator first, RandomAccessiterator last, Compare comp); template constexpr ForwardIterator // constexpr in C++14 min_element(ForwardIterator first, ForwardIterator last); template constexpr ForwardIterator // constexpr in C++14 min_element(ForwardIterator first, ForwardIterator last, Compare comp); template constexpr const T& // constexpr in C++14 min(const T& a, const T& b); template constexpr const T& // constexpr in C++14 min(const T& a, const T& b, Compare comp); template constexpr T // constexpr in C++14 min(initializer_list t); template constexpr T // constexpr in C++14 min(initializer_list t, Compare comp); template constexpr const T& clamp(const T& v, const T& lo, const T& hi); // C++17 template constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp); // C++17 template constexpr ForwardIterator // constexpr in C++14 max_element(ForwardIterator first, ForwardIterator last); template constexpr ForwardIterator // constexpr in C++14 max_element(ForwardIterator first, ForwardIterator last, Compare comp); template constexpr const T& // constexpr in C++14 max(const T& a, const T& b); template constexpr const T& // constexpr in C++14 max(const T& a, const T& b, Compare comp); template constexpr T // constexpr in C++14 max(initializer_list t); template constexpr T // constexpr in C++14 max(initializer_list t, Compare comp); template constexpr pair // constexpr in C++14 minmax_element(ForwardIterator first, ForwardIterator last); template constexpr pair // constexpr in C++14 minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); template constexpr pair // constexpr in C++14 minmax(const T& a, const T& b); template constexpr pair // constexpr in C++14 minmax(const T& a, const T& b, Compare comp); template constexpr pair // constexpr in C++14 minmax(initializer_list t); template constexpr pair // constexpr in C++14 minmax(initializer_list t, Compare comp); template constexpr bool // constexpr in C++20 lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template constexpr bool // constexpr in C++20 lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); template constexpr bool // constexpr in C++20 next_permutation(BidirectionalIterator first, BidirectionalIterator last); template constexpr bool // constexpr in C++20 next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); template constexpr bool // constexpr in C++20 prev_permutation(BidirectionalIterator first, BidirectionalIterator last); template constexpr bool // constexpr in C++20 prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); namespace ranges { // [algorithms.results], algorithm result types template struct in_out_result; } } // std */ #include <__bits> // __libcpp_clz #include <__config> #include <__debug> #include #include #include #include #include #include #include #include // swap_ranges #include #include <__algorithm/adjacent_find.h> #include <__algorithm/all_of.h> #include <__algorithm/any_of.h> #include <__algorithm/binary_search.h> #include <__algorithm/clamp.h> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> #include <__algorithm/copy_backward.h> #include <__algorithm/copy_if.h> #include <__algorithm/copy_n.h> #include <__algorithm/count.h> #include <__algorithm/count_if.h> #include <__algorithm/equal.h> #include <__algorithm/equal_range.h> #include <__algorithm/fill.h> #include <__algorithm/fill_n.h> #include <__algorithm/find.h> #include <__algorithm/find_end.h> #include <__algorithm/find_first_of.h> #include <__algorithm/find_if.h> #include <__algorithm/find_if_not.h> #include <__algorithm/for_each.h> #include <__algorithm/for_each_n.h> #include <__algorithm/generate.h> #include <__algorithm/generate_n.h> #include <__algorithm/half_positive.h> #include <__algorithm/in_in_out_result.h> #include <__algorithm/in_in_result.h> #include <__algorithm/in_out_result.h> #include <__algorithm/includes.h> #include <__algorithm/inplace_merge.h> #include <__algorithm/is_heap.h> #include <__algorithm/is_heap_until.h> #include <__algorithm/is_partitioned.h> #include <__algorithm/is_permutation.h> #include <__algorithm/is_sorted.h> #include <__algorithm/is_sorted_until.h> #include <__algorithm/iter_swap.h> #include <__algorithm/lexicographical_compare.h> #include <__algorithm/lower_bound.h> #include <__algorithm/make_heap.h> #include <__algorithm/max.h> #include <__algorithm/max_element.h> #include <__algorithm/merge.h> #include <__algorithm/min.h> #include <__algorithm/min_element.h> #include <__algorithm/minmax.h> #include <__algorithm/minmax_element.h> #include <__algorithm/mismatch.h> #include <__algorithm/move.h> #include <__algorithm/move_backward.h> #include <__algorithm/next_permutation.h> #include <__algorithm/none_of.h> #include <__algorithm/nth_element.h> #include <__algorithm/partial_sort.h> #include <__algorithm/partial_sort_copy.h> #include <__algorithm/partition.h> #include <__algorithm/partition_copy.h> #include <__algorithm/partition_point.h> #include <__algorithm/pop_heap.h> #include <__algorithm/prev_permutation.h> #include <__algorithm/push_heap.h> #include <__algorithm/remove.h> #include <__algorithm/remove_copy.h> #include <__algorithm/remove_copy_if.h> #include <__algorithm/remove_if.h> #include <__algorithm/replace.h> #include <__algorithm/replace_copy.h> #include <__algorithm/replace_copy_if.h> #include <__algorithm/replace_if.h> #include <__algorithm/reverse.h> #include <__algorithm/reverse_copy.h> #include <__algorithm/rotate.h> #include <__algorithm/rotate_copy.h> #include <__algorithm/sample.h> #include <__algorithm/search.h> #include <__algorithm/search_n.h> #include <__algorithm/set_difference.h> #include <__algorithm/set_intersection.h> #include <__algorithm/set_symmetric_difference.h> #include <__algorithm/set_union.h> #include <__algorithm/shift_left.h> #include <__algorithm/shift_right.h> #include <__algorithm/shuffle.h> #include <__algorithm/sift_down.h> #include <__algorithm/sort.h> #include <__algorithm/sort_heap.h> #include <__algorithm/stable_partition.h> #include <__algorithm/stable_sort.h> #include <__algorithm/swap_ranges.h> #include <__algorithm/transform.h> #include <__algorithm/unique.h> #include <__algorithm/unique_copy.h> #include <__algorithm/unwrap_iter.h> #include <__algorithm/upper_bound.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 # include <__pstl_algorithm> #endif #endif // _LIBCPP_ALGORITHM