13e519524SHoward Hinnant// -*- C++ -*-
2050b064fSChristopher Di Bella//===----------------------------------------------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP_FUNCTIONAL
113e519524SHoward Hinnant#define _LIBCPP_FUNCTIONAL
123e519524SHoward Hinnant
133e519524SHoward Hinnant/*
143e519524SHoward Hinnant    functional synopsis
153e519524SHoward Hinnant
163e519524SHoward Hinnantnamespace std
173e519524SHoward Hinnant{
183e519524SHoward Hinnant
193e519524SHoward Hinnanttemplate <class Arg, class Result>
203e519524SHoward Hinnantstruct unary_function
213e519524SHoward Hinnant{
223e519524SHoward Hinnant    typedef Arg    argument_type;
233e519524SHoward Hinnant    typedef Result result_type;
243e519524SHoward Hinnant};
253e519524SHoward Hinnant
263e519524SHoward Hinnanttemplate <class Arg1, class Arg2, class Result>
273e519524SHoward Hinnantstruct binary_function
283e519524SHoward Hinnant{
293e519524SHoward Hinnant    typedef Arg1   first_argument_type;
303e519524SHoward Hinnant    typedef Arg2   second_argument_type;
313e519524SHoward Hinnant    typedef Result result_type;
323e519524SHoward Hinnant};
333e519524SHoward Hinnant
349b0b6d45SHoward Hinnanttemplate <class T>
353e519524SHoward Hinnantclass reference_wrapper
363e519524SHoward Hinnant    : public unary_function<T1, R> // if wrapping a unary functor
373e519524SHoward Hinnant    : public binary_function<T1, T2, R> // if wraping a binary functor
383e519524SHoward Hinnant{
393e519524SHoward Hinnantpublic:
403e519524SHoward Hinnant    // types
413e519524SHoward Hinnant    typedef T type;
423e519524SHoward Hinnant    typedef see below result_type; // Not always defined
433e519524SHoward Hinnant
443e519524SHoward Hinnant    // construct/copy/destroy
45eec04092SArthur O'Dwyer    template<class U>
46eec04092SArthur O'Dwyer      reference_wrapper(U&&);
476a07d6f0SHoward Hinnant    reference_wrapper(const reference_wrapper<T>& x) noexcept;
483e519524SHoward Hinnant
493e519524SHoward Hinnant    // assignment
506a07d6f0SHoward Hinnant    reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept;
513e519524SHoward Hinnant
523e519524SHoward Hinnant    // access
536a07d6f0SHoward Hinnant    operator T& () const noexcept;
546a07d6f0SHoward Hinnant    T& get() const noexcept;
553e519524SHoward Hinnant
563e519524SHoward Hinnant    // invoke
573e519524SHoward Hinnant    template <class... ArgTypes>
58b76e6a95SHoward Hinnant      typename result_of<T&(ArgTypes&&...)>::type
593e519524SHoward Hinnant          operator() (ArgTypes&&...) const;
603e519524SHoward Hinnant};
613e519524SHoward Hinnant
62eec04092SArthur O'Dwyertemplate <class T>
63eec04092SArthur O'Dwyer  reference_wrapper(T&) -> reference_wrapper<T>;
64eec04092SArthur O'Dwyer
656a07d6f0SHoward Hinnanttemplate <class T> reference_wrapper<T> ref(T& t) noexcept;
669b0b6d45SHoward Hinnanttemplate <class T> void ref(const T&& t) = delete;
676a07d6f0SHoward Hinnanttemplate <class T> reference_wrapper<T> ref(reference_wrapper<T>t) noexcept;
683e519524SHoward Hinnant
696a07d6f0SHoward Hinnanttemplate <class T> reference_wrapper<const T> cref(const T& t) noexcept;
709b0b6d45SHoward Hinnanttemplate <class T> void cref(const T&& t) = delete;
716a07d6f0SHoward Hinnanttemplate <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
723e519524SHoward Hinnant
73bb9ca6d0SLouis Dionnetemplate <class T> struct unwrap_reference;                                       // since C++20
74bb9ca6d0SLouis Dionnetemplate <class T> struct unwrap_ref_decay : unwrap_reference<decay_t<T>> { };    // since C++20
75bb9ca6d0SLouis Dionnetemplate <class T> using unwrap_reference_t = typename unwrap_reference<T>::type; // since C++20
76bb9ca6d0SLouis Dionnetemplate <class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; // since C++20
77bb9ca6d0SLouis Dionne
7883c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
79dc066888SArthur O'Dwyerstruct plus {
803e519524SHoward Hinnant    T operator()(const T& x, const T& y) const;
813e519524SHoward Hinnant};
823e519524SHoward Hinnant
8383c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
84dc066888SArthur O'Dwyerstruct minus {
853e519524SHoward Hinnant    T operator()(const T& x, const T& y) const;
863e519524SHoward Hinnant};
873e519524SHoward Hinnant
8883c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
89dc066888SArthur O'Dwyerstruct multiplies {
903e519524SHoward Hinnant    T operator()(const T& x, const T& y) const;
913e519524SHoward Hinnant};
923e519524SHoward Hinnant
9383c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
94dc066888SArthur O'Dwyerstruct divides {
953e519524SHoward Hinnant    T operator()(const T& x, const T& y) const;
963e519524SHoward Hinnant};
973e519524SHoward Hinnant
9883c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
99dc066888SArthur O'Dwyerstruct modulus {
1003e519524SHoward Hinnant    T operator()(const T& x, const T& y) const;
1013e519524SHoward Hinnant};
1023e519524SHoward Hinnant
10383c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
104dc066888SArthur O'Dwyerstruct negate {
1053e519524SHoward Hinnant    T operator()(const T& x) const;
1063e519524SHoward Hinnant};
1073e519524SHoward Hinnant
10883c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
109dc066888SArthur O'Dwyerstruct equal_to {
1103e519524SHoward Hinnant    bool operator()(const T& x, const T& y) const;
1113e519524SHoward Hinnant};
1123e519524SHoward Hinnant
11383c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
114dc066888SArthur O'Dwyerstruct not_equal_to {
1153e519524SHoward Hinnant    bool operator()(const T& x, const T& y) const;
1163e519524SHoward Hinnant};
1173e519524SHoward Hinnant
11883c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
119dc066888SArthur O'Dwyerstruct greater {
1203e519524SHoward Hinnant    bool operator()(const T& x, const T& y) const;
1213e519524SHoward Hinnant};
1223e519524SHoward Hinnant
12383c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
124dc066888SArthur O'Dwyerstruct less {
1253e519524SHoward Hinnant    bool operator()(const T& x, const T& y) const;
1263e519524SHoward Hinnant};
1273e519524SHoward Hinnant
12883c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
129dc066888SArthur O'Dwyerstruct greater_equal {
1303e519524SHoward Hinnant    bool operator()(const T& x, const T& y) const;
1313e519524SHoward Hinnant};
1323e519524SHoward Hinnant
13383c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
134dc066888SArthur O'Dwyerstruct less_equal {
1353e519524SHoward Hinnant    bool operator()(const T& x, const T& y) const;
1363e519524SHoward Hinnant};
1373e519524SHoward Hinnant
1383df094d3SArthur O'Dwyer// [comparisons.three.way], class compare_three_way
1393df094d3SArthur O'Dwyerstruct compare_three_way;
1403df094d3SArthur O'Dwyer
14183c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
142dc066888SArthur O'Dwyerstruct logical_and {
1433e519524SHoward Hinnant    bool operator()(const T& x, const T& y) const;
1443e519524SHoward Hinnant};
1453e519524SHoward Hinnant
14683c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
147dc066888SArthur O'Dwyerstruct logical_or {
1483e519524SHoward Hinnant    bool operator()(const T& x, const T& y) const;
1493e519524SHoward Hinnant};
1503e519524SHoward Hinnant
15183c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
152dc066888SArthur O'Dwyerstruct logical_not {
1533e519524SHoward Hinnant    bool operator()(const T& x) const;
1543e519524SHoward Hinnant};
1553e519524SHoward Hinnant
15683c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
157dc066888SArthur O'Dwyerstruct bit_and {
158ab49f50aSArthur O'Dwyer    T operator()(const T& x, const T& y) const;
15983c08b44SMarshall Clow};
16083c08b44SMarshall Clow
16183c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
162dc066888SArthur O'Dwyerstruct bit_or {
163ab49f50aSArthur O'Dwyer    T operator()(const T& x, const T& y) const;
16483c08b44SMarshall Clow};
16583c08b44SMarshall Clow
16683c08b44SMarshall Clowtemplate <class T> // <class T=void> in C++14
167dc066888SArthur O'Dwyerstruct bit_xor {
168ab49f50aSArthur O'Dwyer    T operator()(const T& x, const T& y) const;
16983c08b44SMarshall Clow};
17083c08b44SMarshall Clow
17183c08b44SMarshall Clowtemplate <class T=void> // C++14
172dc066888SArthur O'Dwyerstruct bit_not {
173ab49f50aSArthur O'Dwyer    T operator()(const T& x) const;
17483c08b44SMarshall Clow};
17583c08b44SMarshall Clow
17624c44c37SChristopher Di Bellastruct identity; // C++20
17724c44c37SChristopher Di Bella
1783e519524SHoward Hinnanttemplate <class Predicate>
179d42d9e10SArthur O'Dwyerclass unary_negate // deprecated in C++17, removed in C++20
1803e519524SHoward Hinnant    : public unary_function<typename Predicate::argument_type, bool>
1813e519524SHoward Hinnant{
1823e519524SHoward Hinnantpublic:
1833e519524SHoward Hinnant    explicit unary_negate(const Predicate& pred);
1843e519524SHoward Hinnant    bool operator()(const typename Predicate::argument_type& x) const;
1853e519524SHoward Hinnant};
1863e519524SHoward Hinnant
187d42d9e10SArthur O'Dwyertemplate <class Predicate> // deprecated in C++17, removed in C++20
188ea5cd3b4SLouis Dionneunary_negate<Predicate> not1(const Predicate& pred);
1893e519524SHoward Hinnant
1903e519524SHoward Hinnanttemplate <class Predicate>
191d42d9e10SArthur O'Dwyerclass binary_negate // deprecated in C++17, removed in C++20
1923e519524SHoward Hinnant    : public binary_function<typename Predicate::first_argument_type,
1933e519524SHoward Hinnant                             typename Predicate::second_argument_type,
1943e519524SHoward Hinnant                             bool>
1953e519524SHoward Hinnant{
1963e519524SHoward Hinnantpublic:
1973e519524SHoward Hinnant    explicit binary_negate(const Predicate& pred);
1983e519524SHoward Hinnant    bool operator()(const typename Predicate::first_argument_type& x,
1993e519524SHoward Hinnant                    const typename Predicate::second_argument_type& y) const;
2003e519524SHoward Hinnant};
2013e519524SHoward Hinnant
202d42d9e10SArthur O'Dwyertemplate <class Predicate> // deprecated in C++17, removed in C++20
203ea5cd3b4SLouis Dionnebinary_negate<Predicate> not2(const Predicate& pred);
2043e519524SHoward Hinnant
2057b00e9faSArthur O'Dwyertemplate <class F>
2067b00e9faSArthur O'Dwyerconstexpr unspecified not_fn(F&& f); // C++17, constexpr in C++20
20757257567SEric Fiselier
2083e519524SHoward Hinnanttemplate<class T> struct is_bind_expression;
2093e519524SHoward Hinnanttemplate<class T> struct is_placeholder;
2103e519524SHoward Hinnant
211a48055ceSMarshall Clow    // See C++14 20.9.9, Function object binders
21240a01d53SMarshall Clowtemplate <class T> inline constexpr bool is_bind_expression_v
213a48055ceSMarshall Clow  = is_bind_expression<T>::value; // C++17
21440a01d53SMarshall Clowtemplate <class T> inline constexpr int is_placeholder_v
215a48055ceSMarshall Clow  = is_placeholder<T>::value; // C++17
216a48055ceSMarshall Clow
217a48055ceSMarshall Clow
2189b0b6d45SHoward Hinnanttemplate<class Fn, class... BoundArgs>
2197b00e9faSArthur O'Dwyer  constexpr unspecified bind(Fn&&, BoundArgs&&...);  // constexpr in C++20
2209b0b6d45SHoward Hinnanttemplate<class R, class Fn, class... BoundArgs>
2217b00e9faSArthur O'Dwyer  constexpr unspecified bind(Fn&&, BoundArgs&&...);  // constexpr in C++20
2223e519524SHoward Hinnant
2236c49e1ceSLouis Dionnetemplate<class F, class... Args>
2247b00e9faSArthur O'Dwyer constexpr // constexpr in C++20
2256c49e1ceSLouis Dionne invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) // C++17
2266c49e1ceSLouis Dionne    noexcept(is_nothrow_invocable_v<F, Args...>);
2276c49e1ceSLouis Dionne
2283e519524SHoward Hinnantnamespace placeholders {
2293e519524SHoward Hinnant  // M is the implementation-defined number of placeholders
2303e519524SHoward Hinnant  extern unspecified _1;
2313e519524SHoward Hinnant  extern unspecified _2;
2323e519524SHoward Hinnant  .
2333e519524SHoward Hinnant  .
2343e519524SHoward Hinnant  .
235c003db1fSHoward Hinnant  extern unspecified _Mp;
2363e519524SHoward Hinnant}
2373e519524SHoward Hinnant
2383e519524SHoward Hinnanttemplate <class Operation>
2397d210c78SMarshall Clowclass binder1st     // deprecated in C++11, removed in C++17
2403e519524SHoward Hinnant    : public unary_function<typename Operation::second_argument_type,
2413e519524SHoward Hinnant                            typename Operation::result_type>
2423e519524SHoward Hinnant{
2433e519524SHoward Hinnantprotected:
2443e519524SHoward Hinnant    Operation                               op;
2453e519524SHoward Hinnant    typename Operation::first_argument_type value;
2463e519524SHoward Hinnantpublic:
2473e519524SHoward Hinnant    binder1st(const Operation& x, const typename Operation::first_argument_type y);
2483e519524SHoward Hinnant    typename Operation::result_type operator()(      typename Operation::second_argument_type& x) const;
2493e519524SHoward Hinnant    typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const;
2503e519524SHoward Hinnant};
2513e519524SHoward Hinnant
2523e519524SHoward Hinnanttemplate <class Operation, class T>
2537d210c78SMarshall Clowbinder1st<Operation> bind1st(const Operation& op, const T& x);  // deprecated in C++11, removed in C++17
2543e519524SHoward Hinnant
2553e519524SHoward Hinnanttemplate <class Operation>
2567d210c78SMarshall Clowclass binder2nd     // deprecated in C++11, removed in C++17
2573e519524SHoward Hinnant    : public unary_function<typename Operation::first_argument_type,
2583e519524SHoward Hinnant                            typename Operation::result_type>
2593e519524SHoward Hinnant{
2603e519524SHoward Hinnantprotected:
2613e519524SHoward Hinnant    Operation                                op;
2623e519524SHoward Hinnant    typename Operation::second_argument_type value;
2633e519524SHoward Hinnantpublic:
2643e519524SHoward Hinnant    binder2nd(const Operation& x, const typename Operation::second_argument_type y);
2653e519524SHoward Hinnant    typename Operation::result_type operator()(      typename Operation::first_argument_type& x) const;
2663e519524SHoward Hinnant    typename Operation::result_type operator()(const typename Operation::first_argument_type& x) const;
2673e519524SHoward Hinnant};
2683e519524SHoward Hinnant
2693e519524SHoward Hinnanttemplate <class Operation, class T>
2707d210c78SMarshall Clowbinder2nd<Operation> bind2nd(const Operation& op, const T& x);  // deprecated in C++11, removed in C++17
2713e519524SHoward Hinnant
2727d210c78SMarshall Clowtemplate <class Arg, class Result>      // deprecated in C++11, removed in C++17
2733e519524SHoward Hinnantclass pointer_to_unary_function : public unary_function<Arg, Result>
2743e519524SHoward Hinnant{
2753e519524SHoward Hinnantpublic:
2763e519524SHoward Hinnant    explicit pointer_to_unary_function(Result (*f)(Arg));
2773e519524SHoward Hinnant    Result operator()(Arg x) const;
2783e519524SHoward Hinnant};
2793e519524SHoward Hinnant
2803e519524SHoward Hinnanttemplate <class Arg, class Result>
2817d210c78SMarshall Clowpointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg));      // deprecated in C++11, removed in C++17
2823e519524SHoward Hinnant
2837d210c78SMarshall Clowtemplate <class Arg1, class Arg2, class Result>      // deprecated in C++11, removed in C++17
2843e519524SHoward Hinnantclass pointer_to_binary_function : public binary_function<Arg1, Arg2, Result>
2853e519524SHoward Hinnant{
2863e519524SHoward Hinnantpublic:
2873e519524SHoward Hinnant    explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2));
2883e519524SHoward Hinnant    Result operator()(Arg1 x, Arg2 y) const;
2893e519524SHoward Hinnant};
2903e519524SHoward Hinnant
2913e519524SHoward Hinnanttemplate <class Arg1, class Arg2, class Result>
2927d210c78SMarshall Clowpointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1,Arg2));      // deprecated in C++11, removed in C++17
2933e519524SHoward Hinnant
2947d210c78SMarshall Clowtemplate<class S, class T>      // deprecated in C++11, removed in C++17
2953e519524SHoward Hinnantclass mem_fun_t : public unary_function<T*, S>
2963e519524SHoward Hinnant{
2973e519524SHoward Hinnantpublic:
2983e519524SHoward Hinnant    explicit mem_fun_t(S (T::*p)());
2993e519524SHoward Hinnant    S operator()(T* p) const;
3003e519524SHoward Hinnant};
3013e519524SHoward Hinnant
3023e519524SHoward Hinnanttemplate<class S, class T, class A>
3037d210c78SMarshall Clowclass mem_fun1_t : public binary_function<T*, A, S>      // deprecated in C++11, removed in C++17
3043e519524SHoward Hinnant{
3053e519524SHoward Hinnantpublic:
3063e519524SHoward Hinnant    explicit mem_fun1_t(S (T::*p)(A));
3073e519524SHoward Hinnant    S operator()(T* p, A x) const;
3083e519524SHoward Hinnant};
3093e519524SHoward Hinnant
3107d210c78SMarshall Clowtemplate<class S, class T>          mem_fun_t<S,T>    mem_fun(S (T::*f)());      // deprecated in C++11, removed in C++17
3117d210c78SMarshall Clowtemplate<class S, class T, class A> mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A));     // deprecated in C++11, removed in C++17
3123e519524SHoward Hinnant
3133e519524SHoward Hinnanttemplate<class S, class T>
3147d210c78SMarshall Clowclass mem_fun_ref_t : public unary_function<T, S>      // deprecated in C++11, removed in C++17
3153e519524SHoward Hinnant{
3163e519524SHoward Hinnantpublic:
3173e519524SHoward Hinnant    explicit mem_fun_ref_t(S (T::*p)());
3183e519524SHoward Hinnant    S operator()(T& p) const;
3193e519524SHoward Hinnant};
3203e519524SHoward Hinnant
3213e519524SHoward Hinnanttemplate<class S, class T, class A>
3227d210c78SMarshall Clowclass mem_fun1_ref_t : public binary_function<T, A, S>      // deprecated in C++11, removed in C++17
3233e519524SHoward Hinnant{
3243e519524SHoward Hinnantpublic:
3253e519524SHoward Hinnant    explicit mem_fun1_ref_t(S (T::*p)(A));
3263e519524SHoward Hinnant    S operator()(T& p, A x) const;
3273e519524SHoward Hinnant};
3283e519524SHoward Hinnant
3297d210c78SMarshall Clowtemplate<class S, class T>          mem_fun_ref_t<S,T>    mem_fun_ref(S (T::*f)());      // deprecated in C++11, removed in C++17
3307d210c78SMarshall Clowtemplate<class S, class T, class A> mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A));     // deprecated in C++11, removed in C++17
3313e519524SHoward Hinnant
3323e519524SHoward Hinnanttemplate <class S, class T>
3337d210c78SMarshall Clowclass const_mem_fun_t : public unary_function<const T*, S>      // deprecated in C++11, removed in C++17
3343e519524SHoward Hinnant{
3353e519524SHoward Hinnantpublic:
3363e519524SHoward Hinnant    explicit const_mem_fun_t(S (T::*p)() const);
3373e519524SHoward Hinnant    S operator()(const T* p) const;
3383e519524SHoward Hinnant};
3393e519524SHoward Hinnant
3403e519524SHoward Hinnanttemplate <class S, class T, class A>
3417d210c78SMarshall Clowclass const_mem_fun1_t : public binary_function<const T*, A, S>      // deprecated in C++11, removed in C++17
3423e519524SHoward Hinnant{
3433e519524SHoward Hinnantpublic:
3443e519524SHoward Hinnant    explicit const_mem_fun1_t(S (T::*p)(A) const);
3453e519524SHoward Hinnant    S operator()(const T* p, A x) const;
3463e519524SHoward Hinnant};
3473e519524SHoward Hinnant
3487d210c78SMarshall Clowtemplate <class S, class T>          const_mem_fun_t<S,T>    mem_fun(S (T::*f)() const);      // deprecated in C++11, removed in C++17
3497d210c78SMarshall Clowtemplate <class S, class T, class A> const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const);     // deprecated in C++11, removed in C++17
3503e519524SHoward Hinnant
3513e519524SHoward Hinnanttemplate <class S, class T>
3527d210c78SMarshall Clowclass const_mem_fun_ref_t : public unary_function<T, S>      // deprecated in C++11, removed in C++17
3533e519524SHoward Hinnant{
3543e519524SHoward Hinnantpublic:
3553e519524SHoward Hinnant    explicit const_mem_fun_ref_t(S (T::*p)() const);
3563e519524SHoward Hinnant    S operator()(const T& p) const;
3573e519524SHoward Hinnant};
3583e519524SHoward Hinnant
3593e519524SHoward Hinnanttemplate <class S, class T, class A>
3607d210c78SMarshall Clowclass const_mem_fun1_ref_t : public binary_function<T, A, S>      // deprecated in C++11, removed in C++17
3613e519524SHoward Hinnant{
3623e519524SHoward Hinnantpublic:
3633e519524SHoward Hinnant    explicit const_mem_fun1_ref_t(S (T::*p)(A) const);
3643e519524SHoward Hinnant    S operator()(const T& p, A x) const;
3653e519524SHoward Hinnant};
3663e519524SHoward Hinnant
3677d210c78SMarshall Clowtemplate <class S, class T>          const_mem_fun_ref_t<S,T>    mem_fun_ref(S (T::*f)() const);   // deprecated in C++11, removed in C++17
3687d210c78SMarshall Clowtemplate <class S, class T, class A> const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const);  // deprecated in C++11, removed in C++17
3693e519524SHoward Hinnant
3707b00e9faSArthur O'Dwyertemplate<class R, class T>
3717b00e9faSArthur O'Dwyerconstexpr unspecified mem_fn(R T::*); // constexpr in C++20
3729b0b6d45SHoward Hinnant
3733e519524SHoward Hinnantclass bad_function_call
3743e519524SHoward Hinnant    : public exception
3753e519524SHoward Hinnant{
3763e519524SHoward Hinnant};
3773e519524SHoward Hinnant
3789b0b6d45SHoward Hinnanttemplate<class> class function; // undefined
3793e519524SHoward Hinnant
3809b0b6d45SHoward Hinnanttemplate<class R, class... ArgTypes>
3813e519524SHoward Hinnantclass function<R(ArgTypes...)>
3823e519524SHoward Hinnant  : public unary_function<T1, R>      // iff sizeof...(ArgTypes) == 1 and
3833e519524SHoward Hinnant                                      // ArgTypes contains T1
3843e519524SHoward Hinnant  : public binary_function<T1, T2, R> // iff sizeof...(ArgTypes) == 2 and
3853e519524SHoward Hinnant                                      // ArgTypes contains T1 and T2
3863e519524SHoward Hinnant{
3873e519524SHoward Hinnantpublic:
3883e519524SHoward Hinnant    typedef R result_type;
3893e519524SHoward Hinnant
3909b0b6d45SHoward Hinnant    // construct/copy/destroy:
3916a07d6f0SHoward Hinnant    function() noexcept;
3926a07d6f0SHoward Hinnant    function(nullptr_t) noexcept;
3933e519524SHoward Hinnant    function(const function&);
3946a07d6f0SHoward Hinnant    function(function&&) noexcept;
3953e519524SHoward Hinnant    template<class F>
3963e519524SHoward Hinnant      function(F);
3973e519524SHoward Hinnant    template<Allocator Alloc>
3986ecac730SMarshall Clow      function(allocator_arg_t, const Alloc&) noexcept;            // removed in C++17
3993e519524SHoward Hinnant    template<Allocator Alloc>
4006ecac730SMarshall Clow      function(allocator_arg_t, const Alloc&, nullptr_t) noexcept; // removed in C++17
4013e519524SHoward Hinnant    template<Allocator Alloc>
4026ecac730SMarshall Clow      function(allocator_arg_t, const Alloc&, const function&);    // removed in C++17
4033e519524SHoward Hinnant    template<Allocator Alloc>
4046ecac730SMarshall Clow      function(allocator_arg_t, const Alloc&, function&&);         // removed in C++17
4053e519524SHoward Hinnant    template<class F, Allocator Alloc>
4066ecac730SMarshall Clow      function(allocator_arg_t, const Alloc&, F);                  // removed in C++17
4073e519524SHoward Hinnant
4083e519524SHoward Hinnant    function& operator=(const function&);
4096a07d6f0SHoward Hinnant    function& operator=(function&&) noexcept;
410af152c84SHoward Hinnant    function& operator=(nullptr_t) noexcept;
4113e519524SHoward Hinnant    template<class F>
4129b0b6d45SHoward Hinnant      function& operator=(F&&);
4133e519524SHoward Hinnant    template<class F>
4146a07d6f0SHoward Hinnant      function& operator=(reference_wrapper<F>) noexcept;
4153e519524SHoward Hinnant
4163e519524SHoward Hinnant    ~function();
4173e519524SHoward Hinnant
4189b0b6d45SHoward Hinnant    // function modifiers:
4196a07d6f0SHoward Hinnant    void swap(function&) noexcept;
4209b0b6d45SHoward Hinnant    template<class F, class Alloc>
4210aa1ccb0SMarshall Clow      void assign(F&&, const Alloc&);                 // Removed in C++17
4223e519524SHoward Hinnant
4239b0b6d45SHoward Hinnant    // function capacity:
4246a07d6f0SHoward Hinnant    explicit operator bool() const noexcept;
4253e519524SHoward Hinnant
4269b0b6d45SHoward Hinnant    // function invocation:
4273e519524SHoward Hinnant    R operator()(ArgTypes...) const;
4283e519524SHoward Hinnant
4299b0b6d45SHoward Hinnant    // function target access:
4306a07d6f0SHoward Hinnant    const std::type_info& target_type() const noexcept;
4316a07d6f0SHoward Hinnant    template <typename T>       T* target() noexcept;
4326a07d6f0SHoward Hinnant    template <typename T> const T* target() const noexcept;
4333e519524SHoward Hinnant};
4343e519524SHoward Hinnant
435e1eabcdfSLouis Dionne// Deduction guides
436e1eabcdfSLouis Dionnetemplate<class R, class ...Args>
437e1eabcdfSLouis Dionnefunction(R(*)(Args...)) -> function<R(Args...)>; // since C++17
438e1eabcdfSLouis Dionne
439e1eabcdfSLouis Dionnetemplate<class F>
440e1eabcdfSLouis Dionnefunction(F) -> function<see-below>; // since C++17
441e1eabcdfSLouis Dionne
4429b0b6d45SHoward Hinnant// Null pointer comparisons:
4439b0b6d45SHoward Hinnanttemplate <class R, class ... ArgTypes>
4446a07d6f0SHoward Hinnant  bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
4453e519524SHoward Hinnant
4469b0b6d45SHoward Hinnanttemplate <class R, class ... ArgTypes>
4476a07d6f0SHoward Hinnant  bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
4483e519524SHoward Hinnant
4499b0b6d45SHoward Hinnanttemplate <class R, class ... ArgTypes>
4506a07d6f0SHoward Hinnant  bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
4513e519524SHoward Hinnant
4529b0b6d45SHoward Hinnanttemplate <class  R, class ... ArgTypes>
4536a07d6f0SHoward Hinnant  bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
4543e519524SHoward Hinnant
4559b0b6d45SHoward Hinnant// specialized algorithms:
4569b0b6d45SHoward Hinnanttemplate <class  R, class ... ArgTypes>
4576a07d6f0SHoward Hinnant  void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;
4583e519524SHoward Hinnant
4593e519524SHoward Hinnanttemplate <class T> struct hash;
4603e519524SHoward Hinnant
4613e519524SHoward Hinnanttemplate <> struct hash<bool>;
4623e519524SHoward Hinnanttemplate <> struct hash<char>;
4633e519524SHoward Hinnanttemplate <> struct hash<signed char>;
4643e519524SHoward Hinnanttemplate <> struct hash<unsigned char>;
465b526d876SYuriy Chernyshovtemplate <> struct hash<char8_t>; // since C++20
4663e519524SHoward Hinnanttemplate <> struct hash<char16_t>;
4673e519524SHoward Hinnanttemplate <> struct hash<char32_t>;
4683e519524SHoward Hinnanttemplate <> struct hash<wchar_t>;
4693e519524SHoward Hinnanttemplate <> struct hash<short>;
4703e519524SHoward Hinnanttemplate <> struct hash<unsigned short>;
4713e519524SHoward Hinnanttemplate <> struct hash<int>;
4723e519524SHoward Hinnanttemplate <> struct hash<unsigned int>;
4733e519524SHoward Hinnanttemplate <> struct hash<long>;
4743e519524SHoward Hinnanttemplate <> struct hash<long long>;
4753e519524SHoward Hinnanttemplate <> struct hash<unsigned long>;
4763e519524SHoward Hinnanttemplate <> struct hash<unsigned long long>;
4773e519524SHoward Hinnant
4783e519524SHoward Hinnanttemplate <> struct hash<float>;
4793e519524SHoward Hinnanttemplate <> struct hash<double>;
4803e519524SHoward Hinnanttemplate <> struct hash<long double>;
4813e519524SHoward Hinnant
4823e519524SHoward Hinnanttemplate<class T> struct hash<T*>;
483d8323168SMarshall Clowtemplate <> struct hash<nullptr_t>;  // C++17
4843e519524SHoward Hinnant
485*79a2b4baSKonstantin Varlamovnamespace ranges {
486*79a2b4baSKonstantin Varlamov  // [range.cmp], concept-constrained comparisons
487*79a2b4baSKonstantin Varlamov  struct equal_to;
488*79a2b4baSKonstantin Varlamov  struct not_equal_to;
489*79a2b4baSKonstantin Varlamov  struct greater;
490*79a2b4baSKonstantin Varlamov  struct less;
491*79a2b4baSKonstantin Varlamov  struct greater_equal;
492*79a2b4baSKonstantin Varlamov  struct less_equal;
493*79a2b4baSKonstantin Varlamov}
494*79a2b4baSKonstantin Varlamov
4953e519524SHoward Hinnant}  // std
4963e519524SHoward Hinnant
4973e519524SHoward HinnantPOLICY:  For non-variadic implementations, the number of arguments is limited
4983e519524SHoward Hinnant         to 3.  It is hoped that the need for non-variadic implementations
4993e519524SHoward Hinnant         will be minimal.
5003e519524SHoward Hinnant
5013e519524SHoward Hinnant*/
5023e519524SHoward Hinnant
503d03aa7d6SLouis Dionne#include <__algorithm/search.h>
504385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler
5053df094d3SArthur O'Dwyer#include <__compare/compare_three_way.h>
5063e519524SHoward Hinnant#include <__config>
50706b40e80SArthur O'Dwyer#include <__debug>
508050b064fSChristopher Di Bella#include <__functional/binary_function.h> // TODO: deprecate
509050b064fSChristopher Di Bella#include <__functional/binary_negate.h>
5104d81a46fSArthur O'Dwyer#include <__functional/bind.h>
51189a7bdb1SLouis Dionne#include <__functional/bind_back.h>
512050b064fSChristopher Di Bella#include <__functional/bind_front.h>
513050b064fSChristopher Di Bella#include <__functional/binder1st.h>
514050b064fSChristopher Di Bella#include <__functional/binder2nd.h>
515971e9c80SNikolas Klauser#include <__functional/boyer_moore_searcher.h>
51689a7bdb1SLouis Dionne#include <__functional/compose.h>
517050b064fSChristopher Di Bella#include <__functional/default_searcher.h>
518050b064fSChristopher Di Bella#include <__functional/function.h>
51969d5a666SChristopher Di Bella#include <__functional/hash.h>
520050b064fSChristopher Di Bella#include <__functional/identity.h>
521050b064fSChristopher Di Bella#include <__functional/invoke.h>
522050b064fSChristopher Di Bella#include <__functional/mem_fn.h> // TODO: deprecate
523050b064fSChristopher Di Bella#include <__functional/mem_fun_ref.h>
524050b064fSChristopher Di Bella#include <__functional/not_fn.h>
525050b064fSChristopher Di Bella#include <__functional/operations.h>
526050b064fSChristopher Di Bella#include <__functional/pointer_to_binary_function.h>
527050b064fSChristopher Di Bella#include <__functional/pointer_to_unary_function.h>
528050b064fSChristopher Di Bella#include <__functional/ranges_operations.h>
529050b064fSChristopher Di Bella#include <__functional/reference_wrapper.h>
530050b064fSChristopher Di Bella#include <__functional/unary_function.h> // TODO: deprecate
531050b064fSChristopher Di Bella#include <__functional/unary_negate.h>
53269d5a666SChristopher Di Bella#include <__functional/unwrap_ref.h>
5336adbc83eSChristopher Di Bella#include <__utility/forward.h>
534879cbac0Szoecarver#include <concepts>
5353e519524SHoward Hinnant#include <exception>
5363e519524SHoward Hinnant#include <memory>
5373e519524SHoward Hinnant#include <tuple>
538bfbd73f8SArthur O'Dwyer#include <type_traits>
539bfbd73f8SArthur O'Dwyer#include <typeinfo>
540f56972e2SMarshall Clow#include <version>
5413e519524SHoward Hinnant
542de4a57cbSLouis Dionne#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
543de4a57cbSLouis Dionne#  include <utility>
544de4a57cbSLouis Dionne#endif
545de4a57cbSLouis Dionne
546073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5473e519524SHoward Hinnant#  pragma GCC system_header
548073458b1SHoward Hinnant#endif
5493e519524SHoward Hinnant
5503e519524SHoward Hinnant#endif // _LIBCPP_FUNCTIONAL
551