Standard library header <algorithm>

From cppreference.com
< cpp‎ | header
 
 
 

This header is part of the algorithm library.

Functions

Non-modifying sequence operations
(C++11)(C++11)(C++11)
checks if a predicate is true for all, any or none of the elements in a range
(function template)
applies a function to a range of elements
(function template)
applies a function object to the first n elements of a sequence
(function template)
returns the number of elements satisfying specific criteria
(function template)
finds the first position where two ranges differ
(function template)
finds the first element satisfying specific criteria
(function template)
finds the last sequence of elements in a certain range
(function template)
searches for any one of a set of elements
(function template)
finds the first two adjacent items that are equal (or satisfy a given predicate)
(function template)
searches for a range of elements
(function template)
searches a range for a number of consecutive copies of an element
(function template)
Modifying sequence operations
copies a range of elements to a new location
(function template)
(C++11)
copies a number of elements to a new location
(function template)
copies a range of elements in backwards order
(function template)
(C++11)
moves a range of elements to a new location
(function template)
moves a range of elements to a new location in backwards order
(function template)
copy-assigns the given value to every element in a range
(function template)
copy-assigns the given value to N elements in a range
(function template)
applies a function to a range of elements, storing results in a destination range
(function template)
assigns the results of successive function calls to every element in a range
(function template)
assigns the results of successive function calls to N elements in a range
(function template)
removes elements satisfying specific criteria
(function template)
copies a range of elements omitting those that satisfy specific criteria
(function template)
replaces all values satisfying specific criteria with another value
(function template)
copies a range, replacing elements satisfying specific criteria with another value
(function template)
swaps the values of two objects
(function template)
swaps two ranges of elements
(function template)
swaps the elements pointed to by two iterators
(function template)
reverses the order of elements in a range
(function template)
creates a copy of a range that is reversed
(function template)
rotates the order of elements in a range
(function template)
copies and rotate a range of elements
(function template)
shifts elements in a range
(function template)
(until C++17)(C++11)
randomly re-orders elements in a range
(function template)
(C++17)
selects n random elements from a sequence
(function template)
removes consecutive duplicate elements in a range
(function template)
creates a copy of some range of elements that contains no consecutive duplicates
(function template)
Partitioning operations
determines if the range is partitioned by the given predicate
(function template)
divides a range of elements into two groups
(function template)
copies a range dividing the elements into two groups
(function template)
divides elements into two groups while preserving their relative order
(function template)
locates the partition point of a partitioned range
(function template)
Sorting operations
(C++11)
checks whether a range is sorted into ascending order
(function template)
finds the largest sorted subrange
(function template)
sorts a range into ascending order
(function template)
sorts the first N elements of a range
(function template)
copies and partially sorts a range of elements
(function template)
sorts a range of elements while preserving order between equal elements
(function template)
partially sorts the given range making sure that it is partitioned by the given element
(function template)
Binary search operations (on sorted ranges)
returns an iterator to the first element not less than the given value
(function template)
returns an iterator to the first element greater than a certain value
(function template)
determines if an element exists in a certain range
(function template)
returns range of elements matching a specific key
(function template)
Other operations on sorted ranges
merges two sorted ranges
(function template)
merges two ordered ranges in-place
(function template)
Set operations (on sorted ranges)
returns true if one sequence is a subsequence of another
(function template)
computes the difference between two sets
(function template)
computes the intersection of two sets
(function template)
computes the symmetric difference between two sets
(function template)
computes the union of two sets
(function template)
Heap operations
(C++11)
checks if the given range is a max heap
(function template)
finds the largest subrange that is a max heap
(function template)
creates a max heap out of a range of elements
(function template)
adds an element to a max heap
(function template)
removes the largest element from a max heap
(function template)
turns a max heap into a range of elements sorted in ascending order
(function template)
Minimum/maximum operations
returns the greater of the given values
(function template)
returns the largest element in a range
(function template)
returns the smaller of the given values
(function template)
returns the smallest element in a range
(function template)
(C++11)
returns the smaller and larger of two elements
(function template)
returns the smallest and the largest elements in a range
(function template)
(C++17)
clamps a value between a pair of boundary values
(function template)
Comparison operations
determines if two sets of elements are the same
(function template)
returns true if one range is lexicographically less than another
(function template)
compares two ranges using three-way comparison
(function template)
Permutation operations
determines if a sequence is a permutation of another sequence
(function template)
generates the next greater lexicographic permutation of a range of elements
(function template)
generates the next smaller lexicographic permutation of a range of elements
(function template)

Range Algorithms

Defined in namespace std::ranges
Non-modifying sequence operations
checks if a predicate is true for all, any or none of the elements in a range
(niebloid)
applies a function to a range of elements
(niebloid)
returns the number of elements satisfying specific criteria
(niebloid)
finds the first position where two ranges differ
(niebloid)
finds the first element satisfying specific criteria
(niebloid)
finds the last sequence of elements in a certain range
(niebloid)
searches for any one of a set of elements
(niebloid)
finds the first two adjacent items that are equal (or satisfy a given predicate)
(niebloid)
searches for a range of elements
(niebloid)
searches for a number consecutive copies of an element in a range
(niebloid)
Modifying sequence operations
copies a range of elements to a new location
(niebloid)
copies a number of elements to a new location
(niebloid)
copies a range of elements in backwards order
(niebloid)
moves a range of elements to a new location
(niebloid)
moves a range of elements to a new location in backwards order
(niebloid)
assigns a range of elements a certain value
(niebloid)
assigns a value to a number of elements
(niebloid)
applies a function to a range of elements
(niebloid)
saves the result of a function in a range
(niebloid)
saves the result of N applications of a function
(niebloid)
removes elements satisfying specific criteria
(niebloid)
copies a range of elements omitting those that satisfy specific criteria
(niebloid)
replaces all values satisfying specific criteria with another value
(niebloid)
copies a range, replacing elements satisfying specific criteria with another value
(niebloid)
swaps two ranges of elements
(niebloid)
reverses the order of elements in a range
(niebloid)
creates a copy of a range that is reversed
(niebloid)
rotates the order of elements in a range
(niebloid)
copies and rotate a range of elements
(niebloid)
randomly re-orders elements in a range
(niebloid)
removes consecutive duplicate elements in a range
(niebloid)
creates a copy of some range of elements that contains no consecutive duplicates
(niebloid)
Partitioning operations
determines if the range is partitioned by the given predicate
(niebloid)
divides a range of elements into two groups
(niebloid)
copies a range dividing the elements into two groups
(niebloid)
divides elements into two groups while preserving their relative order
(niebloid)
locates the partition point of a partitioned range
(niebloid)
Sorting operations
checks whether a range is sorted into ascending order
(niebloid)
finds the largest sorted subrange
(niebloid)
sorts a range into ascending order
(niebloid)
sorts the first N elements of a range
(niebloid)
copies and partially sorts a range of elements
(niebloid)
sorts a range of elements while preserving order between equal elements
(niebloid)
partially sorts the given range making sure that it is partitioned by the given element
(niebloid)
Binary search operations (on sorted ranges)
returns an iterator to the first element not less than the given value
(niebloid)
returns an iterator to the first element greater than a certain value
(niebloid)
determines if an element exists in a certain range
(niebloid)
returns range of elements matching a specific key
(niebloid)
Other operations on sorted ranges
merges two sorted ranges
(niebloid)
merges two ordered ranges in-place
(niebloid)
Set operations (on sorted ranges)
returns true if one set is a subset of another
(niebloid)
computes the difference between two sets
(niebloid)
computes the intersection of two sets
(niebloid)
computes the symmetric difference between two sets
(niebloid)
computes the union of two sets
(niebloid)
Heap operations
checks if the given range is a max heap
(niebloid)
finds the largest subrange that is a max heap
(niebloid)
creates a max heap out of a range of elements
(niebloid)
adds an element to a max heap
(niebloid)
removes the largest element from a max heap
(niebloid)
turns a max heap into a range of elements sorted in ascending order
(niebloid)
Minimum/maximum operations
returns the greater of the given values
(niebloid)
returns the largest element in a range
(niebloid)
returns the smaller of the given values
(niebloid)
returns the smallest element in a range
(niebloid)
returns the smaller and larger of two elements
(niebloid)
returns the smallest and the largest elements in a range
(niebloid)
Comparison operations
determines if two sets of elements are the same
(niebloid)
returns true if one range is lexicographically less than another
(niebloid)
Permutation operations
determines if a sequence is a permutation of another sequence
(niebloid)
generates the next greater lexicographic permutation of a range of elements
(niebloid)
generates the next smaller lexicographic permutation of a range of elements
(niebloid)

Synopsis

#include <initializer_list>
 
namespace std {
  // non-modifying sequence operations
  // all of
  template<class InputIter, class Pred>
    constexpr bool all_of(InputIter first, InputIter last, Pred pred);
  template<class ExecutionPolicy, class ForwardIter, class Pred>
    bool all_of(ExecutionPolicy&& exec,
                ForwardIter first, ForwardIter last, Pred pred);
 
  namespace ranges {
    template<input_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      constexpr bool all_of(I first, S last, Pred pred, Proj proj = {});
    template<input_range R, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      constexpr bool all_of(R&& r, Pred pred, Proj proj = {});
  }
 
  // any of
  template<class InputIter, class Pred>
    constexpr bool any_of(InputIter first, InputIter last, Pred pred);
  template<class ExecutionPolicy, class ForwardIter, class Pred>
    bool any_of(ExecutionPolicy&& exec,
                ForwardIter first, ForwardIter last, Pred pred);
 
  namespace ranges {
    template<input_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      constexpr bool any_of(I first, S last, Pred pred, Proj proj = {});
    template<input_range R, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      constexpr bool any_of(R&& r, Pred pred, Proj proj = {});
  }
 
  // none of
  template<class InputIter, class Pred>
    constexpr bool none_of(InputIter first, InputIter last, Pred pred);
  template<class ExecutionPolicy, class ForwardIter, class Pred>
    bool none_of(ExecutionPolicy&& exec,
                 ForwardIter first, ForwardIter last, Pred pred);
 
  namespace ranges {
    template<input_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      constexpr bool none_of(I first, S last, Pred pred, Proj proj = {});
    template<input_range R, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      constexpr bool none_of(R&& r, Pred pred, Proj proj = {});
  }
 
  // for each
  template<class InputIter, class Function>
    constexpr Function for_each(InputIter first, InputIter last, Function f);
  template<class ExecutionPolicy, class ForwardIter, class Function>
    void for_each(ExecutionPolicy&& exec,
                  ForwardIter first, ForwardIter last, Function f);
 
  namespace ranges {
    template<class I, class F>
    struct for_each_result {
      [[no_unique_address]] I in;
      [[no_unique_address]] F fun;
 
      template<class I2, class F2>
        requires convertible_to<const I&, I2> && convertible_to<const F&, F2>
        operator for_each_result<I2, F2>() const & {
          return {in, fun};
        }
 
      template<class I2, class F2>
        requires convertible_to<I, I2> && convertible_to<F, F2>
        operator for_each_result<I2, F2>() && {
          return {std::move(in), std::move(fun)};
        }
    };
 
    template<input_iterator I, sentinel_for<I> S, class Proj = identity,
             indirectly_unary_invocable<projected<I, Proj>> Fun>
      constexpr for_each_result<I, Fun>
        for_each(I first, S last, Fun f, Proj proj = {});
    template<input_range R, class Proj = identity,
             indirectly_unary_invocable<projected<iterator_t<R>, Proj>> Fun>
      constexpr for_each_result<borrowed_iterator_t<R>, Fun>
        for_each(R&& r, Fun f, Proj proj = {});
  }
 
  template<class InputIter, class Size, class Function>
    constexpr InputIter for_each_n(InputIter first, Size n, Function f);
  template<class ExecutionPolicy, class ForwardIter, class Size, class Function>
    ForwardIter for_each_n(ExecutionPolicy&& exec,
                           ForwardIter first, Size n, Function f);
 
  // find
  template<class InputIter, class T>
    constexpr InputIter find(InputIter first, InputIter last, const T& value);
  template<class ExecutionPolicy, class ForwardIter, class T>
    ForwardIter find(ExecutionPolicy&& exec,
                     ForwardIter first, ForwardIter last,const T& value);
  template<class InputIter, class Pred>
    constexpr InputIter find_if(InputIter first, InputIter last, Pred pred);
  template<class ExecutionPolicy, class ForwardIter, class Pred>
    ForwardIter find_if(ExecutionPolicy&& exec,
                        ForwardIter first, ForwardIter last, Pred pred);
  template<class InputIter, class Pred>
    constexpr InputIter find_if_not(InputIter first, InputIter last, Pred pred);
  template<class ExecutionPolicy, class ForwardIter, class Pred>
    ForwardIter find_if_not(ExecutionPolicy&& exec,
                            ForwardIter first, ForwardIter last, Pred pred);
 
  namespace ranges {
    template<input_iterator I, sentinel_for<I> S, class T, class Proj = identity>
      requires indirect_relation<ranges::equal_to, projected<I, Proj>, const T*>
      constexpr I find(I first, S last, const T& value, Proj proj = {});
    template<input_range R, class T, class Proj = identity>
      requires indirect_relation<ranges::equal_to,
                                 projected<iterator_t<R>, Proj>, const T*>
      constexpr borrowed_iterator_t<R>
        find(R&& r, const T& value, Proj proj = {});
    template<input_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      constexpr I find_if(I first, S last, Pred pred, Proj proj = {});
    template<input_range R, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      constexpr borrowed_iterator_t<R>
        find_if(R&& r, Pred pred, Proj proj = {});
    template<input_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      constexpr I find_if_not(I first, S last, Pred pred, Proj proj = {});
    template<input_range R, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      constexpr borrowed_iterator_t<R>
        find_if_not(R&& r, Pred pred, Proj proj = {});
  }
 
  // find end
  template<class ForwardIter1, class ForwardIter2>
    constexpr ForwardIter1
      find_end(ForwardIter1 first1, ForwardIter1 last1,
               ForwardIter2 first2, ForwardIter2 last2);
  template<class ForwardIter1, class ForwardIter2, class BinaryPred>
    constexpr ForwardIter1
      find_end(ForwardIter1 first1, ForwardIter1 last1,
               ForwardIter2 first2, ForwardIter2 last2, BinaryPred pred);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    ForwardIter1
      find_end(ExecutionPolicy&& exec,
               ForwardIter1 first1, ForwardIter1 last1,
               ForwardIter2 first2, ForwardIter2 last2);
  template<class ExecutionPolicy, class ForwardIter1,
           class ForwardIter2, class BinaryPred>
    ForwardIter1
      find_end(ExecutionPolicy&& exec,
               ForwardIter1 first1, ForwardIter1 last1,
               ForwardIter2 first2, ForwardIter2 last2, BinaryPred pred);
 
  namespace ranges {
    template<forward_iterator I1, sentinel_for<I1> S1,
             forward_iterator I2, sentinel_for<I2> S2,
             class Pred = ranges::equal_to,
             class Proj1 = identity, class Proj2 = identity>
      requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
      constexpr subrange<I1>
        find_end(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
                 Proj1 proj1 = {}, Proj2 proj2 = {});
    template<forward_range R1, forward_range R2,
             class Pred = ranges::equal_to,
             class Proj1 = identity, class Proj2 = identity>
      requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
      constexpr borrowed_subrange_t<R1>
        find_end(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  // find first
  template<class InputIter, class ForwardIter>
    constexpr InputIter
      find_first_of(InputIter first1, InputIter last1,
                    ForwardIter first2, ForwardIter last2);
  template<class InputIter, class ForwardIter, class BinaryPred>
    constexpr InputIter
      find_first_of(InputIter first1, InputIter last1,
                    ForwardIter first2, ForwardIter last2, BinaryPred pred);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    ForwardIter1
      find_first_of(ExecutionPolicy&& exec,
                    ForwardIter1 first1, ForwardIter1 last1,
                    ForwardIter2 first2, ForwardIter2 last2);
  template<class ExecutionPolicy, class ForwardIter1,
           class ForwardIter2, class BinaryPred>
    ForwardIter1
      find_first_of(ExecutionPolicy&& exec,
                    ForwardIter1 first1, ForwardIter1 last1,
                    ForwardIter2 first2, ForwardIter2 last2, BinaryPred pred);
 
  namespace ranges {
    template<input_iterator I1, sentinel_for<I1> S1,
             forward_iterator I2, sentinel_for<I2> S2,
             class Proj1 = identity, class Proj2 = identity,
             indirect_relation<projected<I1, Proj1>,
                               projected<I2, Proj2>> Pred = ranges::equal_to>
      constexpr I1 find_first_of(I1 first1, S1 last1, I2 first2, S2 last2,
                                 Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, forward_range R2,
             class Proj1 = identity, class Proj2 = identity,
             indirect_relation<projected<iterator_t<R1>, Proj1>,
                               projected<iterator_t<R2>, Proj2>> Pred = ranges::equal_to>
      constexpr borrowed_iterator_t<R1>
        find_first_of(R1&& r1, R2&& r2, Pred pred = {},
                      Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  // adjacent find
  template<class ForwardIter>
    constexpr ForwardIter
      adjacent_find(ForwardIter first, ForwardIter last);
  template<class ForwardIter, class BinaryPred>
    constexpr ForwardIter
      adjacent_find(ForwardIter first, ForwardIter last, BinaryPred pred);
  template<class ExecutionPolicy, class ForwardIter>
    ForwardIter
      adjacent_find(ExecutionPolicy&& exec,
                    ForwardIter first, ForwardIter last);
  template<class ExecutionPolicy, class ForwardIter, class BinaryPred>
    ForwardIter
      adjacent_find(ExecutionPolicy&& exec,
                    ForwardIter first, ForwardIter last, BinaryPred pred);
 
  namespace ranges {
    template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_relation<projected<I, Proj>> Pred = ranges::equal_to>
      constexpr I adjacent_find(I first, S last, Pred pred = {}, Proj proj = {});
    template<forward_range R, class Proj = identity,
             indirect_relation<projected<iterator_t<R>, Proj>> Pred = ranges::equal_to>
      constexpr borrowed_iterator_t<R>
        adjacent_find(R&& r, Pred pred = {}, Proj proj = {});
  }
 
  // count
  template<class InputIter, class T>
    constexpr typename iterator_traits<InputIter>::difference_type
      count(InputIter first, InputIter last, const T& value);
  template<class ExecutionPolicy, class ForwardIter, class T>
    typename iterator_traits<ForwardIter>::difference_type
      count(ExecutionPolicy&& exec,
            ForwardIter first, ForwardIter last, const T& value);
  template<class InputIter, class Pred>
    constexpr typename iterator_traits<InputIter>::difference_type
      count_if(InputIter first, InputIter last, Pred pred);
  template<class ExecutionPolicy, class ForwardIter, class Pred>
    typename iterator_traits<ForwardIter>::difference_type
      count_if(ExecutionPolicy&& exec,
               ForwardIter first, ForwardIter last, Pred pred);
 
  namespace ranges {
    template<input_iterator I, sentinel_for<I> S, class T, class Proj = identity>
      requires indirect_relation<ranges::equal_to, projected<I, Proj>, const T*>
      constexpr iter_difference_t<I>
        count(I first, S last, const T& value, Proj proj = {});
    template<input_range R, class T, class Proj = identity>
      requires indirect_relation<ranges::equal_to, projected<iterator_t<R>, Proj>,
                                 const T*>
      constexpr range_difference_t<R>
        count(R&& r, const T& value, Proj proj = {});
    template<input_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      constexpr iter_difference_t<I>
        count_if(I first, S last, Pred pred, Proj proj = {});
    template<input_range R, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      constexpr range_difference_t<R>
        count_if(R&& r, Pred pred, Proj proj = {});
  }
 
  // mismatch
  template<class InputIter1, class InputIter2>
    constexpr pair<InputIter1, InputIter2>
      mismatch(InputIter1 first1, InputIter1 last1, InputIter2 first2);
  template<class InputIter1, class InputIter2, class BinaryPred>
    constexpr pair<InputIter1, InputIter2>
      mismatch(InputIter1 first1, InputIter1 last1, InputIter2 first2, BinaryPred pred);
  template<class InputIter1, class InputIter2>
    constexpr pair<InputIter1, InputIter2>
      mismatch(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2);
  template<class InputIter1, class InputIter2, class BinaryPred>
    constexpr pair<InputIter1, InputIter2>
      mismatch(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2,
               BinaryPred pred);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    pair<ForwardIter1, ForwardIter2>
      mismatch(ExecutionPolicy&& exec,
               ForwardIter1 first1, ForwardIter1 last1, ForwardIter2 first2);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class BinaryPred>
    pair<ForwardIter1, ForwardIter2>
      mismatch(ExecutionPolicy&& exec,
               ForwardIter1 first1, ForwardIter1 last1,
               ForwardIter2 first2, BinaryPred pred);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    pair<ForwardIter1, ForwardIter2>
      mismatch(ExecutionPolicy&& exec,
               ForwardIter1 first1, ForwardIter1 last1,
               ForwardIter2 first2, ForwardIter2 last2);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class BinaryPred>
    pair<ForwardIter1, ForwardIter2>
      mismatch(ExecutionPolicy&& exec,
               ForwardIter1 first1, ForwardIter1 last1,
               ForwardIter2 first2, ForwardIter2 last2, BinaryPred pred);
 
  namespace ranges {
    template<class I1, class I2>
    struct mismatch_result {
      [[no_unique_address]] I1 in1;
      [[no_unique_address]] I2 in2;
 
      template<class II1, class II2>
        requires convertible_to<const I1&, II1> && convertible_to<const I2&, II2>
        operator mismatch_result<II1, II2>() const & {
          return {in1, in2};
        }
 
      template<class II1, class II2>
        requires convertible_to<I1, II1> && convertible_to<I2, II2>
        operator mismatch_result<II1, II2>() && {
          return {std::move(in1), std::move(in2)};
        }
    };
 
    template<input_iterator I1, sentinel_for<I1> S1,
             input_iterator I2, sentinel_for<I2> S2,
             class Proj1 = identity, class Proj2 = identity,
             indirect_relation<projected<I1, Proj1>,
                               projected<I2, Proj2>> Pred = ranges::equal_to>
      constexpr mismatch_result<I1, I2>
        mismatch(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
                 Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, input_range R2,
             class Proj1 = identity, class Proj2 = identity,
             indirect_relation<projected<iterator_t<R1>, Proj1>,
                               projected<iterator_t<R2>, Proj2>> Pred = ranges::equal_to>
      constexpr mismatch_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
        mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  // equal
  template<class InputIter1, class InputIter2>
    constexpr bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2);
  template<class InputIter1, class InputIter2, class BinaryPred>
    constexpr bool equal(InputIter1 first1, InputIter1 last1,
                         InputIter2 first2, BinaryPred pred);
  template<class InputIter1, class InputIter2>
    constexpr bool equal(InputIter1 first1, InputIter1 last1,
                         InputIter2 first2, InputIter2 last2);
  template<class InputIter1, class InputIter2, class BinaryPred>
    constexpr bool equal(InputIter1 first1, InputIter1 last1,
                         InputIter2 first2, InputIter2 last2, BinaryPred pred);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    bool equal(ExecutionPolicy&& exec,
               ForwardIter1 first1, ForwardIter1 last1, ForwardIter2 first2);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class BinaryPred>
    bool equal(ExecutionPolicy&& exec,
               ForwardIter1 first1, ForwardIter1 last1,
               ForwardIter2 first2, BinaryPred pred);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    bool equal(ExecutionPolicy&& exec,
               ForwardIter1 first1, ForwardIter1 last1,
               ForwardIter2 first2, ForwardIter2 last2);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class BinaryPred>
    bool equal(ExecutionPolicy&& exec,
               ForwardIter1 first1, ForwardIter1 last1,
               ForwardIter2 first2, ForwardIter2 last2, BinaryPred pred);
 
  namespace ranges {
    template<input_iterator I1, sentinel_for<I1> S1,
             input_iterator I2, sentinel_for<I2> S2,
             class Pred = ranges::equal_to,
             class Proj1 = identity, class Proj2 = identity>
      requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
      constexpr bool equal(I1 first1, S1 last1, I2 first2, S2 last2,
                           Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, input_range R2, class Pred = ranges::equal_to,
             class Proj1 = identity, class Proj2 = identity>
      requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
      constexpr bool equal(R1&& r1, R2&& r2, Pred pred = {},
                           Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  // is permutation
  template<class ForwardIter1, class ForwardIter2>
    constexpr bool is_permutation(ForwardIter1 first1, ForwardIter1 last1,
                                  ForwardIter2 first2);
  template<class ForwardIter1, class ForwardIter2, class BinaryPred>
    constexpr bool is_permutation(ForwardIter1 first1, ForwardIter1 last1,
                                  ForwardIter2 first2, BinaryPred pred);
  template<class ForwardIter1, class ForwardIter2>
    constexpr bool is_permutation(ForwardIter1 first1, ForwardIter1 last1,
                                  ForwardIter2 first2, ForwardIter2 last2);
  template<class ForwardIter1, class ForwardIter2, class BinaryPred>
    constexpr bool is_permutation(ForwardIter1 first1, ForwardIter1 last1,
                                  ForwardIter2 first2, ForwardIter2 last2,
                                  BinaryPred pred);
 
  namespace ranges {
    template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,
             sentinel_for<I2> S2, class Pred = ranges::equal_to, class Proj1 = identity,
             class Proj2 = identity>
      requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
      constexpr bool is_permutation(I1 first1, S1 last1, I2 first2, S2 last2,
                                    Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
    template<forward_range R1, forward_range R2, class Pred = ranges::equal_to,
             class Proj1 = identity, class Proj2 = identity>
      requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
      constexpr bool is_permutation(R1&& r1, R2&& r2, Pred pred = {},
                                    Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  // search
  template<class ForwardIter1, class ForwardIter2>
    constexpr ForwardIter1
      search(ForwardIter1 first1, ForwardIter1 last1,
             ForwardIter2 first2, ForwardIter2 last2);
  template<class ForwardIter1, class ForwardIter2, class BinaryPred>
    constexpr ForwardIter1
      search(ForwardIter1 first1, ForwardIter1 last1,
             ForwardIter2 first2, ForwardIter2 last2,
             BinaryPred pred);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    ForwardIter1
      search(ExecutionPolicy&& exec,
             ForwardIter1 first1, ForwardIter1 last1,
             ForwardIter2 first2, ForwardIter2 last2);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class BinaryPred>
    ForwardIter1
      search(ExecutionPolicy&& exec,
             ForwardIter1 first1, ForwardIter1 last1,
             ForwardIter2 first2, ForwardIter2 last2, BinaryPred pred);
 
  namespace ranges {
    template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,
             sentinel_for<I2> S2, class Pred = ranges::equal_to,
             class Proj1 = identity, class Proj2 = identity>
      requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
      constexpr subrange<I1>
        search(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
               Proj1 proj1 = {}, Proj2 proj2 = {});
    template<forward_range R1, forward_range R2, class Pred = ranges::equal_to,
             class Proj1 = identity, class Proj2 = identity>
      requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
      constexpr borrowed_subrange_t<R1>
        search(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  template<class ForwardIter, class Size, class T>
    constexpr ForwardIter
      search_n(ForwardIter first, ForwardIter last, Size count, const T& value);
  template<class ForwardIter, class Size, class T, class BinaryPred>
    constexpr ForwardIter
      search_n(ForwardIter first, ForwardIter last, Size count, const T& value,
               BinaryPred pred);
  template<class ExecutionPolicy, class ForwardIter, class Size, class T>
    ForwardIter
      search_n(ExecutionPolicy&& exec,
               ForwardIter first, ForwardIter last, Size count, const T& value);
  template<class ExecutionPolicy, class ForwardIter, class Size, class T,
           class BinaryPred>
    ForwardIter
      search_n(ExecutionPolicy&& exec,
               ForwardIter first, ForwardIter last, Size count, const T& value,
               BinaryPred pred);
 
  namespace ranges {
    template<forward_iterator I, sentinel_for<I> S, class T,
             class Pred = ranges::equal_to, class Proj = identity>
      requires indirectly_comparable<I, const T*, Pred, Proj>
      constexpr subrange<I>
        search_n(I first, S last, iter_difference_t<I> count,
                 const T& value, Pred pred = {}, Proj proj = {});
    template<forward_range R, class T, class Pred = ranges::equal_to,
             class Proj = identity>
      requires indirectly_comparable<iterator_t<R>, const T*, Pred, Proj>
      constexpr borrowed_subrange_t<R>
        search_n(R&& r, range_difference_t<R> count,
                 const T& value, Pred pred = {}, Proj proj = {});
  }
 
  template<class ForwardIter, class Searcher>
    constexpr ForwardIter
      search(ForwardIter first, ForwardIter last, const Searcher& searcher);
 
  // mutating sequence operations
  // copy
  template<class InputIter, class OutputIter>
    constexpr OutputIter copy(InputIter first, InputIter last, OutputIter result);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    ForwardIter2 copy(ExecutionPolicy&& exec,
                      ForwardIter1 first, ForwardIter1 last, ForwardIter2 result);
 
  namespace ranges {
    template<class I, class O>
    struct copy_result {
      [[no_unique_address]] I in;
      [[no_unique_address]] O out;
 
      template<class I2, class O2>
        requires convertible_to<const I&, I2> && convertible_to<const O&, O2>
        operator copy_result<I2, O2>() const & {
          return {in, out};
        }
 
      template<class I2, class O2>
        requires convertible_to<I, I2> && convertible_to<O, O2>
        operator copy_result<I2, O2>() && {
          return {std::move(in), std::move(out)};
        }
    };
 
    template<input_iterator I, sentinel_for<I> S, weakly_incrementable O>
      requires indirectly_copyable<I, O>
      constexpr copy_result<I, O>
        copy(I first, S last, O result);
    template<input_range R, weakly_incrementable O>
      requires indirectly_copyable<iterator_t<R>, O>
      constexpr copy_result<borrowed_iterator_t<R>, O>
        copy(R&& r, O result);
  }
 
  template<class InputIter, class Size, class OutputIter>
    constexpr OutputIter copy_n(InputIter first, Size n, OutputIter result);
  template<class ExecutionPolicy, class ForwardIter1, class Size,
           class ForwardIter2>
    ForwardIter2 copy_n(ExecutionPolicy&& exec,
                        ForwardIter1 first, Size n, ForwardIter2 result);
 
  namespace ranges {
    template<class I, class O>
    using copy_n_result = copy_result<I, O>;
 
    template<input_iterator I, weakly_incrementable O>
      requires indirectly_copyable<I, O>
      constexpr copy_n_result<I, O>
        copy_n(I first, iter_difference_t<I> n, O result);
  }
 
  template<class InputIter, class OutputIter, class Pred>
    constexpr OutputIter copy_if(InputIter first, InputIter last,
                                 OutputIter result, Pred pred);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2, class Pred>
    ForwardIter2 copy_if(ExecutionPolicy&& exec,
                         ForwardIter1 first, ForwardIter1 last,
                         ForwardIter2 result, Pred pred);
 
  namespace ranges {
    template<class I, class O>
    using copy_if_result = copy_result<I, O>;
 
    template<input_iterator I, sentinel_for<I> S,
             weakly_incrementable O, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      requires indirectly_copyable<I, O>
      constexpr copy_if_result<I, O>
        copy_if(I first, S last, O result, Pred pred, Proj proj = {});
    template<input_range R, weakly_incrementable O, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      requires indirectly_copyable<iterator_t<R>, O>
      constexpr copy_if_result<borrowed_iterator_t<R>, O>
        copy_if(R&& r, O result, Pred pred, Proj proj = {});
  }
 
  template<class BidirectionalIter1, class BidirectionalIter2>
    constexpr BidirectionalIter2
      copy_backward(BidirectionalIter1 first, BidirectionalIter1 last,
                    BidirectionalIter2 result);
 
  namespace ranges {
    template<class I1, class I2>
    using copy_backward_result = copy_result<I1, I2>;
 
    template<bidirectional_iterator I1, sentinel_for<I1> S1, bidirectional_iterator I2>
      requires indirectly_copyable<I1, I2>
      constexpr copy_backward_result<I1, I2>
        copy_backward(I1 first, S1 last, I2 result);
    template<bidirectional_range R, bidirectional_iterator I>
      requires indirectly_copyable<iterator_t<R>, I>
      constexpr copy_backward_result<borrowed_iterator_t<R>, I>
        copy_backward(R&& r, I result);
  }
 
  // move
  template<class InputIter, class OutputIter>
    constexpr OutputIter move(InputIter first, InputIter last, OutputIter result);
  template<class ExecutionPolicy, class ForwardIter1,
           class ForwardIter2>
    ForwardIter2 move(ExecutionPolicy&& exec,
                      ForwardIter1 first, ForwardIter1 last, ForwardIter2 result);
 
  namespace ranges {
    template<class I, class O>
    using move_result = copy_result<I, O>;
 
    template<input_iterator I, sentinel_for<I> S, weakly_incrementable O>
      requires indirectly_movable<I, O>
      constexpr move_result<I, O>
        move(I first, S last, O result);
    template<input_range R, weakly_incrementable O>
      requires indirectly_movable<iterator_t<R>, O>
      constexpr move_result<borrowed_iterator_t<R>, O>
        move(R&& r, O result);
  }
 
  template<class BidirectionalIter1, class BidirectionalIter2>
    constexpr BidirectionalIter2
      move_backward(BidirectionalIter1 first, BidirectionalIter1 last,
                    BidirectionalIter2 result);
 
  namespace ranges {
    template<class I1, class I2>
    using move_backward_result = copy_result<I1, I2>;
 
    template<bidirectional_iterator I1, sentinel_for<I1> S1, bidirectional_iterator I2>
      requires indirectly_movable<I1, I2>
      constexpr move_backward_result<I1, I2>
        move_backward(I1 first, S1 last, I2 result);
    template<bidirectional_range R, bidirectional_iterator I>
      requires indirectly_movable<iterator_t<R>, I>
      constexpr move_backward_result<borrowed_iterator_t<R>, I>
        move_backward(R&& r, I result);
  }
 
  // swap
  template<class ForwardIter1, class ForwardIter2>
    constexpr ForwardIter2 swap_ranges(ForwardIter1 first1, ForwardIter1 last1,
                                       ForwardIter2 first2);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    ForwardIter2 swap_ranges(ExecutionPolicy&& exec,
                             ForwardIter1 first1, ForwardIter1 last1,
                             ForwardIter2 first2);
 
  namespace ranges {
    template<class I1, class I2>
    using swap_ranges_result = mismatch_result<I1, I2>;
 
    template<input_iterator I1, sentinel_for<I1> S1,
             input_iterator I2, sentinel_for<I2> S2>
      requires indirectly_swappable<I1, I2>
      constexpr swap_ranges_result<I1, I2>
        swap_ranges(I1 first1, S1 last1, I2 first2, S2 last2);
    template<input_range R1, input_range R2>
      requires indirectly_swappable<iterator_t<R1>, iterator_t<R2>>
      constexpr swap_ranges_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
        swap_ranges(R1&& r1, R2&& r2);
  }
 
  template<class ForwardIter1, class ForwardIter2>
    constexpr void iter_swap(ForwardIter1 a, ForwardIter2 b);
 
  // transform
  template<class InputIter, class OutputIter, class UnaryOp>
    constexpr OutputIter
      transform(InputIter first1, InputIter last1, OutputIter result, UnaryOp op);
  template<class InputIter1, class InputIter2, class OutputIter, class BinaryOp>
    constexpr OutputIter
      transform(InputIter1 first1, InputIter1 last1, InputIter2 first2, OutputIter result,
                BinaryOp binary_op);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2, class UnaryOp>
    ForwardIter2
      transform(ExecutionPolicy&& exec,
                ForwardIter1 first1, ForwardIter1 last1, ForwardIter2 result, UnaryOp op);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class ForwardIter, class BinaryOp>
    ForwardIter
      transform(ExecutionPolicy&& exec,
                ForwardIter1 first1, ForwardIter1 last1,
                ForwardIter2 first2, ForwardIter result, BinaryOp binary_op);
 
  namespace ranges {
    template<class I, class O>
    using unary_transform_result = copy_result<I, O>;
 
    template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
             copy_constructible F, class Proj = identity>
      requires writable<O, indirect_result_t<F&, projected<I, Proj>>>
      constexpr unary_transform_result<I, O>
        transform(I first1, S last1, O result, F op, Proj proj = {});
    template<input_range R, weakly_incrementable O, copy_constructible F,
             class Proj = identity>
      requires writable<O, indirect_result_t<F&, projected<iterator_t<R>, Proj>>>
      constexpr unary_transform_result<borrowed_iterator_t<R>, O>
        transform(R&& r, O result, F op, Proj proj = {});
 
    template<class I1, class I2, class O>
    struct binary_transform_result {
      [[no_unique_address]] I1 in1;
      [[no_unique_address]] I2 in2;
      [[no_unique_address]] O  out;
 
      template<class II1, class II2, class OO>
        requires convertible_to<const I1&, II1> &&
          convertible_to<const I2&, II2> && convertible_to<const O&, OO>
        operator binary_transform_result<II1, II2, OO>() const & {
          return {in1, in2, out};
        }
 
      template<class II1, class II2, class OO>
        requires convertible_to<I1, II1> &&
          convertible_to<I2, II2> && convertible_to<O, OO>
        operator binary_transform_result<II1, II2, OO>() && {
          return {std::move(in1), std::move(in2), std::move(out)};
        }
    };
 
    template<input_iterator I1, sentinel_for<I1> S1,
             input_iterator I2, sentinel_for<I2> S2,
             weakly_incrementable O, copy_constructible F, class Proj1 = identity,
             class Proj2 = identity>
      requires writable<O, indirect_result_t<F&, projected<I1, Proj1>,
                                             projected<I2, Proj2>>>
      constexpr binary_transform_result<I1, I2, O>
        transform(I1 first1, S1 last1, I2 first2, S2 last2, O result,
                  F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, input_range R2, weakly_incrementable O,
             copy_constructible F, class Proj1 = identity, class Proj2 = identity>
      requires writable<O, indirect_result_t<F&, projected<iterator_t<R1>, Proj1>,
                                             projected<iterator_t<R2>, Proj2>>>
      constexpr binary_transform_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
        transform(R1&& r1, R2&& r2, O result,
                  F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  // replace
  template<class ForwardIter, class T>
    constexpr void replace(ForwardIter first, ForwardIter last,
                           const T& old_value, const T& new_value);
  template<class ExecutionPolicy, class ForwardIter, class T>
    void replace(ExecutionPolicy&& exec,
                 ForwardIter first, ForwardIter last,
                 const T& old_value, const T& new_value);
  template<class ForwardIter, class Pred, class T>
    constexpr void replace_if(ForwardIter first, ForwardIter last,
                              Pred pred, const T& new_value);
  template<class ExecutionPolicy, class ForwardIter, class Pred, class T>
    void replace_if(ExecutionPolicy&& exec,
                    ForwardIter first, ForwardIter last, Pred pred, const T& new_value);
 
  namespace ranges {
    template<input_iterator I, sentinel_for<I> S,
             class T1, class T2, class Proj = identity>
      requires writable<I, const T2&> &&
               indirect_relation<ranges::equal_to, projected<I, Proj>, const T1*>
      constexpr I
        replace(I first, S last, const T1& old_value, const T2& new_value,
                Proj proj = {});
    template<input_range R, class T1, class T2, class Proj = identity>
      requires writable<iterator_t<R>, const T2&> &&
               indirect_relation<ranges::equal_to, projected<iterator_t<R>, Proj>,
                                 const T1*>
      constexpr borrowed_iterator_t<R>
        replace(R&& r, const T1& old_value, const T2& new_value, Proj proj = {});
    template<input_iterator I, sentinel_for<I> S, class T, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      requires writable<I, const T&>
      constexpr I replace_if(I first, S last, Pred pred, const T& new_value,
                             Proj proj = {});
    template<input_range R, class T, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      requires writable<iterator_t<R>, const T&>
      constexpr borrowed_iterator_t<R>
        replace_if(R&& r, Pred pred, const T& new_value, Proj proj = {});
  }
 
  template<class InputIter, class OutputIter, class T>
    constexpr OutputIter replace_copy(InputIter first, InputIter last, OutputIter result,
                                      const T& old_value, const T& new_value);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2, class T>
    ForwardIter2 replace_copy(ExecutionPolicy&& exec,
                              ForwardIter1 first, ForwardIter1 last, ForwardIter2 result,
                              const T& old_value, const T& new_value);
  template<class InputIter, class OutputIter, class Pred, class T>
    constexpr OutputIter replace_copy_if(InputIter first, InputIter last,
                                         OutputIter result,
                                         Pred pred, const T& new_value);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class Pred, class T>
    ForwardIter2 replace_copy_if(ExecutionPolicy&& exec,
                                 ForwardIter1 first, ForwardIter1 last,
                                 ForwardIter2 result, Pred pred, const T& new_value);
 
  namespace ranges {
    template<class I, class O>
    using replace_copy_result = copy_result<I, O>;
 
    template<input_iterator I, sentinel_for<I> S, class T1, class T2,
             output_iterator<const T2&> O, class Proj = identity>
      requires indirectly_copyable<I, O> &&
               indirect_relation<ranges::equal_to, projected<I, Proj>, const T1*>
      constexpr replace_copy_result<I, O>
        replace_copy(I first, S last, O result, const T1& old_value, const T2& new_value,
                     Proj proj = {});
    template<input_range R, class T1, class T2, output_iterator<const T2&> O,
             class Proj = identity>
      requires indirectly_copyable<iterator_t<R>, O> &&
               indirect_relation<ranges::equal_to,
                                 projected<iterator_t<R>, Proj>, const T1*>
      constexpr replace_copy_result<borrowed_iterator_t<R>, O>
        replace_copy(R&& r, O result, const T1& old_value, const T2& new_value,
                     Proj proj = {});
 
    template<class I, class O>
    using replace_copy_if_result = copy_result<I, O>;
 
    template<input_iterator I, sentinel_for<I> S, class T, output_iterator<const T&> O,
             class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>
      requires indirectly_copyable<I, O>
      constexpr replace_copy_if_result<I, O>
        replace_copy_if(I first, S last, O result, Pred pred, const T& new_value,
                        Proj proj = {});
    template<input_range R, class T, output_iterator<const T&> O, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      requires indirectly_copyable<iterator_t<R>, O>
      constexpr replace_copy_if_result<borrowed_iterator_t<R>, O>
        replace_copy_if(R&& r, O result, Pred pred, const T& new_value, Proj proj = {});
  }
 
  // fill
  template<class ForwardIter, class T>
    constexpr void fill(ForwardIter first, ForwardIter last, const T& value);
  template<class ExecutionPolicy, class ForwardIter, class T>
    void fill(ExecutionPolicy&& exec,
              ForwardIter first, ForwardIter last, const T& value);
  template<class OutputIter, class Size, class T>
    constexpr OutputIter fill_n(OutputIter first, Size n, const T& value);
  template<class ExecutionPolicy, class ForwardIter,
           class Size, class T>
    ForwardIter fill_n(ExecutionPolicy&& exec, ForwardIter first, Size n, const T& value);
 
  namespace ranges {
    template<class T, output_iterator<const T&> O, sentinel_for<O> S>
      constexpr O fill(O first, S last, const T& value);
    template<class T, output_range<const T&> R>
      constexpr borrowed_iterator_t<R> fill(R&& r, const T& value);
    template<class T, output_iterator<const T&> O>
      constexpr O fill_n(O first, iter_difference_t<O> n, const T& value);
  }
 
  // generate
  template<class ForwardIter, class Generator>
    constexpr void generate(ForwardIter first, ForwardIter last, Generator gen);
  template<class ExecutionPolicy, class ForwardIter, class Generator>
    void generate(ExecutionPolicy&& exec,
                  ForwardIter first, ForwardIter last, Generator gen);
  template<class OutputIter, class Size, class Generator>
    constexpr OutputIter generate_n(OutputIter first, Size n, Generator gen);
  template<class ExecutionPolicy, class ForwardIter, class Size, class Generator>
    ForwardIter generate_n(ExecutionPolicy&& exec,
                           ForwardIter first, Size n, Generator gen);
 
  namespace ranges {
    template<input_or_output_iterator O, sentinel_for<O> S, copy_constructible F>
      requires invocable<F&> && writable<O, invoke_result_t<F&>>
      constexpr O generate(O first, S last, F gen);
    template<class R, copy_constructible F>
      requires invocable<F&> && output_range<R, invoke_result_t<F&>>
      constexpr borrowed_iterator_t<R> generate(R&& r, F gen);
    template<input_or_output_iterator O, copy_constructible F>
      requires invocable<F&> && writable<O, invoke_result_t<F&>>
      constexpr O generate_n(O first, iter_difference_t<O> n, F gen);
  }
 
  // remove
  template<class ForwardIter, class T>
    constexpr ForwardIter remove(ForwardIter first, ForwardIter last, const T& value);
  template<class ExecutionPolicy, class ForwardIter, class T>
    ForwardIter remove(ExecutionPolicy&& exec,
                       ForwardIter first, ForwardIter last, const T& value);
  template<class ForwardIter, class Pred>
    constexpr ForwardIter remove_if(ForwardIter first, ForwardIter last, Pred pred);
  template<class ExecutionPolicy, class ForwardIter, class Pred>
    ForwardIter remove_if(ExecutionPolicy&& exec,
                          ForwardIter first, ForwardIter last, Pred pred);
 
  namespace ranges {
    template<permutable I, sentinel_for<I> S, class T, class Proj = identity>
      requires indirect_relation<ranges::equal_to, projected<I, Proj>, const T*>
      constexpr subrange<I> remove(I first, S last, const T& value, Proj proj = {});
    template<forward_range R, class T, class Proj = identity>
      requires permutable<iterator_t<R>> &&
               indirect_relation<ranges::equal_to,
                                 projected<iterator_t<R>, Proj>, const T*>
      constexpr borrowed_subrange_t<R>
        remove(R&& r, const T& value, Proj proj = {});
    template<permutable I, sentinel_for<I> S, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      constexpr subrange<I> remove_if(I first, S last, Pred pred, Proj proj = {});
    template<forward_range R, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      requires permutable<iterator_t<R>>
      constexpr borrowed_subrange_t<R>
        remove_if(R&& r, Pred pred, Proj proj = {});
  }
 
  template<class InputIter, class OutputIter, class T>
    constexpr OutputIter
      remove_copy(InputIter first, InputIter last, OutputIter result, const T& value);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2, class T>
    ForwardIter2
      remove_copy(ExecutionPolicy&& exec,
                  ForwardIter1 first, ForwardIter1 last,
                  ForwardIter2 result, const T& value);
  template<class InputIter, class OutputIter, class Pred>
    constexpr OutputIter
      remove_copy_if(InputIter first, InputIter last, OutputIter result, Pred pred);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2, class Pred>
    ForwardIter2
      remove_copy_if(ExecutionPolicy&& exec,
                     ForwardIter1 first, ForwardIter1 last,
                     ForwardIter2 result, Pred pred);
 
  namespace ranges {
    template<class I, class O>
    using remove_copy_result = copy_result<I, O>;
 
    template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class T,
             class Proj = identity>
      requires indirectly_copyable<I, O> &&
               indirect_relation<ranges::equal_to, projected<I, Proj>, const T*>
      constexpr remove_copy_result<I, O>
        remove_copy(I first, S last, O result, const T& value, Proj proj = {});
    template<input_range R, weakly_incrementable O, class T, class Proj = identity>
      requires indirectly_copyable<iterator_t<R>, O> &&
               indirect_relation<ranges::equal_to,
                                 projected<iterator_t<R>, Proj>, const T*>
      constexpr remove_copy_result<borrowed_iterator_t<R>, O>
        remove_copy(R&& r, O result, const T& value, Proj proj = {});
 
    template<class I, class O>
    using remove_copy_if_result = copy_result<I, O>;
 
    template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
             class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>
      requires indirectly_copyable<I, O>
      constexpr remove_copy_if_result<I, O>
        remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {});
    template<input_range R, weakly_incrementable O, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      requires indirectly_copyable<iterator_t<R>, O>
      constexpr remove_copy_if_result<borrowed_iterator_t<R>, O>
        remove_copy_if(R&& r, O result, Pred pred, Proj proj = {});
  }
 
  // unique
  template<class ForwardIter>
    constexpr ForwardIter unique(ForwardIter first, ForwardIter last);
  template<class ForwardIter, class BinaryPred>
    constexpr ForwardIter unique(ForwardIter first, ForwardIter last, BinaryPred pred);
  template<class ExecutionPolicy, class ForwardIter>
    ForwardIter unique(ExecutionPolicy&& exec,
                       ForwardIter first, ForwardIter last);
  template<class ExecutionPolicy, class ForwardIter, class BinaryPred>
    ForwardIter unique(ExecutionPolicy&& exec,
                       ForwardIter first, ForwardIter last, BinaryPred pred);
 
  namespace ranges {
    template<permutable I, sentinel_for<I> S, class Proj = identity,
             indirect_relation<projected<I, Proj>> C = ranges::equal_to>
      constexpr subrange<I> unique(I first, S last, C comp = {}, Proj proj = {});
    template<forward_range R, class Proj = identity,
             indirect_relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to>
      requires permutable<iterator_t<R>>
      constexpr borrowed_subrange_t<R>
        unique(R&& r, C comp = {}, Proj proj = {});
  }
 
  template<class InputIter, class OutputIter>
    constexpr OutputIter
      unique_copy(InputIter first, InputIter last, OutputIter result);
  template<class InputIter, class OutputIter, class BinaryPred>
    constexpr OutputIter
      unique_copy(InputIter first, InputIter last, OutputIter result, BinaryPred pred);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    ForwardIter2
      unique_copy(ExecutionPolicy&& exec,
                  ForwardIter1 first, ForwardIter1 last, ForwardIter2 result);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class BinaryPred>
    ForwardIter2
      unique_copy(ExecutionPolicy&& exec,
                  ForwardIter1 first, ForwardIter1 last,
                  ForwardIter2 result, BinaryPred pred);
 
  namespace ranges {
    template<class I, class O>
    using unique_copy_result = copy_result<I, O>;
 
    template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
             class Proj = identity,
             indirect_relation<projected<I, Proj>> C = ranges::equal_to>
      requires indirectly_copyable<I, O> &&
               (forward_iterator<I> ||
                (input_iterator<O> && same_as<iter_value_t<I>, iter_value_t<O>>) ||
                indirectly_copyable_storable<I, O>)
      constexpr unique_copy_result<I, O>
        unique_copy(I first, S last, O result, C comp = {}, Proj proj = {});
    template<input_range R, weakly_incrementable O, class Proj = identity,
             indirect_relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to>
      requires indirectly_copyable<iterator_t<R>, O> &&
               (forward_iterator<iterator_t<R>> ||
                (input_iterator<O> && same_as<range_value_t<R>, iter_value_t<O>>) ||
                indirectly_copyable_storable<iterator_t<R>, O>)
      constexpr unique_copy_result<borrowed_iterator_t<R>, O>
        unique_copy(R&& r, O result, C comp = {}, Proj proj = {});
  }
 
  // reverse
  template<class BidirectionalIter>
    constexpr void reverse(BidirectionalIter first, BidirectionalIter last);
  template<class ExecutionPolicy, class BidirectionalIter>
    void reverse(ExecutionPolicy&& exec,
                 BidirectionalIter first, BidirectionalIter last);
 
  namespace ranges {
    template<bidirectional_iterator I, sentinel_for<I> S>
      requires permutable<I>
      constexpr I reverse(I first, S last);
    template<bidirectional_range R>
      requires permutable<iterator_t<R>>
      constexpr borrowed_iterator_t<R> reverse(R&& r);
  }
 
  template<class BidirectionalIter, class OutputIter>
    constexpr OutputIter
      reverse_copy(BidirectionalIter first, BidirectionalIter last, OutputIter result);
  template<class ExecutionPolicy, class BidirectionalIter, class ForwardIter>
    ForwardIter
      reverse_copy(ExecutionPolicy&& exec,
                   BidirectionalIter first, BidirectionalIter last, ForwardIter result);
 
  namespace ranges {
    template<class I, class O>
    using reverse_copy_result = copy_result<I, O>;
 
    template<bidirectional_iterator I, sentinel_for<I> S, weakly_incrementable O>
      requires indirectly_copyable<I, O>
      constexpr reverse_copy_result<I, O>
        reverse_copy(I first, S last, O result);
    template<bidirectional_range R, weakly_incrementable O>
      requires indirectly_copyable<iterator_t<R>, O>
      constexpr reverse_copy_result<borrowed_iterator_t<R>, O>
        reverse_copy(R&& r, O result);
  }
 
  // rotate
  template<class ForwardIter>
    constexpr ForwardIter rotate(ForwardIter first, ForwardIter middle, ForwardIter last);
  template<class ExecutionPolicy, class ForwardIter>
    ForwardIter rotate(ExecutionPolicy&& exec,
                       ForwardIter first, ForwardIter middle, ForwardIter last);
 
  namespace ranges {
    template<permutable I, sentinel_for<I> S>
      constexpr subrange<I> rotate(I first, I middle, S last);
    template<forward_range R>
      requires permutable<iterator_t<R>>
      constexpr borrowed_subrange_t<R> rotate(R&& r, iterator_t<R> middle);
  }
 
  template<class ForwardIter, class OutputIter>
    constexpr OutputIter
      rotate_copy(ForwardIter first, ForwardIter middle,
                  ForwardIter last, OutputIter result);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    ForwardIter2
      rotate_copy(ExecutionPolicy&& exec,
                  ForwardIter1 first, ForwardIter1 middle,
                  ForwardIter1 last, ForwardIter2 result);
 
  namespace ranges {
    template<class I, class O>
    using rotate_copy_result = copy_result<I, O>;
 
    template<forward_iterator I, sentinel_for<I> S, weakly_incrementable O>
      requires indirectly_copyable<I, O>
      constexpr rotate_copy_result<I, O>
        rotate_copy(I first, I middle, S last, O result);
    template<forward_range R, weakly_incrementable O>
      requires indirectly_copyable<iterator_t<R>, O>
      constexpr rotate_copy_result<borrowed_iterator_t<R>, O>
        rotate_copy(R&& r, iterator_t<R> middle, O result);
  }
 
  // sample
  template<class PopulationIter, class SampleIter,
           class Distance, class UniformRandomBitGenerator>
    SampleIter sample(PopulationIter first, PopulationIter last,
                      SampleIter out, Distance n, UniformRandomBitGenerator&& g);
 
  // shuffle
  template<class RandomAccessIter, class UniformRandomBitGenerator>
    void shuffle(RandomAccessIter first, RandomAccessIter last,
                 UniformRandomBitGenerator&& g);
 
  namespace ranges {
    template<random_access_iterator I, sentinel_for<I> S, class Gen>
      requires permutable<I> &&
               uniform_random_bit_generator<remove_reference_t<Gen>>
      I shuffle(I first, S last, Gen&& g);
    template<random_access_range R, class Gen>
      requires permutable<iterator_t<R>> &&
               uniform_random_bit_generator<remove_reference_t<Gen>>
      borrowed_iterator_t<R> shuffle(R&& r, Gen&& g);
  }
 
  // shift
  template<class ForwardIter>
    constexpr ForwardIter
      shift_left(ForwardIter first, ForwardIter last,
                 typename iterator_traits<ForwardIter>::difference_type n);
  template<class ExecutionPolicy, class ForwardIter>
    ForwardIter
      shift_left(ExecutionPolicy&& exec,
                 ForwardIter first, ForwardIter last,
                 typename iterator_traits<ForwardIter>::difference_type n);
  template<class ForwardIter>
    constexpr ForwardIter
      shift_right(ForwardIter first, ForwardIter last,
                  typename iterator_traits<ForwardIter>::difference_type n);
  template<class ExecutionPolicy, class ForwardIter>
    ForwardIter
      shift_right(ExecutionPolicy&& exec,
                  ForwardIter first, ForwardIter last,
                  typename iterator_traits<ForwardIter>::difference_type n);
 
  // sorting and related operations
  // sorting
  template<class RandomAccessIter>
    constexpr void sort(RandomAccessIter first, RandomAccessIter last);
  template<class RandomAccessIter, class Cmp>
    constexpr void sort(RandomAccessIter first, RandomAccessIter last, Cmp comp);
  template<class ExecutionPolicy, class RandomAccessIter>
    void sort(ExecutionPolicy&& exec,
              RandomAccessIter first, RandomAccessIter last);
  template<class ExecutionPolicy, class RandomAccessIter, class Cmp>
    void sort(ExecutionPolicy&& exec,
              RandomAccessIter first, RandomAccessIter last, Cmp comp);
 
  namespace ranges {
    template<random_access_iterator I, sentinel_for<I> S, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<I, Cmp, Proj>
      constexpr I
        sort(I first, S last, Cmp comp = {}, Proj proj = {});
    template<random_access_range R, class Cmp = ranges::less, class Proj = identity>
      requires sortable<iterator_t<R>, Cmp, Proj>
      constexpr borrowed_iterator_t<R>
        sort(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class RandomAccessIter>
    void stable_sort(RandomAccessIter first, RandomAccessIter last);
  template<class RandomAccessIter, class Cmp>
    void stable_sort(RandomAccessIter first, RandomAccessIter last, Cmp comp);
  template<class ExecutionPolicy, class RandomAccessIter>
    void stable_sort(ExecutionPolicy&& exec,
                     RandomAccessIter first, RandomAccessIter last);
  template<class ExecutionPolicy, class RandomAccessIter, class Cmp>
    void stable_sort(ExecutionPolicy&& exec,
                     RandomAccessIter first, RandomAccessIter last, Cmp comp);
 
  namespace ranges {
    template<random_access_iterator I, sentinel_for<I> S, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<I, Cmp, Proj>
      I stable_sort(I first, S last, Cmp comp = {}, Proj proj = {});
    template<random_access_range R, class Cmp = ranges::less, class Proj = identity>
      requires sortable<iterator_t<R>, Cmp, Proj>
      borrowed_iterator_t<R>
        stable_sort(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class RandomAccessIter>
    constexpr void partial_sort(RandomAccessIter first,
                                RandomAccessIter middle,
                                RandomAccessIter last);
  template<class RandomAccessIter, class Cmp>
    constexpr void partial_sort(RandomAccessIter first,
                                RandomAccessIter middle,
                                RandomAccessIter last, Cmp comp);
  template<class ExecutionPolicy, class RandomAccessIter>
    void partial_sort(ExecutionPolicy&& exec,
                      RandomAccessIter first,
                      RandomAccessIter middle,
                      RandomAccessIter last);
  template<class ExecutionPolicy, class RandomAccessIter, class Cmp>
    void partial_sort(ExecutionPolicy&& exec,
                      RandomAccessIter first,
                      RandomAccessIter middle,
                      RandomAccessIter last, Cmp comp);
 
  namespace ranges {
    template<random_access_iterator I, sentinel_for<I> S, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<I, Cmp, Proj>
      constexpr I
        partial_sort(I first, I middle, S last, Cmp comp = {}, Proj proj = {});
    template<random_access_range R, class Cmp = ranges::less, class Proj = identity>
      requires sortable<iterator_t<R>, Cmp, Proj>
      constexpr borrowed_iterator_t<R>
        partial_sort(R&& r, iterator_t<R> middle, Cmp comp = {},
                     Proj proj = {});
  }
 
  template<class InputIter, class RandomAccessIter>
    constexpr RandomAccessIter
      partial_sort_copy(InputIter first, InputIter last,
                        RandomAccessIter result_first, RandomAccessIter result_last);
  template<class InputIter, class RandomAccessIter, class Cmp>
    constexpr RandomAccessIter
      partial_sort_copy(InputIter first, InputIter last,
                        RandomAccessIter result_first, RandomAccessIter result_last,
                        Cmp comp);
  template<class ExecutionPolicy, class ForwardIter, class RandomAccessIter>
    RandomAccessIter
      partial_sort_copy(ExecutionPolicy&& exec, 
                        ForwardIter first, ForwardIter last,
                        RandomAccessIter result_first, RandomAccessIter result_last);
  template<class ExecutionPolicy, class ForwardIter, class RandomAccessIter,
           class Cmp>
    RandomAccessIter
      partial_sort_copy(ExecutionPolicy&& exec, 
                        ForwardIter first, ForwardIter last,
                        RandomAccessIter result_first, RandomAccessIter result_last,
                        Cmp comp);
 
  namespace ranges {
    template<class I, class O> using partial_sort_copy_result = copy_result<I, O>;
 
    template<input_iterator I1, sentinel_for<I1> S1,
             random_access_iterator I2, sentinel_for<I2> S2,
             class Cmp = ranges::less, class Proj1 = identity, class Proj2 = identity>
      requires indirectly_copyable<I1, I2> && sortable<I2, Cmp, Proj2> &&
               indirect_strict_weak_order<Cmp, projected<I1, Proj1>, projected<I2, Proj2>>
      constexpr partial_sort_copy_result<I1, I2>
        partial_sort_copy(I1 first, S1 last, I2 result_first, S2 result_last,
                          Cmp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, random_access_range R2, class Cmp = ranges::less,
             class Proj1 = identity, class Proj2 = identity>
      requires indirectly_copyable<iterator_t<R1>, iterator_t<R2>> &&
               sortable<iterator_t<R2>, Cmp, Proj2> &&
               indirect_strict_weak_order<Cmp, projected<iterator_t<R1>, Proj1>,
                                          projected<iterator_t<R2>, Proj2>>
      constexpr partial_sort_copy_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
        partial_sort_copy(R1&& r, R2&& result_r, Cmp comp = {},
                          Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  template<class ForwardIter>
    constexpr bool is_sorted(ForwardIter first, ForwardIter last);
  template<class ForwardIter, class Cmp>
    constexpr bool is_sorted(ForwardIter first, ForwardIter last, Cmp comp);
  template<class ExecutionPolicy, class ForwardIter>
    bool is_sorted(ExecutionPolicy&& exec,
                   ForwardIter first, ForwardIter last);
  template<class ExecutionPolicy, class ForwardIter, class Cmp>
    bool is_sorted(ExecutionPolicy&& exec,
                   ForwardIter first, ForwardIter last, Cmp comp);
 
  namespace ranges {
    template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_strict_weak_order<projected<I, Proj>> Cmp = ranges::less>
      constexpr bool is_sorted(I first, S last, Cmp comp = {}, Proj proj = {});
    template<forward_range R, class Proj = identity,
             indirect_strict_weak_order< projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      constexpr bool is_sorted(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class ForwardIter>
    constexpr ForwardIter
      is_sorted_until(ForwardIter first, ForwardIter last);
  template<class ForwardIter, class Cmp>
    constexpr ForwardIter
      is_sorted_until(ForwardIter first, ForwardIter last, Cmp comp);
  template<class ExecutionPolicy, class ForwardIter>
    ForwardIter
      is_sorted_until(ExecutionPolicy&& exec,
                      ForwardIter first, ForwardIter last);
  template<class ExecutionPolicy, class ForwardIter, class Cmp>
    ForwardIter
      is_sorted_until(ExecutionPolicy&& exec,
                      ForwardIter first, ForwardIter last, Cmp comp);
 
  namespace ranges {
    template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_strict_weak_order<projected<I, Proj>> Cmp = ranges::less>
      constexpr I is_sorted_until(I first, S last, Cmp comp = {}, Proj proj = {});
    template<forward_range R, class Proj = identity,
             indirect_strict_weak_order<
               projected<iterator_t<R>, Proj>> Cmp = ranges::less>
      constexpr borrowed_iterator_t<R>
        is_sorted_until(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  // Nth element
  template<class RandomAccessIter>
    constexpr void nth_element(RandomAccessIter first, RandomAccessIter nth,
                               RandomAccessIter last);
  template<class RandomAccessIter, class Cmp>
    constexpr void nth_element(RandomAccessIter first, RandomAccessIter nth,
                               RandomAccessIter last, Cmp comp);
  template<class ExecutionPolicy, class RandomAccessIter>
    void nth_element(ExecutionPolicy&& exec,
                     RandomAccessIter first, RandomAccessIter nth,
                     RandomAccessIter last);
  template<class ExecutionPolicy, class RandomAccessIter, class Cmp>
    void nth_element(ExecutionPolicy&& exec,
                     RandomAccessIter first, RandomAccessIter nth,
                     RandomAccessIter last, Cmp comp);
 
  namespace ranges {
    template<random_access_iterator I, sentinel_for<I> S, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<I, Cmp, Proj>
      constexpr I
        nth_element(I first, I nth, S last, Cmp comp = {}, Proj proj = {});
    template<random_access_range R, class Cmp = ranges::less, class Proj = identity>
      requires sortable<iterator_t<R>, Cmp, Proj>
      constexpr borrowed_iterator_t<R>
        nth_element(R&& r, iterator_t<R> nth, Cmp comp = {}, Proj proj = {});
  }
 
  // binary search
  template<class ForwardIter, class T>
    constexpr ForwardIter
      lower_bound(ForwardIter first, ForwardIter last, const T& value);
  template<class ForwardIter, class T, class Cmp>
    constexpr ForwardIter
      lower_bound(ForwardIter first, ForwardIter last, const T& value, Cmp comp);
 
  namespace ranges {
    template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
             indirect_strict_weak_order<const T*, projected<I, Proj>> Cmp = ranges::less>
      constexpr I lower_bound(I first, S last, const T& value, Cmp comp = {},
                              Proj proj = {});
    template<forward_range R, class T, class Proj = identity,
             indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      constexpr borrowed_iterator_t<R>
        lower_bound(R&& r, const T& value, Cmp comp = {}, Proj proj = {});
  }
 
  template<class ForwardIter, class T>
    constexpr ForwardIter
      upper_bound(ForwardIter first, ForwardIter last, const T& value);
  template<class ForwardIter, class T, class Cmp>
    constexpr ForwardIter
      upper_bound(ForwardIter first, ForwardIter last, const T& value, Cmp comp);
 
  namespace ranges {
    template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
             indirect_strict_weak_order<const T*, projected<I, Proj>> Cmp = ranges::less>
      constexpr I upper_bound(I first, S last, const T& value, Cmp comp = {},
                              Proj proj = {});
    template<forward_range R, class T, class Proj = identity,
             indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      constexpr borrowed_iterator_t<R>
        upper_bound(R&& r, const T& value, Cmp comp = {}, Proj proj = {});
  }
 
  template<class ForwardIter, class T>
    constexpr pair<ForwardIter, ForwardIter>
      equal_range(ForwardIter first, ForwardIter last, const T& value);
  template<class ForwardIter, class T, class Cmp>
    constexpr pair<ForwardIter, ForwardIter>
      equal_range(ForwardIter first, ForwardIter last, const T& value, Cmp comp);
 
  namespace ranges {
    template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
             indirect_strict_weak_order<const T*, projected<I, Proj>> Cmp = ranges::less>
      constexpr subrange<I>
        equal_range(I first, S last, const T& value, Cmp comp = {}, Proj proj = {});
    template<forward_range R, class T, class Proj = identity,
             indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      constexpr borrowed_subrange_t<R>
        equal_range(R&& r, const T& value, Cmp comp = {}, Proj proj = {});
  }
 
  template<class ForwardIter, class T>
    constexpr bool
      binary_search(ForwardIter first, ForwardIter last, const T& value);
  template<class ForwardIter, class T, class Cmp>
    constexpr bool
      binary_search(ForwardIter first, ForwardIter last, const T& value, Cmp comp);
 
  namespace ranges {
    template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
             indirect_strict_weak_order<const T*, projected<I, Proj>> Cmp = ranges::less>
      constexpr bool binary_search(I first, S last, const T& value, Cmp comp = {},
                                   Proj proj = {});
    template<forward_range R, class T, class Proj = identity,
             indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      constexpr bool binary_search(R&& r, const T& value, Cmp comp = {},
                                   Proj proj = {});
  }
 
  // partitions
  template<class InputIter, class Pred>
    constexpr bool is_partitioned(InputIter first, InputIter last, Pred pred);
  template<class ExecutionPolicy, class ForwardIter, class Pred>
    bool is_partitioned(ExecutionPolicy&& exec,
                        ForwardIter first, ForwardIter last, Pred pred);
 
  namespace ranges {
    template<input_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      constexpr bool is_partitioned(I first, S last, Pred pred, Proj proj = {});
    template<input_range R, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      constexpr bool is_partitioned(R&& r, Pred pred, Proj proj = {});
  }
 
  template<class ForwardIter, class Pred>
    constexpr ForwardIter partition(ForwardIter first, ForwardIter last, Pred pred);
  template<class ExecutionPolicy, class ForwardIter, class Pred>
    ForwardIter partition(ExecutionPolicy&& exec,
                          ForwardIter first, ForwardIter last, Pred pred);
 
  namespace ranges {
    template<permutable I, sentinel_for<I> S, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      constexpr subrange<I>
        partition(I first, S last, Pred pred, Proj proj = {});
    template<forward_range R, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      requires permutable<iterator_t<R>>
      constexpr borrowed_subrange_t<R>
        partition(R&& r, Pred pred, Proj proj = {});
  }
 
  template<class BidirectionalIter, class Pred>
    BidirectionalIter stable_partition(BidirectionalIter first, BidirectionalIter last,
                                       Pred pred);
  template<class ExecutionPolicy, class BidirectionalIter, class Pred>
    BidirectionalIter stable_partition(ExecutionPolicy&& exec,
                                       BidirectionalIter first, BidirectionalIter last,
                                       Pred pred);
 
  namespace ranges {
    template<bidirectional_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      requires permutable<I>
      subrange<I> stable_partition(I first, S last, Pred pred, Proj proj = {});
    template<bidirectional_range R, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      requires permutable<iterator_t<R>>
      borrowed_subrange_t<R> stable_partition(R&& r, Pred pred, Proj proj = {});
  }
 
  template<class InputIter, class OutputIter1, class OutputIter2, class Pred>
    constexpr pair<OutputIter1, OutputIter2>
      partition_copy(InputIter first, InputIter last,
                     OutputIter1 out_true, OutputIter2 out_false, Pred pred);
  template<class ExecutionPolicy, class ForwardIter, class ForwardIter1,
           class ForwardIter2, class Pred>
    pair<ForwardIter1, ForwardIter2>
      partition_copy(ExecutionPolicy&& exec,
                     ForwardIter first, ForwardIter last,
                     ForwardIter1 out_true, ForwardIter2 out_false, Pred pred);
 
  namespace ranges {
    template<class I, class O1, class O2>
    struct partition_copy_result {
      [[no_unique_address]] I  in;
      [[no_unique_address]] O1 out1;
      [[no_unique_address]] O2 out2;
 
      template<class II, class OO1, class OO2>
        requires convertible_to<const I&, II> &&
          convertible_to<const O1&, OO1> && convertible_to<const O2&, OO2>
        operator partition_copy_result<II, OO1, OO2>() const & {
          return {in, out1, out2};
        }
 
      template<class II, class OO1, class OO2>
        requires convertible_to<I, II> &&
          convertible_to<O1, OO1> && convertible_to<O2, OO2>
        operator partition_copy_result<II, OO1, OO2>() && {
          return {std::move(in), std::move(out1), std::move(out2)};
        }
    };
 
    template<input_iterator I, sentinel_for<I> S,
             weakly_incrementable O1, weakly_incrementable O2,
             class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>
      requires indirectly_copyable<I, O1> && indirectly_copyable<I, O2>
      constexpr partition_copy_result<I, O1, O2>
        partition_copy(I first, S last, O1 out_true, O2 out_false, Pred pred,
                       Proj proj = {});
    template<input_range R, weakly_incrementable O1, weakly_incrementable O2,
             class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      requires indirectly_copyable<iterator_t<R>, O1> &&
               indirectly_copyable<iterator_t<R>, O2>
      constexpr partition_copy_result<borrowed_iterator_t<R>, O1, O2>
        partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {});
  }
 
  template<class ForwardIter, class Pred>
    constexpr ForwardIter
      partition_point(ForwardIter first, ForwardIter last, Pred pred);
 
  namespace ranges {
    template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_unary_predicate<projected<I, Proj>> Pred>
      constexpr I partition_point(I first, S last, Pred pred, Proj proj = {});
    template<forward_range R, class Proj = identity,
             indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
      constexpr borrowed_iterator_t<R>
        partition_point(R&& r, Pred pred, Proj proj = {});
  }
 
  // merge
  template<class InputIter1, class InputIter2, class OutputIter>
    constexpr OutputIter
      merge(InputIter1 first1, InputIter1 last1,
            InputIter2 first2, InputIter2 last2, OutputIter result);
  template<class InputIter1, class InputIter2, class OutputIter,
           class Cmp>
    constexpr OutputIter
      merge(InputIter1 first1, InputIter1 last1,
            InputIter2 first2, InputIter2 last2, OutputIter result, Cmp comp);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class ForwardIter>
    ForwardIter
      merge(ExecutionPolicy&& exec,
            ForwardIter1 first1, ForwardIter1 last1,
            ForwardIter2 first2, ForwardIter2 last2, ForwardIter result);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class ForwardIter, class Cmp>
    ForwardIter
      merge(ExecutionPolicy&& exec,
            ForwardIter1 first1, ForwardIter1 last1,
            ForwardIter2 first2, ForwardIter2 last2, ForwardIter result, Cmp comp);
 
  namespace ranges {
    template<class I1, class I2, class O>
    using merge_result = binary_transform_result<I1, I2, O>;
 
    template<input_iterator I1, sentinel_for<I1> S1,
             input_iterator I2, sentinel_for<I2> S2,
             weakly_incrementable O, class Cmp = ranges::less, class Proj1 = identity,
             class Proj2 = identity>
      requires mergeable<I1, I2, O, Cmp, Proj1, Proj2>
      constexpr merge_result<I1, I2, O>
        merge(I1 first1, S1 last1, I2 first2, S2 last2, O result,
              Cmp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, input_range R2, weakly_incrementable O,
             class Cmp = ranges::less, class Proj1 = identity, class Proj2 = identity>
      requires mergeable<iterator_t<R1>, iterator_t<R2>, O, Cmp, Proj1, Proj2>
      constexpr merge_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
        merge(R1&& r1, R2&& r2, O result,
              Cmp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  template<class BidirectionalIter>
    void inplace_merge(BidirectionalIter first,
                       BidirectionalIter middle,
                       BidirectionalIter last);
  template<class BidirectionalIter, class Cmp>
    void inplace_merge(BidirectionalIter first,
                       BidirectionalIter middle,
                       BidirectionalIter last, Cmp comp);
  template<class ExecutionPolicy, class BidirectionalIter>
    void inplace_merge(ExecutionPolicy&& exec,
                       BidirectionalIter first,
                       BidirectionalIter middle,
                       BidirectionalIter last);
  template<class ExecutionPolicy, class BidirectionalIter, class Cmp>
    void inplace_merge(ExecutionPolicy&& exec,
                       BidirectionalIter first,
                       BidirectionalIter middle,
                       BidirectionalIter last, Cmp comp);
 
  namespace ranges {
    template<bidirectional_iterator I, sentinel_for<I> S, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<I, Cmp, Proj>
      I inplace_merge(I first, I middle, S last, Cmp comp = {}, Proj proj = {});
    template<bidirectional_range R, class Cmp = ranges::less, class Proj = identity>
      requires sortable<iterator_t<R>, Cmp, Proj>
      borrowed_iterator_t<R>
        inplace_merge(R&& r, iterator_t<R> middle, Cmp comp = {},
                      Proj proj = {});
  }
 
  // set operations
  template<class InputIter1, class InputIter2>
    constexpr bool includes(InputIter1 first1, InputIter1 last1,
                            InputIter2 first2, InputIter2 last2);
  template<class InputIter1, class InputIter2, class Cmp>
    constexpr bool includes(InputIter1 first1, InputIter1 last1,
                            InputIter2 first2, InputIter2 last2, Cmp comp);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    bool includes(ExecutionPolicy&& exec,
                  ForwardIter1 first1, ForwardIter1 last1,
                  ForwardIter2 first2, ForwardIter2 last2);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class Cmp>
    bool includes(ExecutionPolicy&& exec,
                  ForwardIter1 first1, ForwardIter1 last1,
                  ForwardIter2 first2, ForwardIter2 last2, Cmp comp);
 
  namespace ranges {
    template<input_iterator I1, sentinel_for<I1> S1,
             input_iterator I2, sentinel_for<I2> S2,
             class Proj1 = identity, class Proj2 = identity,
             indirect_strict_weak_order<projected<I1, Proj1>, projected<I2, Proj2>> Cmp =
               ranges::less>
      constexpr bool includes(I1 first1, S1 last1, I2 first2, S2 last2, Cmp comp = {},
                              Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, input_range R2, class Proj1 = identity,
             class Proj2 = identity,
             indirect_strict_weak_order<
               projected<iterator_t<R1>, Proj1>,
               projected<iterator_t<R2>, Proj2>> Cmp = ranges::less>
      constexpr bool includes(R1&& r1, R2&& r2, Cmp comp = {},
                              Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  template<class InputIter1, class InputIter2, class OutputIter>
    constexpr OutputIter
      set_union(InputIter1 first1, InputIter1 last1,
                InputIter2 first2, InputIter2 last2, OutputIter result);
  template<class InputIter1, class InputIter2, class OutputIter, class Cmp>
    constexpr OutputIter
      set_union(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2,
                OutputIter result, Cmp comp);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class ForwardIter>
    ForwardIter
      set_union(ExecutionPolicy&& exec,
                ForwardIter1 first1, ForwardIter1 last1,
                ForwardIter2 first2, ForwardIter2 last2, ForwardIter result);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class ForwardIter, class Cmp>
    ForwardIter
      set_union(ExecutionPolicy&& exec,
                ForwardIter1 first1, ForwardIter1 last1,
                ForwardIter2 first2, ForwardIter2 last2,
                ForwardIter result, Cmp comp);
 
  namespace ranges {
    template<class I1, class I2, class O>
    using set_union_result = binary_transform_result<I1, I2, O>;
 
    template<input_iterator I1, sentinel_for<I1> S1,
             input_iterator I2, sentinel_for<I2> S2,
             weakly_incrementable O, class Cmp = ranges::less,
             class Proj1 = identity, class Proj2 = identity>
      requires mergeable<I1, I2, O, Cmp, Proj1, Proj2>
      constexpr set_union_result<I1, I2, O>
        set_union(I1 first1, S1 last1, I2 first2, S2 last2, O result, Cmp comp = {},
                  Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, input_range R2, weakly_incrementable O,
             class Cmp = ranges::less, class Proj1 = identity, class Proj2 = identity>
      requires mergeable<iterator_t<R1>, iterator_t<R2>, O, Cmp, Proj1, Proj2>
      constexpr set_union_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
        set_union(R1&& r1, R2&& r2, O result, Cmp comp = {},
                  Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  template<class InputIter1, class InputIter2, class OutputIter>
    constexpr OutputIter
      set_intersection(InputIter1 first1, InputIter1 last1,
                       InputIter2 first2, InputIter2 last2, OutputIter result);
  template<class InputIter1, class InputIter2, class OutputIter, class Cmp>
    constexpr OutputIter
      set_intersection(InputIter1 first1, InputIter1 last1,
                       InputIter2 first2, InputIter2 last2,
                       OutputIter result, Cmp comp);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class ForwardIter>
    ForwardIter
      set_intersection(ExecutionPolicy&& exec,
                       ForwardIter1 first1, ForwardIter1 last1,
                       ForwardIter2 first2, ForwardIter2 last2, ForwardIter result);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class ForwardIter, class Cmp>
    ForwardIter
      set_intersection(ExecutionPolicy&& exec,
                       ForwardIter1 first1, ForwardIter1 last1,
                       ForwardIter2 first2, ForwardIter2 last2,
                       ForwardIter result, Cmp comp);
 
  namespace ranges {
    template<class I1, class I2, class O>
    using set_intersection_result = binary_transform_result<I1, I2, O>;
 
    template<input_iterator I1, sentinel_for<I1> S1,
             input_iterator I2, sentinel_for<I2> S2,
             weakly_incrementable O, class Cmp = ranges::less,
             class Proj1 = identity, class Proj2 = identity>
      requires mergeable<I1, I2, O, Cmp, Proj1, Proj2>
      constexpr set_intersection_result<I1, I2, O>
        set_intersection(I1 first1, S1 last1, I2 first2, S2 last2, O result,
                         Cmp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, input_range R2, weakly_incrementable O,
             class Cmp = ranges::less, class Proj1 = identity, class Proj2 = identity>
      requires mergeable<iterator_t<R1>, iterator_t<R2>, O, Cmp, Proj1, Proj2>
      constexpr set_intersection_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
        set_intersection(R1&& r1, R2&& r2, O result,
                         Cmp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  template<class InputIter1, class InputIter2, class OutputIter>
    constexpr OutputIter
      set_difference(InputIter1 first1, InputIter1 last1,
                     InputIter2 first2, InputIter2 last2, OutputIter result);
  template<class InputIter1, class InputIter2, class OutputIter, class Cmp>
    constexpr OutputIter
      set_difference(InputIter1 first1, InputIter1 last1,
                     InputIter2 first2, InputIter2 last2,
                     OutputIter result, Cmp comp);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class ForwardIter>
    ForwardIter
      set_difference(ExecutionPolicy&& exec,
                     ForwardIter1 first1, ForwardIter1 last1,
                     ForwardIter2 first2, ForwardIter2 last2, ForwardIter result);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class ForwardIter, class Cmp>
    ForwardIter
      set_difference(ExecutionPolicy&& exec,
                     ForwardIter1 first1, ForwardIter1 last1,
                     ForwardIter2 first2, ForwardIter2 last2,
                     ForwardIter result, Cmp comp);
 
  namespace ranges {
    template<class I, class O>
    using set_difference_result = copy_result<I, O>;
 
    template<input_iterator I1, sentinel_for<I1> S1,
             input_iterator I2, sentinel_for<I2> S2,
             weakly_incrementable O, class Cmp = ranges::less,
             class Proj1 = identity, class Proj2 = identity>
      requires mergeable<I1, I2, O, Cmp, Proj1, Proj2>
      constexpr set_difference_result<I1, O>
        set_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result,
                       Cmp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, input_range R2, weakly_incrementable O,
             class Cmp = ranges::less, class Proj1 = identity, class Proj2 = identity>
      requires mergeable<iterator_t<R1>, iterator_t<R2>, O, Cmp, Proj1, Proj2>
      constexpr set_difference_result<borrowed_iterator_t<R1>, O>
        set_difference(R1&& r1, R2&& r2, O result,
                       Cmp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  template<class InputIter1, class InputIter2, class OutputIter>
    constexpr OutputIter
      set_symmetric_difference(InputIter1 first1, InputIter1 last1,
                               InputIter2 first2, InputIter2 last2, OutputIter result);
  template<class InputIter1, class InputIter2, class OutputIter, class Cmp>
    constexpr OutputIter
      set_symmetric_difference(InputIter1 first1, InputIter1 last1,
                               InputIter2 first2, InputIter2 last2,
                               OutputIter result, Cmp comp);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class ForwardIter>
    ForwardIter
      set_symmetric_difference(ExecutionPolicy&& exec,
                               ForwardIter1 first1, ForwardIter1 last1,
                               ForwardIter2 first2, ForwardIter2 last2,
                               ForwardIter result);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2,
           class ForwardIter, class Cmp>
    ForwardIter
      set_symmetric_difference(ExecutionPolicy&& exec,
                               ForwardIter1 first1, ForwardIter1 last1,
                               ForwardIter2 first2, ForwardIter2 last2,
                               ForwardIter result, Cmp comp);
 
  namespace ranges {
    template<class I1, class I2, class O>
    using set_symmetric_difference_result = binary_transform_result<I1, I2, O>;
 
    template<input_iterator I1, sentinel_for<I1> S1,
             input_iterator I2, sentinel_for<I2> S2,
             weakly_incrementable O, class Cmp = ranges::less,
             class Proj1 = identity, class Proj2 = identity>
      requires mergeable<I1, I2, O, Cmp, Proj1, Proj2>
      constexpr set_symmetric_difference_result<I1, I2, O>
        set_symmetric_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result,
                                 Cmp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, input_range R2, weakly_incrementable O,
             class Cmp = ranges::less, class Proj1 = identity, class Proj2 = identity>
      requires mergeable<iterator_t<R1>, iterator_t<R2>, O, Cmp, Proj1, Proj2>
      constexpr
        set_symmetric_difference_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
        set_symmetric_difference(R1&& r1, R2&& r2, O result, Cmp comp = {},
                                 Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  // heap operations
  template<class RandomAccessIter>
    constexpr void push_heap(RandomAccessIter first, RandomAccessIter last);
  template<class RandomAccessIter, class Cmp>
    constexpr void push_heap(RandomAccessIter first, RandomAccessIter last, Cmp comp);
 
  namespace ranges {
    template<random_access_iterator I, sentinel_for<I> S, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<I, Cmp, Proj>
      constexpr I
        push_heap(I first, S last, Cmp comp = {}, Proj proj = {});
    template<random_access_range R, class Cmp = ranges::less, class Proj = identity>
      requires sortable<iterator_t<R>, Cmp, Proj>
      constexpr borrowed_iterator_t<R>
        push_heap(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class RandomAccessIter>
    constexpr void pop_heap(RandomAccessIter first, RandomAccessIter last);
  template<class RandomAccessIter, class Cmp>
    constexpr void pop_heap(RandomAccessIter first, RandomAccessIter last, Cmp comp);
 
  namespace ranges {
    template<random_access_iterator I, sentinel_for<I> S, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<I, Cmp, Proj>
      constexpr I
        pop_heap(I first, S last, Cmp comp = {}, Proj proj = {});
    template<random_access_range R, class Cmp = ranges::less, class Proj = identity>
      requires sortable<iterator_t<R>, Cmp, Proj>
      constexpr borrowed_iterator_t<R>
        pop_heap(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class RandomAccessIter>
    constexpr void make_heap(RandomAccessIter first, RandomAccessIter last);
  template<class RandomAccessIter, class Cmp>
    constexpr void make_heap(RandomAccessIter first, RandomAccessIter last, Cmp comp);
 
  namespace ranges {
    template<random_access_iterator I, sentinel_for<I> S, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<I, Cmp, Proj>
      constexpr I
        make_heap(I first, S last, Cmp comp = {}, Proj proj = {});
    template<random_access_range R, class Cmp = ranges::less, class Proj = identity>
      requires sortable<iterator_t<R>, Cmp, Proj>
      constexpr borrowed_iterator_t<R>
        make_heap(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class RandomAccessIter>
    constexpr void sort_heap(RandomAccessIter first, RandomAccessIter last);
  template<class RandomAccessIter, class Cmp>
    constexpr void sort_heap(RandomAccessIter first, RandomAccessIter last, Cmp comp);
 
  namespace ranges {
    template<random_access_iterator I, sentinel_for<I> S, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<I, Cmp, Proj>
      constexpr I
        sort_heap(I first, S last, Cmp comp = {}, Proj proj = {});
    template<random_access_range R, class Cmp = ranges::less, class Proj = identity>
      requires sortable<iterator_t<R>, Cmp, Proj>
      constexpr borrowed_iterator_t<R>
        sort_heap(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class RandomAccessIter>
    constexpr bool is_heap(RandomAccessIter first, RandomAccessIter last);
  template<class RandomAccessIter, class Cmp>
    constexpr bool is_heap(RandomAccessIter first, RandomAccessIter last, Cmp comp);
  template<class ExecutionPolicy, class RandomAccessIter>
    bool is_heap(ExecutionPolicy&& exec,
                 RandomAccessIter first, RandomAccessIter last);
  template<class ExecutionPolicy, class RandomAccessIter, class Cmp>
    bool is_heap(ExecutionPolicy&& exec,
                 RandomAccessIter first, RandomAccessIter last, Cmp comp);
 
  namespace ranges {
    template<random_access_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_strict_weak_order<projected<I, Proj>> Cmp = ranges::less>
      constexpr bool is_heap(I first, S last, Cmp comp = {}, Proj proj = {});
    template<random_access_range R, class Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      constexpr bool is_heap(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class RandomAccessIter>
    constexpr RandomAccessIter
      is_heap_until(RandomAccessIter first, RandomAccessIter last);
  template<class RandomAccessIter, class Cmp>
    constexpr RandomAccessIter
      is_heap_until(RandomAccessIter first, RandomAccessIter last, Cmp comp);
  template<class ExecutionPolicy, class RandomAccessIter>
    RandomAccessIter
      is_heap_until(ExecutionPolicy&& exec,
                    RandomAccessIter first, RandomAccessIter last);
  template<class ExecutionPolicy, class RandomAccessIter, class Cmp>
    RandomAccessIter
      is_heap_until(ExecutionPolicy&& exec,
                    RandomAccessIter first, RandomAccessIter last, Cmp comp);
 
  namespace ranges {
    template<random_access_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_strict_weak_order<projected<I, Proj>> Cmp = ranges::less>
      constexpr I is_heap_until(I first, S last, Cmp comp = {}, Proj proj = {});
    template<random_access_range R, class Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      constexpr borrowed_iterator_t<R>
        is_heap_until(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  // minimum and maximum
  template<class T> constexpr const T& min(const T& a, const T& b);
  template<class T, class Cmp>
    constexpr const T& min(const T& a, const T& b, Cmp comp);
  template<class T>
    constexpr T min(initializer_list<T> t);
  template<class T, class Cmp>
    constexpr T min(initializer_list<T> t, Cmp comp);
 
  namespace ranges {
    template<class T, class Proj = identity,
             indirect_strict_weak_order<projected<const T*, Proj>> Cmp = ranges::less>
      constexpr const T& min(const T& a, const T& b, Cmp comp = {}, Proj proj = {});
    template<copyable T, class Proj = identity,
             indirect_strict_weak_order<projected<const T*, Proj>> Cmp = ranges::less>
      constexpr T min(initializer_list<T> r, Cmp comp = {}, Proj proj = {});
    template<input_range R, class Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
      constexpr range_value_t<R>
        min(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class T> constexpr const T& max(const T& a, const T& b);
  template<class T, class Cmp>
    constexpr const T& max(const T& a, const T& b, Cmp comp);
  template<class T>
    constexpr T max(initializer_list<T> t);
  template<class T, class Cmp>
    constexpr T max(initializer_list<T> t, Cmp comp);
 
  namespace ranges {
    template<class T, class Proj = identity,
             indirect_strict_weak_order<projected<const T*, Proj>> Cmp = ranges::less>
      constexpr const T& max(const T& a, const T& b, Cmp comp = {}, Proj proj = {});
    template<copyable T, class Proj = identity,
             indirect_strict_weak_order<projected<const T*, Proj>> Cmp = ranges::less>
      constexpr T max(initializer_list<T> r, Cmp comp = {}, Proj proj = {});
    template<input_range R, class Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
      constexpr range_value_t<R>
        max(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class T> constexpr pair<const T&, const T&> minmax(const T& a, const T& b);
  template<class T, class Cmp>
    constexpr pair<const T&, const T&> minmax(const T& a, const T& b, Cmp comp);
  template<class T>
    constexpr pair<T, T> minmax(initializer_list<T> t);
  template<class T, class Cmp>
    constexpr pair<T, T> minmax(initializer_list<T> t, Cmp comp);
 
  namespace ranges {
    template<class T>
    struct minmax_result {
      [[no_unique_address]] T min;
      [[no_unique_address]] T max;
 
      template<class T2>
        requires convertible_to<const T&, T2>
        operator minmax_result<T2>() const & {
          return {min, max};
        }
 
      template<class T2>
        requires convertible_to<T, T2>
        operator minmax_result<T2>() && {
          return {std::move(min), std::move(max)};
        }
    };
 
    template<class T, class Proj = identity,
             indirect_strict_weak_order<projected<const T*, Proj>> Cmp = ranges::less>
      constexpr minmax_result<const T&>
        minmax(const T& a, const T& b, Cmp comp = {}, Proj proj = {});
    template<copyable T, class Proj = identity,
             indirect_strict_weak_order<projected<const T*, Proj>> Cmp = ranges::less>
      constexpr minmax_result<T>
        minmax(initializer_list<T> r, Cmp comp = {}, Proj proj = {});
    template<input_range R, class Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
      constexpr minmax_result<range_value_t<R>>
        minmax(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class ForwardIter>
    constexpr ForwardIter min_element(ForwardIter first, ForwardIter last);
  template<class ForwardIter, class Cmp>
    constexpr ForwardIter min_element(ForwardIter first, ForwardIter last, Cmp comp);
  template<class ExecutionPolicy, class ForwardIter>
    ForwardIter min_element(ExecutionPolicy&& exec,
                            ForwardIter first, ForwardIter last);
  template<class ExecutionPolicy, class ForwardIter, class Cmp>
    ForwardIter min_element(ExecutionPolicy&& exec,
                            ForwardIter first, ForwardIter last, Cmp comp);
 
  namespace ranges {
    template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_strict_weak_order<projected<I, Proj>> Cmp = ranges::less>
      constexpr I min_element(I first, S last, Cmp comp = {}, Proj proj = {});
    template<forward_range R, class Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      constexpr borrowed_iterator_t<R>
        min_element(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class ForwardIter>
    constexpr ForwardIter max_element(ForwardIter first, ForwardIter last);
  template<class ForwardIter, class Cmp>
    constexpr ForwardIter max_element(ForwardIter first, ForwardIter last, Cmp comp);
  template<class ExecutionPolicy, class ForwardIter>
    ForwardIter max_element(ExecutionPolicy&& exec,
                            ForwardIter first, ForwardIter last);
  template<class ExecutionPolicy, class ForwardIter, class Cmp>
    ForwardIter max_element(ExecutionPolicy&& exec,
                            ForwardIter first, ForwardIter last, Cmp comp);
 
 namespace ranges {
    template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_strict_weak_order<projected<I, Proj>> Cmp = ranges::less>
      constexpr I max_element(I first, S last, Cmp comp = {}, Proj proj = {});
    template<forward_range R, class Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      constexpr borrowed_iterator_t<R>
        max_element(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class ForwardIter>
    constexpr pair<ForwardIter, ForwardIter>
      minmax_element(ForwardIter first, ForwardIter last);
  template<class ForwardIter, class Cmp>
    constexpr pair<ForwardIter, ForwardIter>
      minmax_element(ForwardIter first, ForwardIter last, Cmp comp);
  template<class ExecutionPolicy, class ForwardIter>
    pair<ForwardIter, ForwardIter>
      minmax_element(ExecutionPolicy&& exec,
                     ForwardIter first, ForwardIter last);
  template<class ExecutionPolicy, class ForwardIter, class Cmp>
    pair<ForwardIter, ForwardIter>
      minmax_element(ExecutionPolicy&& exec,
                     ForwardIter first, ForwardIter last, Cmp comp);
 
  namespace ranges {
    template<class I>
    using minmax_element_result = minmax_result<I>;
 
    template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
             indirect_strict_weak_order<projected<I, Proj>> Cmp = ranges::less>
      constexpr minmax_element_result<I>
        minmax_element(I first, S last, Cmp comp = {}, Proj proj = {});
    template<forward_range R, class Proj = identity,
             indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Cmp =
               ranges::less>
      constexpr minmax_element_result<borrowed_iterator_t<R>>
        minmax_element(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  // bounded value
  template<class T>
    constexpr const T& clamp(const T& v, const T& lo, const T& hi);
  template<class T, class Cmp>
    constexpr const T& clamp(const T& v, const T& lo, const T& hi, Cmp comp);
 
  // lexicographical comparison
  template<class InputIter1, class InputIter2>
    constexpr bool
      lexicographical_compare(InputIter1 first1, InputIter1 last1,
                              InputIter2 first2, InputIter2 last2);
  template<class InputIter1, class InputIter2, class Cmp>
    constexpr bool
      lexicographical_compare(InputIter1 first1, InputIter1 last1,
                              InputIter2 first2, InputIter2 last2,
                              Cmp comp);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2>
    bool
      lexicographical_compare(ExecutionPolicy&& exec,
                              ForwardIter1 first1, ForwardIter1 last1,
                              ForwardIter2 first2, ForwardIter2 last2);
  template<class ExecutionPolicy, class ForwardIter1, class ForwardIter2, class Cmp>
    bool
      lexicographical_compare(ExecutionPolicy&& exec,
                              ForwardIter1 first1, ForwardIter1 last1,
                              ForwardIter2 first2, ForwardIter2 last2,
                              Cmp comp);
 
  namespace ranges {
    template<input_iterator I1, sentinel_for<I1> S1,
             input_iterator I2, sentinel_for<I2> S2,
             class Proj1 = identity, class Proj2 = identity,
             indirect_strict_weak_order<projected<I1, Proj1>, projected<I2, Proj2>> Cmp =
               ranges::less>
      constexpr bool
        lexicographical_compare(I1 first1, S1 last1, I2 first2, S2 last2,
                                Cmp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
    template<input_range R1, input_range R2, class Proj1 = identity,
             class Proj2 = identity,
             indirect_strict_weak_order<
               projected<iterator_t<R1>, Proj1>,
               projected<iterator_t<R2>, Proj2>> Cmp = ranges::less>
      constexpr bool
        lexicographical_compare(R1&& r1, R2&& r2, Cmp comp = {},
                                Proj1 proj1 = {}, Proj2 proj2 = {});
  }
 
  // three-way comparison algorithms
  template<class InputIter1, class InputIter2, class Cmp>
    constexpr auto
      lexicographical_compare_three_way(InputIter1 b1, InputIter1 e1,
                                        InputIter2 b2, InputIter2 e2, Cmp comp)
        -> common_comparison_category_t<decltype(comp(*b1, *b2)), strong_ordering>;
  template<class InputIter1, class InputIter2>
    constexpr auto
      lexicographical_compare_three_way(InputIter1 b1, InputIter1 e1,
                                        InputIter2 b2, InputIter2 e2);
 
  // permutations
  template<class BidirectionalIter>
    constexpr bool next_permutation(BidirectionalIter first, BidirectionalIter last);
  template<class BidirectionalIter, class Cmp>
    constexpr bool next_permutation(BidirectionalIter first, BidirectionalIter last,
                                    Cmp comp);
 
  namespace ranges {
    template<class I>
    struct next_permutation_result {
      bool found;
      I in;
    };
 
    template<bidirectional_iterator I, sentinel_for<I> S, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<I, Cmp, Proj>
      constexpr next_permutation_result<I>
        next_permutation(I first, S last, Cmp comp = {}, Proj proj = {});
    template<bidirectional_range R, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<iterator_t<R>, Cmp, Proj>
      constexpr next_permutation_result<borrowed_iterator_t<R>>
        next_permutation(R&& r, Cmp comp = {}, Proj proj = {});
  }
 
  template<class BidirectionalIter>
    constexpr bool prev_permutation(BidirectionalIter first,
                                    BidirectionalIter last);
  template<class BidirectionalIter, class Cmp>
    constexpr bool prev_permutation(BidirectionalIter first,
                                    BidirectionalIter last, Cmp comp);
 
  namespace ranges {
    template<class I>
    using prev_permutation_result = next_permutation_result<I>;
 
    template<bidirectional_iterator I, sentinel_for<I> S, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<I, Cmp, Proj>
      constexpr prev_permutation_result<I>
        prev_permutation(I first, S last, Cmp comp = {}, Proj proj = {});
    template<bidirectional_range R, class Cmp = ranges::less,
             class Proj = identity>
      requires sortable<iterator_t<R>, Cmp, Proj>
      constexpr prev_permutation_result<borrowed_iterator_t<R>>
        prev_permutation(R&& r, Cmp comp = {}, Proj proj = {});
  }
}