17a984708SDavid Chisnall// -*- C++ -*-
27a984708SDavid Chisnall//===------------------------ functional ----------------------------------===//
37a984708SDavid Chisnall//
47a984708SDavid Chisnall//                     The LLVM Compiler Infrastructure
57a984708SDavid Chisnall//
67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open
77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details.
87a984708SDavid Chisnall//
97a984708SDavid Chisnall//===----------------------------------------------------------------------===//
107a984708SDavid Chisnall
117a984708SDavid Chisnall#ifndef _LIBCPP_FUNCTIONAL
127a984708SDavid Chisnall#define _LIBCPP_FUNCTIONAL
137a984708SDavid Chisnall
147a984708SDavid Chisnall/*
157a984708SDavid Chisnall    functional synopsis
167a984708SDavid Chisnall
177a984708SDavid Chisnallnamespace std
187a984708SDavid Chisnall{
197a984708SDavid Chisnall
207a984708SDavid Chisnalltemplate <class Arg, class Result>
217a984708SDavid Chisnallstruct unary_function
227a984708SDavid Chisnall{
237a984708SDavid Chisnall    typedef Arg    argument_type;
247a984708SDavid Chisnall    typedef Result result_type;
257a984708SDavid Chisnall};
267a984708SDavid Chisnall
277a984708SDavid Chisnalltemplate <class Arg1, class Arg2, class Result>
287a984708SDavid Chisnallstruct binary_function
297a984708SDavid Chisnall{
307a984708SDavid Chisnall    typedef Arg1   first_argument_type;
317a984708SDavid Chisnall    typedef Arg2   second_argument_type;
327a984708SDavid Chisnall    typedef Result result_type;
337a984708SDavid Chisnall};
347a984708SDavid Chisnall
357a984708SDavid Chisnalltemplate <class T>
367a984708SDavid Chisnallclass reference_wrapper
377a984708SDavid Chisnall    : public unary_function<T1, R> // if wrapping a unary functor
387a984708SDavid Chisnall    : public binary_function<T1, T2, R> // if wraping a binary functor
397a984708SDavid Chisnall{
407a984708SDavid Chisnallpublic:
417a984708SDavid Chisnall    // types
427a984708SDavid Chisnall    typedef T type;
437a984708SDavid Chisnall    typedef see below result_type; // Not always defined
447a984708SDavid Chisnall
457a984708SDavid Chisnall    // construct/copy/destroy
467a984708SDavid Chisnall    reference_wrapper(T&) noexcept;
477a984708SDavid Chisnall    reference_wrapper(T&&) = delete; // do not bind to temps
487a984708SDavid Chisnall    reference_wrapper(const reference_wrapper<T>& x) noexcept;
497a984708SDavid Chisnall
507a984708SDavid Chisnall    // assignment
517a984708SDavid Chisnall    reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept;
527a984708SDavid Chisnall
537a984708SDavid Chisnall    // access
547a984708SDavid Chisnall    operator T& () const noexcept;
557a984708SDavid Chisnall    T& get() const noexcept;
567a984708SDavid Chisnall
577a984708SDavid Chisnall    // invoke
587a984708SDavid Chisnall    template <class... ArgTypes>
594f7ab58eSDimitry Andric      typename result_of<T&(ArgTypes&&...)>::type
607a984708SDavid Chisnall          operator() (ArgTypes&&...) const;
617a984708SDavid Chisnall};
627a984708SDavid Chisnall
637a984708SDavid Chisnalltemplate <class T> reference_wrapper<T> ref(T& t) noexcept;
647a984708SDavid Chisnalltemplate <class T> void ref(const T&& t) = delete;
657a984708SDavid Chisnalltemplate <class T> reference_wrapper<T> ref(reference_wrapper<T>t) noexcept;
667a984708SDavid Chisnall
677a984708SDavid Chisnalltemplate <class T> reference_wrapper<const T> cref(const T& t) noexcept;
687a984708SDavid Chisnalltemplate <class T> void cref(const T&& t) = delete;
697a984708SDavid Chisnalltemplate <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
707a984708SDavid Chisnall
71*b5893f02SDimitry Andrictemplate <class T> struct unwrap_reference;                                       // since C++20
72*b5893f02SDimitry Andrictemplate <class T> struct unwrap_ref_decay : unwrap_reference<decay_t<T>> { };    // since C++20
73*b5893f02SDimitry Andrictemplate <class T> using unwrap_reference_t = typename unwrap_reference<T>::type; // since C++20
74*b5893f02SDimitry Andrictemplate <class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; // since C++20
75*b5893f02SDimitry Andric
764f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
777a984708SDavid Chisnallstruct plus : binary_function<T, T, T>
787a984708SDavid Chisnall{
797a984708SDavid Chisnall    T operator()(const T& x, const T& y) const;
807a984708SDavid Chisnall};
817a984708SDavid Chisnall
824f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
837a984708SDavid Chisnallstruct minus : binary_function<T, T, T>
847a984708SDavid Chisnall{
857a984708SDavid Chisnall    T operator()(const T& x, const T& y) const;
867a984708SDavid Chisnall};
877a984708SDavid Chisnall
884f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
897a984708SDavid Chisnallstruct multiplies : binary_function<T, T, T>
907a984708SDavid Chisnall{
917a984708SDavid Chisnall    T operator()(const T& x, const T& y) const;
927a984708SDavid Chisnall};
937a984708SDavid Chisnall
944f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
957a984708SDavid Chisnallstruct divides : binary_function<T, T, T>
967a984708SDavid Chisnall{
977a984708SDavid Chisnall    T operator()(const T& x, const T& y) const;
987a984708SDavid Chisnall};
997a984708SDavid Chisnall
1004f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1017a984708SDavid Chisnallstruct modulus : binary_function<T, T, T>
1027a984708SDavid Chisnall{
1037a984708SDavid Chisnall    T operator()(const T& x, const T& y) const;
1047a984708SDavid Chisnall};
1057a984708SDavid Chisnall
1064f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1077a984708SDavid Chisnallstruct negate : unary_function<T, T>
1087a984708SDavid Chisnall{
1097a984708SDavid Chisnall    T operator()(const T& x) const;
1107a984708SDavid Chisnall};
1117a984708SDavid Chisnall
1124f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1137a984708SDavid Chisnallstruct equal_to : binary_function<T, T, bool>
1147a984708SDavid Chisnall{
1157a984708SDavid Chisnall    bool operator()(const T& x, const T& y) const;
1167a984708SDavid Chisnall};
1177a984708SDavid Chisnall
1184f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1197a984708SDavid Chisnallstruct not_equal_to : binary_function<T, T, bool>
1207a984708SDavid Chisnall{
1217a984708SDavid Chisnall    bool operator()(const T& x, const T& y) const;
1227a984708SDavid Chisnall};
1237a984708SDavid Chisnall
1244f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1257a984708SDavid Chisnallstruct greater : binary_function<T, T, bool>
1267a984708SDavid Chisnall{
1277a984708SDavid Chisnall    bool operator()(const T& x, const T& y) const;
1287a984708SDavid Chisnall};
1297a984708SDavid Chisnall
1304f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1317a984708SDavid Chisnallstruct less : binary_function<T, T, bool>
1327a984708SDavid Chisnall{
1337a984708SDavid Chisnall    bool operator()(const T& x, const T& y) const;
1347a984708SDavid Chisnall};
1357a984708SDavid Chisnall
1364f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1377a984708SDavid Chisnallstruct greater_equal : binary_function<T, T, bool>
1387a984708SDavid Chisnall{
1397a984708SDavid Chisnall    bool operator()(const T& x, const T& y) const;
1407a984708SDavid Chisnall};
1417a984708SDavid Chisnall
1424f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1437a984708SDavid Chisnallstruct less_equal : binary_function<T, T, bool>
1447a984708SDavid Chisnall{
1457a984708SDavid Chisnall    bool operator()(const T& x, const T& y) const;
1467a984708SDavid Chisnall};
1477a984708SDavid Chisnall
1484f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1497a984708SDavid Chisnallstruct logical_and : binary_function<T, T, bool>
1507a984708SDavid Chisnall{
1517a984708SDavid Chisnall    bool operator()(const T& x, const T& y) const;
1527a984708SDavid Chisnall};
1537a984708SDavid Chisnall
1544f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1557a984708SDavid Chisnallstruct logical_or : binary_function<T, T, bool>
1567a984708SDavid Chisnall{
1577a984708SDavid Chisnall    bool operator()(const T& x, const T& y) const;
1587a984708SDavid Chisnall};
1597a984708SDavid Chisnall
1604f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1617a984708SDavid Chisnallstruct logical_not : unary_function<T, bool>
1627a984708SDavid Chisnall{
1637a984708SDavid Chisnall    bool operator()(const T& x) const;
1647a984708SDavid Chisnall};
1657a984708SDavid Chisnall
1664f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1674f7ab58eSDimitry Andricstruct bit_and : unary_function<T, bool>
1684f7ab58eSDimitry Andric{
1694f7ab58eSDimitry Andric    bool operator()(const T& x, const T& y) const;
1704f7ab58eSDimitry Andric};
1714f7ab58eSDimitry Andric
1724f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1734f7ab58eSDimitry Andricstruct bit_or : unary_function<T, bool>
1744f7ab58eSDimitry Andric{
1754f7ab58eSDimitry Andric    bool operator()(const T& x, const T& y) const;
1764f7ab58eSDimitry Andric};
1774f7ab58eSDimitry Andric
1784f7ab58eSDimitry Andrictemplate <class T> // <class T=void> in C++14
1794f7ab58eSDimitry Andricstruct bit_xor : unary_function<T, bool>
1804f7ab58eSDimitry Andric{
1814f7ab58eSDimitry Andric    bool operator()(const T& x, const T& y) const;
1824f7ab58eSDimitry Andric};
1834f7ab58eSDimitry Andric
1844f7ab58eSDimitry Andrictemplate <class T=void> // C++14
1854f7ab58eSDimitry Andricstruct bit_xor : unary_function<T, bool>
1864f7ab58eSDimitry Andric{
1874f7ab58eSDimitry Andric    bool operator()(const T& x) const;
1884f7ab58eSDimitry Andric};
1894f7ab58eSDimitry Andric
1907a984708SDavid Chisnalltemplate <class Predicate>
191*b5893f02SDimitry Andricclass unary_negate // deprecated in C++17
1927a984708SDavid Chisnall    : public unary_function<typename Predicate::argument_type, bool>
1937a984708SDavid Chisnall{
1947a984708SDavid Chisnallpublic:
1957a984708SDavid Chisnall    explicit unary_negate(const Predicate& pred);
1967a984708SDavid Chisnall    bool operator()(const typename Predicate::argument_type& x) const;
1977a984708SDavid Chisnall};
1987a984708SDavid Chisnall
199*b5893f02SDimitry Andrictemplate <class Predicate> // deprecated in C++17
200*b5893f02SDimitry Andricunary_negate<Predicate> not1(const Predicate& pred);
2017a984708SDavid Chisnall
2027a984708SDavid Chisnalltemplate <class Predicate>
203*b5893f02SDimitry Andricclass binary_negate // deprecated in C++17
2047a984708SDavid Chisnall    : public binary_function<typename Predicate::first_argument_type,
2057a984708SDavid Chisnall                             typename Predicate::second_argument_type,
2067a984708SDavid Chisnall                             bool>
2077a984708SDavid Chisnall{
2087a984708SDavid Chisnallpublic:
2097a984708SDavid Chisnall    explicit binary_negate(const Predicate& pred);
2107a984708SDavid Chisnall    bool operator()(const typename Predicate::first_argument_type& x,
2117a984708SDavid Chisnall                    const typename Predicate::second_argument_type& y) const;
2127a984708SDavid Chisnall};
2137a984708SDavid Chisnall
214*b5893f02SDimitry Andrictemplate <class Predicate> // deprecated in C++17
215*b5893f02SDimitry Andricbinary_negate<Predicate> not2(const Predicate& pred);
2167a984708SDavid Chisnall
2177c82a1ecSDimitry Andrictemplate <class F> unspecified not_fn(F&& f); // C++17
2187c82a1ecSDimitry Andric
2197a984708SDavid Chisnalltemplate<class T> struct is_bind_expression;
2207a984708SDavid Chisnalltemplate<class T> struct is_placeholder;
2217a984708SDavid Chisnall
222aed8d94eSDimitry Andric    // See C++14 20.9.9, Function object binders
22330785c0eSDimitry Andrictemplate <class T> inline constexpr bool is_bind_expression_v
224aed8d94eSDimitry Andric  = is_bind_expression<T>::value; // C++17
22530785c0eSDimitry Andrictemplate <class T> inline constexpr int is_placeholder_v
226aed8d94eSDimitry Andric  = is_placeholder<T>::value; // C++17
227aed8d94eSDimitry Andric
228aed8d94eSDimitry Andric
2297a984708SDavid Chisnalltemplate<class Fn, class... BoundArgs>
2307a984708SDavid Chisnall  unspecified bind(Fn&&, BoundArgs&&...);
2317a984708SDavid Chisnalltemplate<class R, class Fn, class... BoundArgs>
2327a984708SDavid Chisnall  unspecified bind(Fn&&, BoundArgs&&...);
2337a984708SDavid Chisnall
2347a984708SDavid Chisnallnamespace placeholders {
2357a984708SDavid Chisnall  // M is the implementation-defined number of placeholders
2367a984708SDavid Chisnall  extern unspecified _1;
2377a984708SDavid Chisnall  extern unspecified _2;
2387a984708SDavid Chisnall  .
2397a984708SDavid Chisnall  .
2407a984708SDavid Chisnall  .
24194e3ee44SDavid Chisnall  extern unspecified _Mp;
2427a984708SDavid Chisnall}
2437a984708SDavid Chisnall
2447a984708SDavid Chisnalltemplate <class Operation>
245540d2a8bSDimitry Andricclass binder1st     // deprecated in C++11, removed in C++17
2467a984708SDavid Chisnall    : public unary_function<typename Operation::second_argument_type,
2477a984708SDavid Chisnall                            typename Operation::result_type>
2487a984708SDavid Chisnall{
2497a984708SDavid Chisnallprotected:
2507a984708SDavid Chisnall    Operation                               op;
2517a984708SDavid Chisnall    typename Operation::first_argument_type value;
2527a984708SDavid Chisnallpublic:
2537a984708SDavid Chisnall    binder1st(const Operation& x, const typename Operation::first_argument_type y);
2547a984708SDavid Chisnall    typename Operation::result_type operator()(      typename Operation::second_argument_type& x) const;
2557a984708SDavid Chisnall    typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const;
2567a984708SDavid Chisnall};
2577a984708SDavid Chisnall
2587a984708SDavid Chisnalltemplate <class Operation, class T>
259540d2a8bSDimitry Andricbinder1st<Operation> bind1st(const Operation& op, const T& x);  // deprecated in C++11, removed in C++17
2607a984708SDavid Chisnall
2617a984708SDavid Chisnalltemplate <class Operation>
262540d2a8bSDimitry Andricclass binder2nd     // deprecated in C++11, removed in C++17
2637a984708SDavid Chisnall    : public unary_function<typename Operation::first_argument_type,
2647a984708SDavid Chisnall                            typename Operation::result_type>
2657a984708SDavid Chisnall{
2667a984708SDavid Chisnallprotected:
2677a984708SDavid Chisnall    Operation                                op;
2687a984708SDavid Chisnall    typename Operation::second_argument_type value;
2697a984708SDavid Chisnallpublic:
2707a984708SDavid Chisnall    binder2nd(const Operation& x, const typename Operation::second_argument_type y);
2717a984708SDavid Chisnall    typename Operation::result_type operator()(      typename Operation::first_argument_type& x) const;
2727a984708SDavid Chisnall    typename Operation::result_type operator()(const typename Operation::first_argument_type& x) const;
2737a984708SDavid Chisnall};
2747a984708SDavid Chisnall
2757a984708SDavid Chisnalltemplate <class Operation, class T>
276540d2a8bSDimitry Andricbinder2nd<Operation> bind2nd(const Operation& op, const T& x);  // deprecated in C++11, removed in C++17
2777a984708SDavid Chisnall
278540d2a8bSDimitry Andrictemplate <class Arg, class Result>      // deprecated in C++11, removed in C++17
2797a984708SDavid Chisnallclass pointer_to_unary_function : public unary_function<Arg, Result>
2807a984708SDavid Chisnall{
2817a984708SDavid Chisnallpublic:
2827a984708SDavid Chisnall    explicit pointer_to_unary_function(Result (*f)(Arg));
2837a984708SDavid Chisnall    Result operator()(Arg x) const;
2847a984708SDavid Chisnall};
2857a984708SDavid Chisnall
2867a984708SDavid Chisnalltemplate <class Arg, class Result>
287540d2a8bSDimitry Andricpointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg));      // deprecated in C++11, removed in C++17
2887a984708SDavid Chisnall
289540d2a8bSDimitry Andrictemplate <class Arg1, class Arg2, class Result>      // deprecated in C++11, removed in C++17
2907a984708SDavid Chisnallclass pointer_to_binary_function : public binary_function<Arg1, Arg2, Result>
2917a984708SDavid Chisnall{
2927a984708SDavid Chisnallpublic:
2937a984708SDavid Chisnall    explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2));
2947a984708SDavid Chisnall    Result operator()(Arg1 x, Arg2 y) const;
2957a984708SDavid Chisnall};
2967a984708SDavid Chisnall
2977a984708SDavid Chisnalltemplate <class Arg1, class Arg2, class Result>
298540d2a8bSDimitry Andricpointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1,Arg2));      // deprecated in C++11, removed in C++17
2997a984708SDavid Chisnall
300540d2a8bSDimitry Andrictemplate<class S, class T>      // deprecated in C++11, removed in C++17
3017a984708SDavid Chisnallclass mem_fun_t : public unary_function<T*, S>
3027a984708SDavid Chisnall{
3037a984708SDavid Chisnallpublic:
3047a984708SDavid Chisnall    explicit mem_fun_t(S (T::*p)());
3057a984708SDavid Chisnall    S operator()(T* p) const;
3067a984708SDavid Chisnall};
3077a984708SDavid Chisnall
3087a984708SDavid Chisnalltemplate<class S, class T, class A>
309540d2a8bSDimitry Andricclass mem_fun1_t : public binary_function<T*, A, S>      // deprecated in C++11, removed in C++17
3107a984708SDavid Chisnall{
3117a984708SDavid Chisnallpublic:
3127a984708SDavid Chisnall    explicit mem_fun1_t(S (T::*p)(A));
3137a984708SDavid Chisnall    S operator()(T* p, A x) const;
3147a984708SDavid Chisnall};
3157a984708SDavid Chisnall
316540d2a8bSDimitry Andrictemplate<class S, class T>          mem_fun_t<S,T>    mem_fun(S (T::*f)());      // deprecated in C++11, removed in C++17
317540d2a8bSDimitry Andrictemplate<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
3187a984708SDavid Chisnall
3197a984708SDavid Chisnalltemplate<class S, class T>
320540d2a8bSDimitry Andricclass mem_fun_ref_t : public unary_function<T, S>      // deprecated in C++11, removed in C++17
3217a984708SDavid Chisnall{
3227a984708SDavid Chisnallpublic:
3237a984708SDavid Chisnall    explicit mem_fun_ref_t(S (T::*p)());
3247a984708SDavid Chisnall    S operator()(T& p) const;
3257a984708SDavid Chisnall};
3267a984708SDavid Chisnall
3277a984708SDavid Chisnalltemplate<class S, class T, class A>
328540d2a8bSDimitry Andricclass mem_fun1_ref_t : public binary_function<T, A, S>      // deprecated in C++11, removed in C++17
3297a984708SDavid Chisnall{
3307a984708SDavid Chisnallpublic:
3317a984708SDavid Chisnall    explicit mem_fun1_ref_t(S (T::*p)(A));
3327a984708SDavid Chisnall    S operator()(T& p, A x) const;
3337a984708SDavid Chisnall};
3347a984708SDavid Chisnall
335540d2a8bSDimitry Andrictemplate<class S, class T>          mem_fun_ref_t<S,T>    mem_fun_ref(S (T::*f)());      // deprecated in C++11, removed in C++17
336540d2a8bSDimitry Andrictemplate<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
3377a984708SDavid Chisnall
3387a984708SDavid Chisnalltemplate <class S, class T>
339540d2a8bSDimitry Andricclass const_mem_fun_t : public unary_function<const T*, S>      // deprecated in C++11, removed in C++17
3407a984708SDavid Chisnall{
3417a984708SDavid Chisnallpublic:
3427a984708SDavid Chisnall    explicit const_mem_fun_t(S (T::*p)() const);
3437a984708SDavid Chisnall    S operator()(const T* p) const;
3447a984708SDavid Chisnall};
3457a984708SDavid Chisnall
3467a984708SDavid Chisnalltemplate <class S, class T, class A>
347540d2a8bSDimitry Andricclass const_mem_fun1_t : public binary_function<const T*, A, S>      // deprecated in C++11, removed in C++17
3487a984708SDavid Chisnall{
3497a984708SDavid Chisnallpublic:
3507a984708SDavid Chisnall    explicit const_mem_fun1_t(S (T::*p)(A) const);
3517a984708SDavid Chisnall    S operator()(const T* p, A x) const;
3527a984708SDavid Chisnall};
3537a984708SDavid Chisnall
354540d2a8bSDimitry Andrictemplate <class S, class T>          const_mem_fun_t<S,T>    mem_fun(S (T::*f)() const);      // deprecated in C++11, removed in C++17
355540d2a8bSDimitry Andrictemplate <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
3567a984708SDavid Chisnall
3577a984708SDavid Chisnalltemplate <class S, class T>
358540d2a8bSDimitry Andricclass const_mem_fun_ref_t : public unary_function<T, S>      // deprecated in C++11, removed in C++17
3597a984708SDavid Chisnall{
3607a984708SDavid Chisnallpublic:
3617a984708SDavid Chisnall    explicit const_mem_fun_ref_t(S (T::*p)() const);
3627a984708SDavid Chisnall    S operator()(const T& p) const;
3637a984708SDavid Chisnall};
3647a984708SDavid Chisnall
3657a984708SDavid Chisnalltemplate <class S, class T, class A>
366540d2a8bSDimitry Andricclass const_mem_fun1_ref_t : public binary_function<T, A, S>      // deprecated in C++11, removed in C++17
3677a984708SDavid Chisnall{
3687a984708SDavid Chisnallpublic:
3697a984708SDavid Chisnall    explicit const_mem_fun1_ref_t(S (T::*p)(A) const);
3707a984708SDavid Chisnall    S operator()(const T& p, A x) const;
3717a984708SDavid Chisnall};
3727a984708SDavid Chisnall
373540d2a8bSDimitry Andrictemplate <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
374540d2a8bSDimitry Andrictemplate <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
3757a984708SDavid Chisnall
3767a984708SDavid Chisnalltemplate<class R, class T> unspecified mem_fn(R T::*);
3777a984708SDavid Chisnall
3787a984708SDavid Chisnallclass bad_function_call
3797a984708SDavid Chisnall    : public exception
3807a984708SDavid Chisnall{
3817a984708SDavid Chisnall};
3827a984708SDavid Chisnall
3837a984708SDavid Chisnalltemplate<class> class function; // undefined
3847a984708SDavid Chisnall
3857a984708SDavid Chisnalltemplate<class R, class... ArgTypes>
3867a984708SDavid Chisnallclass function<R(ArgTypes...)>
3877a984708SDavid Chisnall  : public unary_function<T1, R>      // iff sizeof...(ArgTypes) == 1 and
3887a984708SDavid Chisnall                                      // ArgTypes contains T1
3897a984708SDavid Chisnall  : public binary_function<T1, T2, R> // iff sizeof...(ArgTypes) == 2 and
3907a984708SDavid Chisnall                                      // ArgTypes contains T1 and T2
3917a984708SDavid Chisnall{
3927a984708SDavid Chisnallpublic:
3937a984708SDavid Chisnall    typedef R result_type;
3947a984708SDavid Chisnall
3957a984708SDavid Chisnall    // construct/copy/destroy:
3967a984708SDavid Chisnall    function() noexcept;
3977a984708SDavid Chisnall    function(nullptr_t) noexcept;
3987a984708SDavid Chisnall    function(const function&);
3997a984708SDavid Chisnall    function(function&&) noexcept;
4007a984708SDavid Chisnall    template<class F>
4017a984708SDavid Chisnall      function(F);
4027a984708SDavid Chisnall    template<Allocator Alloc>
403aed8d94eSDimitry Andric      function(allocator_arg_t, const Alloc&) noexcept;            // removed in C++17
4047a984708SDavid Chisnall    template<Allocator Alloc>
405aed8d94eSDimitry Andric      function(allocator_arg_t, const Alloc&, nullptr_t) noexcept; // removed in C++17
4067a984708SDavid Chisnall    template<Allocator Alloc>
407aed8d94eSDimitry Andric      function(allocator_arg_t, const Alloc&, const function&);    // removed in C++17
4087a984708SDavid Chisnall    template<Allocator Alloc>
409aed8d94eSDimitry Andric      function(allocator_arg_t, const Alloc&, function&&);         // removed in C++17
4107a984708SDavid Chisnall    template<class F, Allocator Alloc>
411aed8d94eSDimitry Andric      function(allocator_arg_t, const Alloc&, F);                  // removed in C++17
4127a984708SDavid Chisnall
4137a984708SDavid Chisnall    function& operator=(const function&);
4147a984708SDavid Chisnall    function& operator=(function&&) noexcept;
4157a984708SDavid Chisnall    function& operator=(nullptr_t) noexcept;
4167a984708SDavid Chisnall    template<class F>
4177a984708SDavid Chisnall      function& operator=(F&&);
4187a984708SDavid Chisnall    template<class F>
4197a984708SDavid Chisnall      function& operator=(reference_wrapper<F>) noexcept;
4207a984708SDavid Chisnall
4217a984708SDavid Chisnall    ~function();
4227a984708SDavid Chisnall
4237a984708SDavid Chisnall    // function modifiers:
4247a984708SDavid Chisnall    void swap(function&) noexcept;
4257a984708SDavid Chisnall    template<class F, class Alloc>
4267c82a1ecSDimitry Andric      void assign(F&&, const Alloc&);                 // Removed in C++17
4277a984708SDavid Chisnall
4287a984708SDavid Chisnall    // function capacity:
4297a984708SDavid Chisnall    explicit operator bool() const noexcept;
4307a984708SDavid Chisnall
4317a984708SDavid Chisnall    // function invocation:
4327a984708SDavid Chisnall    R operator()(ArgTypes...) const;
4337a984708SDavid Chisnall
4347a984708SDavid Chisnall    // function target access:
4357a984708SDavid Chisnall    const std::type_info& target_type() const noexcept;
4367a984708SDavid Chisnall    template <typename T>       T* target() noexcept;
4377a984708SDavid Chisnall    template <typename T> const T* target() const noexcept;
4387a984708SDavid Chisnall};
4397a984708SDavid Chisnall
4407a984708SDavid Chisnall// Null pointer comparisons:
4417a984708SDavid Chisnalltemplate <class R, class ... ArgTypes>
4427a984708SDavid Chisnall  bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
4437a984708SDavid Chisnall
4447a984708SDavid Chisnalltemplate <class R, class ... ArgTypes>
4457a984708SDavid Chisnall  bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
4467a984708SDavid Chisnall
4477a984708SDavid Chisnalltemplate <class R, class ... ArgTypes>
4487a984708SDavid Chisnall  bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
4497a984708SDavid Chisnall
4507a984708SDavid Chisnalltemplate <class  R, class ... ArgTypes>
4517a984708SDavid Chisnall  bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
4527a984708SDavid Chisnall
4537a984708SDavid Chisnall// specialized algorithms:
4547a984708SDavid Chisnalltemplate <class  R, class ... ArgTypes>
4557a984708SDavid Chisnall  void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;
4567a984708SDavid Chisnall
4577a984708SDavid Chisnalltemplate <class T> struct hash;
4587a984708SDavid Chisnall
4597a984708SDavid Chisnalltemplate <> struct hash<bool>;
4607a984708SDavid Chisnalltemplate <> struct hash<char>;
4617a984708SDavid Chisnalltemplate <> struct hash<signed char>;
4627a984708SDavid Chisnalltemplate <> struct hash<unsigned char>;
4637a984708SDavid Chisnalltemplate <> struct hash<char16_t>;
4647a984708SDavid Chisnalltemplate <> struct hash<char32_t>;
4657a984708SDavid Chisnalltemplate <> struct hash<wchar_t>;
4667a984708SDavid Chisnalltemplate <> struct hash<short>;
4677a984708SDavid Chisnalltemplate <> struct hash<unsigned short>;
4687a984708SDavid Chisnalltemplate <> struct hash<int>;
4697a984708SDavid Chisnalltemplate <> struct hash<unsigned int>;
4707a984708SDavid Chisnalltemplate <> struct hash<long>;
4717a984708SDavid Chisnalltemplate <> struct hash<long long>;
4727a984708SDavid Chisnalltemplate <> struct hash<unsigned long>;
4737a984708SDavid Chisnalltemplate <> struct hash<unsigned long long>;
4747a984708SDavid Chisnall
4757a984708SDavid Chisnalltemplate <> struct hash<float>;
4767a984708SDavid Chisnalltemplate <> struct hash<double>;
4777a984708SDavid Chisnalltemplate <> struct hash<long double>;
4787a984708SDavid Chisnall
4797a984708SDavid Chisnalltemplate<class T> struct hash<T*>;
480540d2a8bSDimitry Andrictemplate <> struct hash<nullptr_t>;  // C++17
4817a984708SDavid Chisnall
4827a984708SDavid Chisnall}  // std
4837a984708SDavid Chisnall
4847a984708SDavid ChisnallPOLICY:  For non-variadic implementations, the number of arguments is limited
4857a984708SDavid Chisnall         to 3.  It is hoped that the need for non-variadic implementations
4867a984708SDavid Chisnall         will be minimal.
4877a984708SDavid Chisnall
4887a984708SDavid Chisnall*/
4897a984708SDavid Chisnall
4907a984708SDavid Chisnall#include <__config>
4917a984708SDavid Chisnall#include <type_traits>
4927a984708SDavid Chisnall#include <typeinfo>
4937a984708SDavid Chisnall#include <exception>
4947a984708SDavid Chisnall#include <memory>
4957a984708SDavid Chisnall#include <tuple>
496540d2a8bSDimitry Andric#include <utility>
497*b5893f02SDimitry Andric#include <version>
4987a984708SDavid Chisnall
4997a984708SDavid Chisnall#include <__functional_base>
5007a984708SDavid Chisnall
5017a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5027a984708SDavid Chisnall#pragma GCC system_header
5037a984708SDavid Chisnall#endif
5047a984708SDavid Chisnall
5057a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD
5067a984708SDavid Chisnall
5074f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
5084f7ab58eSDimitry Andrictemplate <class _Tp = void>
5094f7ab58eSDimitry Andric#else
5107a984708SDavid Chisnalltemplate <class _Tp>
5114f7ab58eSDimitry Andric#endif
512aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS plus : binary_function<_Tp, _Tp, _Tp>
5137a984708SDavid Chisnall{
5144f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
5154f7ab58eSDimitry Andric    _Tp operator()(const _Tp& __x, const _Tp& __y) const
5167a984708SDavid Chisnall        {return __x + __y;}
5177a984708SDavid Chisnall};
5187a984708SDavid Chisnall
5194f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
5204f7ab58eSDimitry Andrictemplate <>
521aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS plus<void>
5227a984708SDavid Chisnall{
5234f7ab58eSDimitry Andric    template <class _T1, class _T2>
5244f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
5254f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
526854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)))
527854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))
5284f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }
5294f7ab58eSDimitry Andric    typedef void is_transparent;
5304f7ab58eSDimitry Andric};
5314f7ab58eSDimitry Andric#endif
5324f7ab58eSDimitry Andric
5334f7ab58eSDimitry Andric
5344f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
5354f7ab58eSDimitry Andrictemplate <class _Tp = void>
5364f7ab58eSDimitry Andric#else
5374f7ab58eSDimitry Andrictemplate <class _Tp>
5384f7ab58eSDimitry Andric#endif
539aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS minus : binary_function<_Tp, _Tp, _Tp>
5404f7ab58eSDimitry Andric{
5414f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
5424f7ab58eSDimitry Andric    _Tp operator()(const _Tp& __x, const _Tp& __y) const
5437a984708SDavid Chisnall        {return __x - __y;}
5447a984708SDavid Chisnall};
5457a984708SDavid Chisnall
5464f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
5474f7ab58eSDimitry Andrictemplate <>
548aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS minus<void>
5497a984708SDavid Chisnall{
5504f7ab58eSDimitry Andric    template <class _T1, class _T2>
5514f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
5524f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
553854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u)))
554854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u))
5554f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); }
5564f7ab58eSDimitry Andric    typedef void is_transparent;
5574f7ab58eSDimitry Andric};
5584f7ab58eSDimitry Andric#endif
5594f7ab58eSDimitry Andric
5604f7ab58eSDimitry Andric
5614f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
5624f7ab58eSDimitry Andrictemplate <class _Tp = void>
5634f7ab58eSDimitry Andric#else
5644f7ab58eSDimitry Andrictemplate <class _Tp>
5654f7ab58eSDimitry Andric#endif
566aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS multiplies : binary_function<_Tp, _Tp, _Tp>
5674f7ab58eSDimitry Andric{
5684f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
5694f7ab58eSDimitry Andric    _Tp operator()(const _Tp& __x, const _Tp& __y) const
5707a984708SDavid Chisnall        {return __x * __y;}
5717a984708SDavid Chisnall};
5727a984708SDavid Chisnall
5734f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
5744f7ab58eSDimitry Andrictemplate <>
575aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS multiplies<void>
5767a984708SDavid Chisnall{
5774f7ab58eSDimitry Andric    template <class _T1, class _T2>
5784f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
5794f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
580854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u)))
581854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u))
5824f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); }
5834f7ab58eSDimitry Andric    typedef void is_transparent;
5844f7ab58eSDimitry Andric};
5854f7ab58eSDimitry Andric#endif
5864f7ab58eSDimitry Andric
5874f7ab58eSDimitry Andric
5884f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
5894f7ab58eSDimitry Andrictemplate <class _Tp = void>
5904f7ab58eSDimitry Andric#else
5914f7ab58eSDimitry Andrictemplate <class _Tp>
5924f7ab58eSDimitry Andric#endif
593aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS divides : binary_function<_Tp, _Tp, _Tp>
5944f7ab58eSDimitry Andric{
5954f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
5964f7ab58eSDimitry Andric    _Tp operator()(const _Tp& __x, const _Tp& __y) const
5977a984708SDavid Chisnall        {return __x / __y;}
5987a984708SDavid Chisnall};
5997a984708SDavid Chisnall
6004f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
6014f7ab58eSDimitry Andrictemplate <>
602aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS divides<void>
6037a984708SDavid Chisnall{
6044f7ab58eSDimitry Andric    template <class _T1, class _T2>
6054f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
6064f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
607854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u)))
608854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u))
6094f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); }
6104f7ab58eSDimitry Andric    typedef void is_transparent;
6114f7ab58eSDimitry Andric};
6124f7ab58eSDimitry Andric#endif
6134f7ab58eSDimitry Andric
6144f7ab58eSDimitry Andric
6154f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
6164f7ab58eSDimitry Andrictemplate <class _Tp = void>
6174f7ab58eSDimitry Andric#else
6184f7ab58eSDimitry Andrictemplate <class _Tp>
6194f7ab58eSDimitry Andric#endif
620aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS modulus : binary_function<_Tp, _Tp, _Tp>
6214f7ab58eSDimitry Andric{
6224f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
6234f7ab58eSDimitry Andric    _Tp operator()(const _Tp& __x, const _Tp& __y) const
6247a984708SDavid Chisnall        {return __x % __y;}
6257a984708SDavid Chisnall};
6267a984708SDavid Chisnall
6274f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
6284f7ab58eSDimitry Andrictemplate <>
629aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS modulus<void>
6307a984708SDavid Chisnall{
6314f7ab58eSDimitry Andric    template <class _T1, class _T2>
6324f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
6334f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
634854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u)))
635854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u))
6364f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); }
6374f7ab58eSDimitry Andric    typedef void is_transparent;
6384f7ab58eSDimitry Andric};
6394f7ab58eSDimitry Andric#endif
6404f7ab58eSDimitry Andric
6414f7ab58eSDimitry Andric
6424f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
6434f7ab58eSDimitry Andrictemplate <class _Tp = void>
6444f7ab58eSDimitry Andric#else
6454f7ab58eSDimitry Andrictemplate <class _Tp>
6464f7ab58eSDimitry Andric#endif
647aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS negate : unary_function<_Tp, _Tp>
6484f7ab58eSDimitry Andric{
6494f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
6504f7ab58eSDimitry Andric    _Tp operator()(const _Tp& __x) const
6517a984708SDavid Chisnall        {return -__x;}
6527a984708SDavid Chisnall};
6537a984708SDavid Chisnall
6544f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
6554f7ab58eSDimitry Andrictemplate <>
656aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS negate<void>
6577a984708SDavid Chisnall{
6584f7ab58eSDimitry Andric    template <class _Tp>
6594f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
6604f7ab58eSDimitry Andric    auto operator()(_Tp&& __x) const
661854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(- _VSTD::forward<_Tp>(__x)))
662854fa44bSDimitry Andric    -> decltype        (- _VSTD::forward<_Tp>(__x))
6634f7ab58eSDimitry Andric        { return        - _VSTD::forward<_Tp>(__x); }
6644f7ab58eSDimitry Andric    typedef void is_transparent;
6654f7ab58eSDimitry Andric};
6664f7ab58eSDimitry Andric#endif
6674f7ab58eSDimitry Andric
6684f7ab58eSDimitry Andric
6694f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
6704f7ab58eSDimitry Andrictemplate <class _Tp = void>
6714f7ab58eSDimitry Andric#else
6724f7ab58eSDimitry Andrictemplate <class _Tp>
6734f7ab58eSDimitry Andric#endif
674aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS equal_to : binary_function<_Tp, _Tp, bool>
6754f7ab58eSDimitry Andric{
6764f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
6774f7ab58eSDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
6787a984708SDavid Chisnall        {return __x == __y;}
6797a984708SDavid Chisnall};
6807a984708SDavid Chisnall
6814f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
6824f7ab58eSDimitry Andrictemplate <>
683aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS equal_to<void>
6847a984708SDavid Chisnall{
6854f7ab58eSDimitry Andric    template <class _T1, class _T2>
6864f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
6874f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
688854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u)))
689854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u))
6904f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); }
6914f7ab58eSDimitry Andric    typedef void is_transparent;
6924f7ab58eSDimitry Andric};
6934f7ab58eSDimitry Andric#endif
6944f7ab58eSDimitry Andric
6954f7ab58eSDimitry Andric
6964f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
6974f7ab58eSDimitry Andrictemplate <class _Tp = void>
6984f7ab58eSDimitry Andric#else
6994f7ab58eSDimitry Andrictemplate <class _Tp>
7004f7ab58eSDimitry Andric#endif
701aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS not_equal_to : binary_function<_Tp, _Tp, bool>
7024f7ab58eSDimitry Andric{
7034f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
7044f7ab58eSDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
7057a984708SDavid Chisnall        {return __x != __y;}
7067a984708SDavid Chisnall};
7077a984708SDavid Chisnall
7084f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
7094f7ab58eSDimitry Andrictemplate <>
710aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS not_equal_to<void>
7117a984708SDavid Chisnall{
7124f7ab58eSDimitry Andric    template <class _T1, class _T2>
7134f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
7144f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
715854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u)))
716854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u))
7174f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); }
7184f7ab58eSDimitry Andric    typedef void is_transparent;
7194f7ab58eSDimitry Andric};
7204f7ab58eSDimitry Andric#endif
7214f7ab58eSDimitry Andric
7224f7ab58eSDimitry Andric
7234f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
7244f7ab58eSDimitry Andrictemplate <class _Tp = void>
7254f7ab58eSDimitry Andric#else
7264f7ab58eSDimitry Andrictemplate <class _Tp>
7274f7ab58eSDimitry Andric#endif
728aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS greater : binary_function<_Tp, _Tp, bool>
7294f7ab58eSDimitry Andric{
7304f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
7314f7ab58eSDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
7327a984708SDavid Chisnall        {return __x > __y;}
7337a984708SDavid Chisnall};
7347a984708SDavid Chisnall
7354f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
7364f7ab58eSDimitry Andrictemplate <>
737aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS greater<void>
7384f7ab58eSDimitry Andric{
7394f7ab58eSDimitry Andric    template <class _T1, class _T2>
7404f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
7414f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
742854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u)))
743854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u))
7444f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); }
7454f7ab58eSDimitry Andric    typedef void is_transparent;
7464f7ab58eSDimitry Andric};
7474f7ab58eSDimitry Andric#endif
7484f7ab58eSDimitry Andric
7494f7ab58eSDimitry Andric
75094e3ee44SDavid Chisnall// less in <__functional_base>
7517a984708SDavid Chisnall
7524f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
7534f7ab58eSDimitry Andrictemplate <class _Tp = void>
7544f7ab58eSDimitry Andric#else
7557a984708SDavid Chisnalltemplate <class _Tp>
7564f7ab58eSDimitry Andric#endif
757aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS greater_equal : binary_function<_Tp, _Tp, bool>
7587a984708SDavid Chisnall{
7594f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
7604f7ab58eSDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
7617a984708SDavid Chisnall        {return __x >= __y;}
7627a984708SDavid Chisnall};
7637a984708SDavid Chisnall
7644f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
7654f7ab58eSDimitry Andrictemplate <>
766aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS greater_equal<void>
7677a984708SDavid Chisnall{
7684f7ab58eSDimitry Andric    template <class _T1, class _T2>
7694f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
7704f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
771854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u)))
772854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u))
7734f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); }
7744f7ab58eSDimitry Andric    typedef void is_transparent;
7754f7ab58eSDimitry Andric};
7764f7ab58eSDimitry Andric#endif
7774f7ab58eSDimitry Andric
7784f7ab58eSDimitry Andric
7794f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
7804f7ab58eSDimitry Andrictemplate <class _Tp = void>
7814f7ab58eSDimitry Andric#else
7824f7ab58eSDimitry Andrictemplate <class _Tp>
7834f7ab58eSDimitry Andric#endif
784aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS less_equal : binary_function<_Tp, _Tp, bool>
7854f7ab58eSDimitry Andric{
7864f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
7874f7ab58eSDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
7887a984708SDavid Chisnall        {return __x <= __y;}
7897a984708SDavid Chisnall};
7907a984708SDavid Chisnall
7914f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
7924f7ab58eSDimitry Andrictemplate <>
793aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS less_equal<void>
7947a984708SDavid Chisnall{
7954f7ab58eSDimitry Andric    template <class _T1, class _T2>
7964f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
7974f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
798854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u)))
799854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u))
8004f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); }
8014f7ab58eSDimitry Andric    typedef void is_transparent;
8024f7ab58eSDimitry Andric};
8034f7ab58eSDimitry Andric#endif
8044f7ab58eSDimitry Andric
8054f7ab58eSDimitry Andric
8064f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
8074f7ab58eSDimitry Andrictemplate <class _Tp = void>
8084f7ab58eSDimitry Andric#else
8094f7ab58eSDimitry Andrictemplate <class _Tp>
8104f7ab58eSDimitry Andric#endif
811aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS logical_and : binary_function<_Tp, _Tp, bool>
8124f7ab58eSDimitry Andric{
8134f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
8144f7ab58eSDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
8157a984708SDavid Chisnall        {return __x && __y;}
8167a984708SDavid Chisnall};
8177a984708SDavid Chisnall
8184f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
8194f7ab58eSDimitry Andrictemplate <>
820aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS logical_and<void>
8217a984708SDavid Chisnall{
8224f7ab58eSDimitry Andric    template <class _T1, class _T2>
8234f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
8244f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
825854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u)))
826854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u))
8274f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); }
8284f7ab58eSDimitry Andric    typedef void is_transparent;
8294f7ab58eSDimitry Andric};
8304f7ab58eSDimitry Andric#endif
8314f7ab58eSDimitry Andric
8324f7ab58eSDimitry Andric
8334f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
8344f7ab58eSDimitry Andrictemplate <class _Tp = void>
8354f7ab58eSDimitry Andric#else
8364f7ab58eSDimitry Andrictemplate <class _Tp>
8374f7ab58eSDimitry Andric#endif
838aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS logical_or : binary_function<_Tp, _Tp, bool>
8394f7ab58eSDimitry Andric{
8404f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
8414f7ab58eSDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
8427a984708SDavid Chisnall        {return __x || __y;}
8437a984708SDavid Chisnall};
8447a984708SDavid Chisnall
8454f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
8464f7ab58eSDimitry Andrictemplate <>
847aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS logical_or<void>
8487a984708SDavid Chisnall{
8494f7ab58eSDimitry Andric    template <class _T1, class _T2>
8504f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
8514f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
852854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u)))
853854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u))
8544f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); }
8554f7ab58eSDimitry Andric    typedef void is_transparent;
8564f7ab58eSDimitry Andric};
8574f7ab58eSDimitry Andric#endif
8584f7ab58eSDimitry Andric
8594f7ab58eSDimitry Andric
8604f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
8614f7ab58eSDimitry Andrictemplate <class _Tp = void>
8624f7ab58eSDimitry Andric#else
8634f7ab58eSDimitry Andrictemplate <class _Tp>
8644f7ab58eSDimitry Andric#endif
865aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS logical_not : unary_function<_Tp, bool>
8664f7ab58eSDimitry Andric{
8674f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
8684f7ab58eSDimitry Andric    bool operator()(const _Tp& __x) const
8697a984708SDavid Chisnall        {return !__x;}
8707a984708SDavid Chisnall};
8717a984708SDavid Chisnall
8724f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
8734f7ab58eSDimitry Andrictemplate <>
874aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS logical_not<void>
8757a984708SDavid Chisnall{
8764f7ab58eSDimitry Andric    template <class _Tp>
8774f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
8784f7ab58eSDimitry Andric    auto operator()(_Tp&& __x) const
879854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(!_VSTD::forward<_Tp>(__x)))
880854fa44bSDimitry Andric    -> decltype        (!_VSTD::forward<_Tp>(__x))
8814f7ab58eSDimitry Andric        { return        !_VSTD::forward<_Tp>(__x); }
8824f7ab58eSDimitry Andric    typedef void is_transparent;
8834f7ab58eSDimitry Andric};
8844f7ab58eSDimitry Andric#endif
8854f7ab58eSDimitry Andric
8864f7ab58eSDimitry Andric
8874f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
8884f7ab58eSDimitry Andrictemplate <class _Tp = void>
8894f7ab58eSDimitry Andric#else
8904f7ab58eSDimitry Andrictemplate <class _Tp>
8914f7ab58eSDimitry Andric#endif
892aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS bit_and : binary_function<_Tp, _Tp, _Tp>
8934f7ab58eSDimitry Andric{
8944f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
8954f7ab58eSDimitry Andric    _Tp operator()(const _Tp& __x, const _Tp& __y) const
8967a984708SDavid Chisnall        {return __x & __y;}
8977a984708SDavid Chisnall};
8987a984708SDavid Chisnall
8994f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
9004f7ab58eSDimitry Andrictemplate <>
901aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS bit_and<void>
9027a984708SDavid Chisnall{
9034f7ab58eSDimitry Andric    template <class _T1, class _T2>
9044f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
9054f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
906854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u)))
907854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u))
9084f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); }
9094f7ab58eSDimitry Andric    typedef void is_transparent;
9104f7ab58eSDimitry Andric};
9114f7ab58eSDimitry Andric#endif
9124f7ab58eSDimitry Andric
9134f7ab58eSDimitry Andric
9144f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
9154f7ab58eSDimitry Andrictemplate <class _Tp = void>
9164f7ab58eSDimitry Andric#else
9174f7ab58eSDimitry Andrictemplate <class _Tp>
9184f7ab58eSDimitry Andric#endif
919aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS bit_or : binary_function<_Tp, _Tp, _Tp>
9204f7ab58eSDimitry Andric{
9214f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
9224f7ab58eSDimitry Andric    _Tp operator()(const _Tp& __x, const _Tp& __y) const
9237a984708SDavid Chisnall        {return __x | __y;}
9247a984708SDavid Chisnall};
9257a984708SDavid Chisnall
9264f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
9274f7ab58eSDimitry Andrictemplate <>
928aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS bit_or<void>
9297a984708SDavid Chisnall{
9304f7ab58eSDimitry Andric    template <class _T1, class _T2>
9314f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
9324f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
933854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u)))
934854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u))
9354f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); }
9364f7ab58eSDimitry Andric    typedef void is_transparent;
9374f7ab58eSDimitry Andric};
9384f7ab58eSDimitry Andric#endif
9394f7ab58eSDimitry Andric
9404f7ab58eSDimitry Andric
9414f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
9424f7ab58eSDimitry Andrictemplate <class _Tp = void>
9434f7ab58eSDimitry Andric#else
9444f7ab58eSDimitry Andrictemplate <class _Tp>
9454f7ab58eSDimitry Andric#endif
946aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS bit_xor : binary_function<_Tp, _Tp, _Tp>
9474f7ab58eSDimitry Andric{
9484f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
9494f7ab58eSDimitry Andric    _Tp operator()(const _Tp& __x, const _Tp& __y) const
9507a984708SDavid Chisnall        {return __x ^ __y;}
9517a984708SDavid Chisnall};
9527a984708SDavid Chisnall
9534f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
9544f7ab58eSDimitry Andrictemplate <>
955aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS bit_xor<void>
9564f7ab58eSDimitry Andric{
9574f7ab58eSDimitry Andric    template <class _T1, class _T2>
9584f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
9594f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
960854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u)))
961854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u))
9624f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); }
9634f7ab58eSDimitry Andric    typedef void is_transparent;
9644f7ab58eSDimitry Andric};
9654f7ab58eSDimitry Andric#endif
9664f7ab58eSDimitry Andric
9674f7ab58eSDimitry Andric
9684f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
9694f7ab58eSDimitry Andrictemplate <class _Tp = void>
970aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS bit_not : unary_function<_Tp, _Tp>
9714f7ab58eSDimitry Andric{
9724f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
9734f7ab58eSDimitry Andric    _Tp operator()(const _Tp& __x) const
9744f7ab58eSDimitry Andric        {return ~__x;}
9754f7ab58eSDimitry Andric};
9764f7ab58eSDimitry Andric
9774f7ab58eSDimitry Andrictemplate <>
978aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS bit_not<void>
9794f7ab58eSDimitry Andric{
9804f7ab58eSDimitry Andric    template <class _Tp>
9814f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
9824f7ab58eSDimitry Andric    auto operator()(_Tp&& __x) const
983854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(~_VSTD::forward<_Tp>(__x)))
984854fa44bSDimitry Andric    -> decltype        (~_VSTD::forward<_Tp>(__x))
9854f7ab58eSDimitry Andric        { return        ~_VSTD::forward<_Tp>(__x); }
9864f7ab58eSDimitry Andric    typedef void is_transparent;
9874f7ab58eSDimitry Andric};
9884f7ab58eSDimitry Andric#endif
9894f7ab58eSDimitry Andric
9907a984708SDavid Chisnalltemplate <class _Predicate>
991*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate
9927a984708SDavid Chisnall    : public unary_function<typename _Predicate::argument_type, bool>
9937a984708SDavid Chisnall{
9947a984708SDavid Chisnall    _Predicate __pred_;
9957a984708SDavid Chisnallpublic:
9964f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
9974f7ab58eSDimitry Andric    explicit unary_negate(const _Predicate& __pred)
9987a984708SDavid Chisnall        : __pred_(__pred) {}
9994f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
10004f7ab58eSDimitry Andric    bool operator()(const typename _Predicate::argument_type& __x) const
10017a984708SDavid Chisnall        {return !__pred_(__x);}
10027a984708SDavid Chisnall};
10037a984708SDavid Chisnall
10047a984708SDavid Chisnalltemplate <class _Predicate>
1005*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
10067a984708SDavid Chisnallunary_negate<_Predicate>
10077a984708SDavid Chisnallnot1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);}
10087a984708SDavid Chisnall
10097a984708SDavid Chisnalltemplate <class _Predicate>
1010*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate
10117a984708SDavid Chisnall    : public binary_function<typename _Predicate::first_argument_type,
10127a984708SDavid Chisnall                             typename _Predicate::second_argument_type,
10137a984708SDavid Chisnall                             bool>
10147a984708SDavid Chisnall{
10157a984708SDavid Chisnall    _Predicate __pred_;
10167a984708SDavid Chisnallpublic:
10174f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11
10184f7ab58eSDimitry Andric    binary_negate(const _Predicate& __pred) : __pred_(__pred) {}
10194f7ab58eSDimitry Andric
10204f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
10214f7ab58eSDimitry Andric    bool operator()(const typename _Predicate::first_argument_type& __x,
10227a984708SDavid Chisnall                    const typename _Predicate::second_argument_type& __y) const
10237a984708SDavid Chisnall        {return !__pred_(__x, __y);}
10247a984708SDavid Chisnall};
10257a984708SDavid Chisnall
10267a984708SDavid Chisnalltemplate <class _Predicate>
1027*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
10287a984708SDavid Chisnallbinary_negate<_Predicate>
10297a984708SDavid Chisnallnot2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);}
10307a984708SDavid Chisnall
1031540d2a8bSDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
10327a984708SDavid Chisnalltemplate <class __Operation>
1033*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st
10347a984708SDavid Chisnall    : public unary_function<typename __Operation::second_argument_type,
10357a984708SDavid Chisnall                            typename __Operation::result_type>
10367a984708SDavid Chisnall{
10377a984708SDavid Chisnallprotected:
10387a984708SDavid Chisnall    __Operation                               op;
10397a984708SDavid Chisnall    typename __Operation::first_argument_type value;
10407a984708SDavid Chisnallpublic:
10417a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x,
10427a984708SDavid Chisnall                               const typename __Operation::first_argument_type __y)
10437a984708SDavid Chisnall        : op(__x), value(__y) {}
10447a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
10457a984708SDavid Chisnall        (typename __Operation::second_argument_type& __x) const
10467a984708SDavid Chisnall            {return op(value, __x);}
10477a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
10487a984708SDavid Chisnall        (const typename __Operation::second_argument_type& __x) const
10497a984708SDavid Chisnall            {return op(value, __x);}
10507a984708SDavid Chisnall};
10517a984708SDavid Chisnall
10527a984708SDavid Chisnalltemplate <class __Operation, class _Tp>
1053*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
10547a984708SDavid Chisnallbinder1st<__Operation>
10557a984708SDavid Chisnallbind1st(const __Operation& __op, const _Tp& __x)
10567a984708SDavid Chisnall    {return binder1st<__Operation>(__op, __x);}
10577a984708SDavid Chisnall
10587a984708SDavid Chisnalltemplate <class __Operation>
1059*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd
10607a984708SDavid Chisnall    : public unary_function<typename __Operation::first_argument_type,
10617a984708SDavid Chisnall                            typename __Operation::result_type>
10627a984708SDavid Chisnall{
10637a984708SDavid Chisnallprotected:
10647a984708SDavid Chisnall    __Operation                                op;
10657a984708SDavid Chisnall    typename __Operation::second_argument_type value;
10667a984708SDavid Chisnallpublic:
10677a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
10687a984708SDavid Chisnall    binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y)
10697a984708SDavid Chisnall        : op(__x), value(__y) {}
10707a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
10717a984708SDavid Chisnall        (      typename __Operation::first_argument_type& __x) const
10727a984708SDavid Chisnall            {return op(__x, value);}
10737a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
10747a984708SDavid Chisnall        (const typename __Operation::first_argument_type& __x) const
10757a984708SDavid Chisnall            {return op(__x, value);}
10767a984708SDavid Chisnall};
10777a984708SDavid Chisnall
10787a984708SDavid Chisnalltemplate <class __Operation, class _Tp>
1079*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
10807a984708SDavid Chisnallbinder2nd<__Operation>
10817a984708SDavid Chisnallbind2nd(const __Operation& __op, const _Tp& __x)
10827a984708SDavid Chisnall    {return binder2nd<__Operation>(__op, __x);}
10837a984708SDavid Chisnall
10847a984708SDavid Chisnalltemplate <class _Arg, class _Result>
1085*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function
10867a984708SDavid Chisnall    : public unary_function<_Arg, _Result>
10877a984708SDavid Chisnall{
10887a984708SDavid Chisnall    _Result (*__f_)(_Arg);
10897a984708SDavid Chisnallpublic:
10907a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit pointer_to_unary_function(_Result (*__f)(_Arg))
10917a984708SDavid Chisnall        : __f_(__f) {}
10927a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg __x) const
10937a984708SDavid Chisnall        {return __f_(__x);}
10947a984708SDavid Chisnall};
10957a984708SDavid Chisnall
10967a984708SDavid Chisnalltemplate <class _Arg, class _Result>
1097*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
10987a984708SDavid Chisnallpointer_to_unary_function<_Arg,_Result>
10997a984708SDavid Chisnallptr_fun(_Result (*__f)(_Arg))
11007a984708SDavid Chisnall    {return pointer_to_unary_function<_Arg,_Result>(__f);}
11017a984708SDavid Chisnall
11027a984708SDavid Chisnalltemplate <class _Arg1, class _Arg2, class _Result>
1103*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function
11047a984708SDavid Chisnall    : public binary_function<_Arg1, _Arg2, _Result>
11057a984708SDavid Chisnall{
11067a984708SDavid Chisnall    _Result (*__f_)(_Arg1, _Arg2);
11077a984708SDavid Chisnallpublic:
11087a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2))
11097a984708SDavid Chisnall        : __f_(__f) {}
11107a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg1 __x, _Arg2 __y) const
11117a984708SDavid Chisnall        {return __f_(__x, __y);}
11127a984708SDavid Chisnall};
11137a984708SDavid Chisnall
11147a984708SDavid Chisnalltemplate <class _Arg1, class _Arg2, class _Result>
1115*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
11167a984708SDavid Chisnallpointer_to_binary_function<_Arg1,_Arg2,_Result>
11177a984708SDavid Chisnallptr_fun(_Result (*__f)(_Arg1,_Arg2))
11187a984708SDavid Chisnall    {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);}
11197a984708SDavid Chisnall
11207a984708SDavid Chisnalltemplate<class _Sp, class _Tp>
1121*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t
1122*b5893f02SDimitry Andric    : public unary_function<_Tp*, _Sp>
11237a984708SDavid Chisnall{
11247a984708SDavid Chisnall    _Sp (_Tp::*__p_)();
11257a984708SDavid Chisnallpublic:
11267a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit mem_fun_t(_Sp (_Tp::*__p)())
11277a984708SDavid Chisnall        : __p_(__p) {}
11287a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p) const
11297a984708SDavid Chisnall        {return (__p->*__p_)();}
11307a984708SDavid Chisnall};
11317a984708SDavid Chisnall
11327a984708SDavid Chisnalltemplate<class _Sp, class _Tp, class _Ap>
1133*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t
1134*b5893f02SDimitry Andric    : public binary_function<_Tp*, _Ap, _Sp>
11357a984708SDavid Chisnall{
11367a984708SDavid Chisnall    _Sp (_Tp::*__p_)(_Ap);
11377a984708SDavid Chisnallpublic:
11387a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap))
11397a984708SDavid Chisnall        : __p_(__p) {}
11407a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p, _Ap __x) const
11417a984708SDavid Chisnall        {return (__p->*__p_)(__x);}
11427a984708SDavid Chisnall};
11437a984708SDavid Chisnall
11447a984708SDavid Chisnalltemplate<class _Sp, class _Tp>
1145*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
11467a984708SDavid Chisnallmem_fun_t<_Sp,_Tp>
11477a984708SDavid Chisnallmem_fun(_Sp (_Tp::*__f)())
11487a984708SDavid Chisnall    {return mem_fun_t<_Sp,_Tp>(__f);}
11497a984708SDavid Chisnall
11507a984708SDavid Chisnalltemplate<class _Sp, class _Tp, class _Ap>
1151*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
11527a984708SDavid Chisnallmem_fun1_t<_Sp,_Tp,_Ap>
11537a984708SDavid Chisnallmem_fun(_Sp (_Tp::*__f)(_Ap))
11547a984708SDavid Chisnall    {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
11557a984708SDavid Chisnall
11567a984708SDavid Chisnalltemplate<class _Sp, class _Tp>
1157*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t
1158*b5893f02SDimitry Andric    : public unary_function<_Tp, _Sp>
11597a984708SDavid Chisnall{
11607a984708SDavid Chisnall    _Sp (_Tp::*__p_)();
11617a984708SDavid Chisnallpublic:
11627a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit mem_fun_ref_t(_Sp (_Tp::*__p)())
11637a984708SDavid Chisnall        : __p_(__p) {}
11647a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p) const
11657a984708SDavid Chisnall        {return (__p.*__p_)();}
11667a984708SDavid Chisnall};
11677a984708SDavid Chisnall
11687a984708SDavid Chisnalltemplate<class _Sp, class _Tp, class _Ap>
1169*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t
1170*b5893f02SDimitry Andric    : public binary_function<_Tp, _Ap, _Sp>
11717a984708SDavid Chisnall{
11727a984708SDavid Chisnall    _Sp (_Tp::*__p_)(_Ap);
11737a984708SDavid Chisnallpublic:
11747a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap))
11757a984708SDavid Chisnall        : __p_(__p) {}
11767a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p, _Ap __x) const
11777a984708SDavid Chisnall        {return (__p.*__p_)(__x);}
11787a984708SDavid Chisnall};
11797a984708SDavid Chisnall
11807a984708SDavid Chisnalltemplate<class _Sp, class _Tp>
1181*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
11827a984708SDavid Chisnallmem_fun_ref_t<_Sp,_Tp>
11837a984708SDavid Chisnallmem_fun_ref(_Sp (_Tp::*__f)())
11847a984708SDavid Chisnall    {return mem_fun_ref_t<_Sp,_Tp>(__f);}
11857a984708SDavid Chisnall
11867a984708SDavid Chisnalltemplate<class _Sp, class _Tp, class _Ap>
1187*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
11887a984708SDavid Chisnallmem_fun1_ref_t<_Sp,_Tp,_Ap>
11897a984708SDavid Chisnallmem_fun_ref(_Sp (_Tp::*__f)(_Ap))
11907a984708SDavid Chisnall    {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
11917a984708SDavid Chisnall
11927a984708SDavid Chisnalltemplate <class _Sp, class _Tp>
1193*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t
1194*b5893f02SDimitry Andric    : public unary_function<const _Tp*, _Sp>
11957a984708SDavid Chisnall{
11967a984708SDavid Chisnall    _Sp (_Tp::*__p_)() const;
11977a984708SDavid Chisnallpublic:
11987a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_t(_Sp (_Tp::*__p)() const)
11997a984708SDavid Chisnall        : __p_(__p) {}
12007a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p) const
12017a984708SDavid Chisnall        {return (__p->*__p_)();}
12027a984708SDavid Chisnall};
12037a984708SDavid Chisnall
12047a984708SDavid Chisnalltemplate <class _Sp, class _Tp, class _Ap>
1205*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t
1206*b5893f02SDimitry Andric    : public binary_function<const _Tp*, _Ap, _Sp>
12077a984708SDavid Chisnall{
12087a984708SDavid Chisnall    _Sp (_Tp::*__p_)(_Ap) const;
12097a984708SDavid Chisnallpublic:
12107a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const)
12117a984708SDavid Chisnall        : __p_(__p) {}
12127a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p, _Ap __x) const
12137a984708SDavid Chisnall        {return (__p->*__p_)(__x);}
12147a984708SDavid Chisnall};
12157a984708SDavid Chisnall
12167a984708SDavid Chisnalltemplate <class _Sp, class _Tp>
1217*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
12187a984708SDavid Chisnallconst_mem_fun_t<_Sp,_Tp>
12197a984708SDavid Chisnallmem_fun(_Sp (_Tp::*__f)() const)
12207a984708SDavid Chisnall    {return const_mem_fun_t<_Sp,_Tp>(__f);}
12217a984708SDavid Chisnall
12227a984708SDavid Chisnalltemplate <class _Sp, class _Tp, class _Ap>
1223*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
12247a984708SDavid Chisnallconst_mem_fun1_t<_Sp,_Tp,_Ap>
12257a984708SDavid Chisnallmem_fun(_Sp (_Tp::*__f)(_Ap) const)
12267a984708SDavid Chisnall    {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
12277a984708SDavid Chisnall
12287a984708SDavid Chisnalltemplate <class _Sp, class _Tp>
1229*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t
1230*b5893f02SDimitry Andric    : public unary_function<_Tp, _Sp>
12317a984708SDavid Chisnall{
12327a984708SDavid Chisnall    _Sp (_Tp::*__p_)() const;
12337a984708SDavid Chisnallpublic:
12347a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const)
12357a984708SDavid Chisnall        : __p_(__p) {}
12367a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p) const
12377a984708SDavid Chisnall        {return (__p.*__p_)();}
12387a984708SDavid Chisnall};
12397a984708SDavid Chisnall
12407a984708SDavid Chisnalltemplate <class _Sp, class _Tp, class _Ap>
1241*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t
12427a984708SDavid Chisnall    : public binary_function<_Tp, _Ap, _Sp>
12437a984708SDavid Chisnall{
12447a984708SDavid Chisnall    _Sp (_Tp::*__p_)(_Ap) const;
12457a984708SDavid Chisnallpublic:
12467a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const)
12477a984708SDavid Chisnall        : __p_(__p) {}
12487a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p, _Ap __x) const
12497a984708SDavid Chisnall        {return (__p.*__p_)(__x);}
12507a984708SDavid Chisnall};
12517a984708SDavid Chisnall
12527a984708SDavid Chisnalltemplate <class _Sp, class _Tp>
1253*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
12547a984708SDavid Chisnallconst_mem_fun_ref_t<_Sp,_Tp>
12557a984708SDavid Chisnallmem_fun_ref(_Sp (_Tp::*__f)() const)
12567a984708SDavid Chisnall    {return const_mem_fun_ref_t<_Sp,_Tp>(__f);}
12577a984708SDavid Chisnall
12587a984708SDavid Chisnalltemplate <class _Sp, class _Tp, class _Ap>
1259*b5893f02SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
12607a984708SDavid Chisnallconst_mem_fun1_ref_t<_Sp,_Tp,_Ap>
12617a984708SDavid Chisnallmem_fun_ref(_Sp (_Tp::*__f)(_Ap) const)
12627a984708SDavid Chisnall    {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
1263540d2a8bSDimitry Andric#endif
12647a984708SDavid Chisnall
12659729cf09SDimitry Andric////////////////////////////////////////////////////////////////////////////////
12669729cf09SDimitry Andric//                                MEMFUN
12679729cf09SDimitry Andric//==============================================================================
12687a984708SDavid Chisnall
12697a984708SDavid Chisnalltemplate <class _Tp>
12707a984708SDavid Chisnallclass __mem_fn
12717a984708SDavid Chisnall    : public __weak_result_type<_Tp>
12727a984708SDavid Chisnall{
12737a984708SDavid Chisnallpublic:
12747a984708SDavid Chisnall    // types
12757a984708SDavid Chisnall    typedef _Tp type;
12767a984708SDavid Chisnallprivate:
12777a984708SDavid Chisnall    type __f_;
12787a984708SDavid Chisnall
12797a984708SDavid Chisnallpublic:
12809729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) _NOEXCEPT : __f_(__f) {}
12817a984708SDavid Chisnall
1282540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
12837a984708SDavid Chisnall    // invoke
12847a984708SDavid Chisnall    template <class... _ArgTypes>
12857a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
12867a984708SDavid Chisnall    typename __invoke_return<type, _ArgTypes...>::type
12879729cf09SDimitry Andric    operator() (_ArgTypes&&... __args) const {
12887a984708SDavid Chisnall        return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
12897a984708SDavid Chisnall    }
12909729cf09SDimitry Andric#else
12919729cf09SDimitry Andric
12929729cf09SDimitry Andric    template <class _A0>
12939729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
12949729cf09SDimitry Andric    typename __invoke_return0<type, _A0>::type
12959729cf09SDimitry Andric    operator() (_A0& __a0) const {
12969729cf09SDimitry Andric        return __invoke(__f_, __a0);
12979729cf09SDimitry Andric    }
12989729cf09SDimitry Andric
12999729cf09SDimitry Andric    template <class _A0>
13009729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13019729cf09SDimitry Andric    typename __invoke_return0<type, _A0 const>::type
13029729cf09SDimitry Andric    operator() (_A0 const& __a0) const {
13039729cf09SDimitry Andric        return __invoke(__f_, __a0);
13049729cf09SDimitry Andric    }
13059729cf09SDimitry Andric
13069729cf09SDimitry Andric    template <class _A0, class _A1>
13079729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13089729cf09SDimitry Andric    typename __invoke_return1<type, _A0, _A1>::type
13099729cf09SDimitry Andric    operator() (_A0& __a0, _A1& __a1) const {
13109729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1);
13119729cf09SDimitry Andric    }
13129729cf09SDimitry Andric
13139729cf09SDimitry Andric    template <class _A0, class _A1>
13149729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13159729cf09SDimitry Andric    typename __invoke_return1<type, _A0 const, _A1>::type
13169729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1& __a1) const {
13179729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1);
13189729cf09SDimitry Andric    }
13199729cf09SDimitry Andric
13209729cf09SDimitry Andric    template <class _A0, class _A1>
13219729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13229729cf09SDimitry Andric    typename __invoke_return1<type, _A0, _A1 const>::type
13239729cf09SDimitry Andric    operator() (_A0& __a0, _A1 const& __a1) const {
13249729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1);
13259729cf09SDimitry Andric    }
13269729cf09SDimitry Andric
13279729cf09SDimitry Andric    template <class _A0, class _A1>
13289729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13299729cf09SDimitry Andric    typename __invoke_return1<type, _A0 const, _A1 const>::type
13309729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1 const& __a1) const {
13319729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1);
13329729cf09SDimitry Andric    }
13339729cf09SDimitry Andric
13349729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
13359729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13369729cf09SDimitry Andric    typename __invoke_return2<type, _A0, _A1, _A2>::type
13379729cf09SDimitry Andric    operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
13389729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1, __a2);
13399729cf09SDimitry Andric    }
13409729cf09SDimitry Andric
13419729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
13429729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13439729cf09SDimitry Andric    typename __invoke_return2<type, _A0 const, _A1, _A2>::type
13449729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
13459729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1, __a2);
13469729cf09SDimitry Andric    }
13479729cf09SDimitry Andric
13489729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
13499729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13509729cf09SDimitry Andric    typename __invoke_return2<type, _A0, _A1 const, _A2>::type
13519729cf09SDimitry Andric    operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
13529729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1, __a2);
13539729cf09SDimitry Andric    }
13549729cf09SDimitry Andric
13559729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
13569729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13579729cf09SDimitry Andric    typename __invoke_return2<type, _A0, _A1, _A2 const>::type
13589729cf09SDimitry Andric    operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
13599729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1, __a2);
13609729cf09SDimitry Andric    }
13619729cf09SDimitry Andric
13629729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
13639729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13649729cf09SDimitry Andric    typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
13659729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
13669729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1, __a2);
13679729cf09SDimitry Andric    }
13689729cf09SDimitry Andric
13699729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
13709729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13719729cf09SDimitry Andric    typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
13729729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
13739729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1, __a2);
13749729cf09SDimitry Andric    }
13759729cf09SDimitry Andric
13769729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
13779729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13789729cf09SDimitry Andric    typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
13799729cf09SDimitry Andric    operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
13809729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1, __a2);
13819729cf09SDimitry Andric    }
13829729cf09SDimitry Andric
13839729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
13849729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13859729cf09SDimitry Andric    typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
13869729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
13879729cf09SDimitry Andric        return __invoke(__f_, __a0, __a1, __a2);
13889729cf09SDimitry Andric    }
13899729cf09SDimitry Andric#endif
13907a984708SDavid Chisnall};
13917a984708SDavid Chisnall
139294e3ee44SDavid Chisnalltemplate<class _Rp, class _Tp>
13937a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
139494e3ee44SDavid Chisnall__mem_fn<_Rp _Tp::*>
13959729cf09SDimitry Andricmem_fn(_Rp _Tp::* __pm) _NOEXCEPT
13967a984708SDavid Chisnall{
139794e3ee44SDavid Chisnall    return __mem_fn<_Rp _Tp::*>(__pm);
13987a984708SDavid Chisnall}
13997a984708SDavid Chisnall
14009729cf09SDimitry Andric////////////////////////////////////////////////////////////////////////////////
14019729cf09SDimitry Andric//                                FUNCTION
14029729cf09SDimitry Andric//==============================================================================
14039729cf09SDimitry Andric
14047a984708SDavid Chisnall// bad_function_call
14057a984708SDavid Chisnall
14067a984708SDavid Chisnallclass _LIBCPP_EXCEPTION_ABI bad_function_call
14077a984708SDavid Chisnall    : public exception
14087a984708SDavid Chisnall{
1409540d2a8bSDimitry Andric#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
1410540d2a8bSDimitry Andricpublic:
1411540d2a8bSDimitry Andric    virtual ~bad_function_call() _NOEXCEPT;
1412540d2a8bSDimitry Andric
1413540d2a8bSDimitry Andric    virtual const char* what() const _NOEXCEPT;
1414540d2a8bSDimitry Andric#endif
14157a984708SDavid Chisnall};
14167a984708SDavid Chisnall
14174ba319b5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
1418aed8d94eSDimitry Andricvoid __throw_bad_function_call()
1419aed8d94eSDimitry Andric{
1420aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
1421aed8d94eSDimitry Andric    throw bad_function_call();
1422aed8d94eSDimitry Andric#else
1423aed8d94eSDimitry Andric    _VSTD::abort();
1424aed8d94eSDimitry Andric#endif
1425aed8d94eSDimitry Andric}
1426aed8d94eSDimitry Andric
1427aed8d94eSDimitry Andrictemplate<class _Fp> class _LIBCPP_TEMPLATE_VIS function; // undefined
14287a984708SDavid Chisnall
14297a984708SDavid Chisnallnamespace __function
14307a984708SDavid Chisnall{
14317a984708SDavid Chisnall
14329729cf09SDimitry Andrictemplate<class _Rp>
14337a984708SDavid Chisnallstruct __maybe_derive_from_unary_function
14347a984708SDavid Chisnall{
14357a984708SDavid Chisnall};
14367a984708SDavid Chisnall
143794e3ee44SDavid Chisnalltemplate<class _Rp, class _A1>
143894e3ee44SDavid Chisnallstruct __maybe_derive_from_unary_function<_Rp(_A1)>
143994e3ee44SDavid Chisnall    : public unary_function<_A1, _Rp>
14407a984708SDavid Chisnall{
14417a984708SDavid Chisnall};
14427a984708SDavid Chisnall
14439729cf09SDimitry Andrictemplate<class _Rp>
14447a984708SDavid Chisnallstruct __maybe_derive_from_binary_function
14457a984708SDavid Chisnall{
14467a984708SDavid Chisnall};
14477a984708SDavid Chisnall
144894e3ee44SDavid Chisnalltemplate<class _Rp, class _A1, class _A2>
144994e3ee44SDavid Chisnallstruct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
145094e3ee44SDavid Chisnall    : public binary_function<_A1, _A2, _Rp>
14517a984708SDavid Chisnall{
14527a984708SDavid Chisnall};
14537a984708SDavid Chisnall
14549729cf09SDimitry Andrictemplate <class _Fp>
14559729cf09SDimitry Andric_LIBCPP_INLINE_VISIBILITY
14569729cf09SDimitry Andricbool __not_null(_Fp const&) { return true; }
14579729cf09SDimitry Andric
14589729cf09SDimitry Andrictemplate <class _Fp>
14599729cf09SDimitry Andric_LIBCPP_INLINE_VISIBILITY
14609729cf09SDimitry Andricbool __not_null(_Fp* __ptr) { return __ptr; }
14619729cf09SDimitry Andric
14629729cf09SDimitry Andrictemplate <class _Ret, class _Class>
14639729cf09SDimitry Andric_LIBCPP_INLINE_VISIBILITY
14649729cf09SDimitry Andricbool __not_null(_Ret _Class::*__ptr) { return __ptr; }
14659729cf09SDimitry Andric
14669729cf09SDimitry Andrictemplate <class _Fp>
14679729cf09SDimitry Andric_LIBCPP_INLINE_VISIBILITY
14689729cf09SDimitry Andricbool __not_null(function<_Fp> const& __f) { return !!__f; }
14699729cf09SDimitry Andric
14709729cf09SDimitry Andric} // namespace __function
14719729cf09SDimitry Andric
1472540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
14739729cf09SDimitry Andric
14749729cf09SDimitry Andricnamespace __function {
14759729cf09SDimitry Andric
1476*b5893f02SDimitry Andric// __alloc_func holds a functor and an allocator.
1477*b5893f02SDimitry Andric
1478*b5893f02SDimitry Andrictemplate <class _Fp, class _Ap, class _FB> class __alloc_func;
1479*b5893f02SDimitry Andric
1480*b5893f02SDimitry Andrictemplate <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
1481*b5893f02SDimitry Andricclass __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
1482*b5893f02SDimitry Andric{
1483*b5893f02SDimitry Andric    __compressed_pair<_Fp, _Ap> __f_;
1484*b5893f02SDimitry Andric
1485*b5893f02SDimitry Andric  public:
1486*b5893f02SDimitry Andric    typedef _Fp _Target;
1487*b5893f02SDimitry Andric    typedef _Ap _Alloc;
1488*b5893f02SDimitry Andric
1489*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1490*b5893f02SDimitry Andric    const _Target& __target() const { return __f_.first(); }
1491*b5893f02SDimitry Andric
1492*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1493*b5893f02SDimitry Andric    const _Alloc& __allocator() const { return __f_.second(); }
1494*b5893f02SDimitry Andric
1495*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1496*b5893f02SDimitry Andric    explicit __alloc_func(_Target&& __f)
1497*b5893f02SDimitry Andric        : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
1498*b5893f02SDimitry Andric               _VSTD::forward_as_tuple())
1499*b5893f02SDimitry Andric    {
1500*b5893f02SDimitry Andric    }
1501*b5893f02SDimitry Andric
1502*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1503*b5893f02SDimitry Andric    explicit __alloc_func(const _Target& __f, const _Alloc& __a)
1504*b5893f02SDimitry Andric        : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
1505*b5893f02SDimitry Andric               _VSTD::forward_as_tuple(__a))
1506*b5893f02SDimitry Andric    {
1507*b5893f02SDimitry Andric    }
1508*b5893f02SDimitry Andric
1509*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1510*b5893f02SDimitry Andric    explicit __alloc_func(const _Target& __f, _Alloc&& __a)
1511*b5893f02SDimitry Andric        : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
1512*b5893f02SDimitry Andric               _VSTD::forward_as_tuple(_VSTD::move(__a)))
1513*b5893f02SDimitry Andric    {
1514*b5893f02SDimitry Andric    }
1515*b5893f02SDimitry Andric
1516*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1517*b5893f02SDimitry Andric    explicit __alloc_func(_Target&& __f, _Alloc&& __a)
1518*b5893f02SDimitry Andric        : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
1519*b5893f02SDimitry Andric               _VSTD::forward_as_tuple(_VSTD::move(__a)))
1520*b5893f02SDimitry Andric    {
1521*b5893f02SDimitry Andric    }
1522*b5893f02SDimitry Andric
1523*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1524*b5893f02SDimitry Andric    _Rp operator()(_ArgTypes&&... __arg)
1525*b5893f02SDimitry Andric    {
1526*b5893f02SDimitry Andric        typedef __invoke_void_return_wrapper<_Rp> _Invoker;
1527*b5893f02SDimitry Andric        return _Invoker::__call(__f_.first(),
1528*b5893f02SDimitry Andric                                _VSTD::forward<_ArgTypes>(__arg)...);
1529*b5893f02SDimitry Andric    }
1530*b5893f02SDimitry Andric
1531*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1532*b5893f02SDimitry Andric    __alloc_func* __clone() const
1533*b5893f02SDimitry Andric    {
1534*b5893f02SDimitry Andric        typedef allocator_traits<_Alloc> __alloc_traits;
1535*b5893f02SDimitry Andric        typedef
1536*b5893f02SDimitry Andric            typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
1537*b5893f02SDimitry Andric                _AA;
1538*b5893f02SDimitry Andric        _AA __a(__f_.second());
1539*b5893f02SDimitry Andric        typedef __allocator_destructor<_AA> _Dp;
1540*b5893f02SDimitry Andric        unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1541*b5893f02SDimitry Andric        ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
1542*b5893f02SDimitry Andric        return __hold.release();
1543*b5893f02SDimitry Andric    }
1544*b5893f02SDimitry Andric
1545*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1546*b5893f02SDimitry Andric    void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
1547*b5893f02SDimitry Andric};
1548*b5893f02SDimitry Andric
1549*b5893f02SDimitry Andric// __base provides an abstract interface for copyable functors.
1550*b5893f02SDimitry Andric
15517a984708SDavid Chisnalltemplate<class _Fp> class __base;
15527a984708SDavid Chisnall
155394e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
155494e3ee44SDavid Chisnallclass __base<_Rp(_ArgTypes...)>
15557a984708SDavid Chisnall{
15567a984708SDavid Chisnall    __base(const __base&);
15577a984708SDavid Chisnall    __base& operator=(const __base&);
15587a984708SDavid Chisnallpublic:
15597a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __base() {}
15607a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY virtual ~__base() {}
15617a984708SDavid Chisnall    virtual __base* __clone() const = 0;
15627a984708SDavid Chisnall    virtual void __clone(__base*) const = 0;
15637a984708SDavid Chisnall    virtual void destroy() _NOEXCEPT = 0;
15647a984708SDavid Chisnall    virtual void destroy_deallocate() _NOEXCEPT = 0;
156594e3ee44SDavid Chisnall    virtual _Rp operator()(_ArgTypes&& ...) = 0;
15667a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI
15677a984708SDavid Chisnall    virtual const void* target(const type_info&) const _NOEXCEPT = 0;
15687a984708SDavid Chisnall    virtual const std::type_info& target_type() const _NOEXCEPT = 0;
15697a984708SDavid Chisnall#endif  // _LIBCPP_NO_RTTI
15707a984708SDavid Chisnall};
15717a984708SDavid Chisnall
1572*b5893f02SDimitry Andric// __func implements __base for a given functor type.
1573*b5893f02SDimitry Andric
15747a984708SDavid Chisnalltemplate<class _FD, class _Alloc, class _FB> class __func;
15757a984708SDavid Chisnall
157694e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
157794e3ee44SDavid Chisnallclass __func<_Fp, _Alloc, _Rp(_ArgTypes...)>
157894e3ee44SDavid Chisnall    : public  __base<_Rp(_ArgTypes...)>
15797a984708SDavid Chisnall{
1580*b5893f02SDimitry Andric    __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
15817a984708SDavid Chisnallpublic:
15827a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
158394e3ee44SDavid Chisnall    explicit __func(_Fp&& __f)
1584*b5893f02SDimitry Andric        : __f_(_VSTD::move(__f)) {}
1585*b5893f02SDimitry Andric
15867a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
158794e3ee44SDavid Chisnall    explicit __func(const _Fp& __f, const _Alloc& __a)
1588*b5893f02SDimitry Andric        : __f_(__f, __a) {}
158994e3ee44SDavid Chisnall
159094e3ee44SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
159194e3ee44SDavid Chisnall    explicit __func(const _Fp& __f, _Alloc&& __a)
1592*b5893f02SDimitry Andric        : __f_(__f, _VSTD::move(__a)) {}
159394e3ee44SDavid Chisnall
159494e3ee44SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
159594e3ee44SDavid Chisnall    explicit __func(_Fp&& __f, _Alloc&& __a)
1596*b5893f02SDimitry Andric        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
1597*b5893f02SDimitry Andric
159894e3ee44SDavid Chisnall    virtual __base<_Rp(_ArgTypes...)>* __clone() const;
159994e3ee44SDavid Chisnall    virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
16007a984708SDavid Chisnall    virtual void destroy() _NOEXCEPT;
16017a984708SDavid Chisnall    virtual void destroy_deallocate() _NOEXCEPT;
160294e3ee44SDavid Chisnall    virtual _Rp operator()(_ArgTypes&&... __arg);
16037a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI
16047a984708SDavid Chisnall    virtual const void* target(const type_info&) const _NOEXCEPT;
16057a984708SDavid Chisnall    virtual const std::type_info& target_type() const _NOEXCEPT;
16067a984708SDavid Chisnall#endif  // _LIBCPP_NO_RTTI
16077a984708SDavid Chisnall};
16087a984708SDavid Chisnall
160994e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
161094e3ee44SDavid Chisnall__base<_Rp(_ArgTypes...)>*
161194e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
16127a984708SDavid Chisnall{
1613854fa44bSDimitry Andric    typedef allocator_traits<_Alloc> __alloc_traits;
1614854fa44bSDimitry Andric    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1615*b5893f02SDimitry Andric    _Ap __a(__f_.__allocator());
161694e3ee44SDavid Chisnall    typedef __allocator_destructor<_Ap> _Dp;
161794e3ee44SDavid Chisnall    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1618*b5893f02SDimitry Andric    ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
16197a984708SDavid Chisnall    return __hold.release();
16207a984708SDavid Chisnall}
16217a984708SDavid Chisnall
162294e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
16237a984708SDavid Chisnallvoid
162494e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
16257a984708SDavid Chisnall{
1626*b5893f02SDimitry Andric    ::new (__p) __func(__f_.__target(), __f_.__allocator());
16277a984708SDavid Chisnall}
16287a984708SDavid Chisnall
162994e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
16307a984708SDavid Chisnallvoid
163194e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT
16327a984708SDavid Chisnall{
1633*b5893f02SDimitry Andric    __f_.destroy();
16347a984708SDavid Chisnall}
16357a984708SDavid Chisnall
163694e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
16377a984708SDavid Chisnallvoid
163894e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
16397a984708SDavid Chisnall{
1640854fa44bSDimitry Andric    typedef allocator_traits<_Alloc> __alloc_traits;
1641854fa44bSDimitry Andric    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1642*b5893f02SDimitry Andric    _Ap __a(__f_.__allocator());
1643*b5893f02SDimitry Andric    __f_.destroy();
16447a984708SDavid Chisnall    __a.deallocate(this, 1);
16457a984708SDavid Chisnall}
16467a984708SDavid Chisnall
164794e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
164894e3ee44SDavid Chisnall_Rp
164994e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
16507a984708SDavid Chisnall{
1651*b5893f02SDimitry Andric    return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
16527a984708SDavid Chisnall}
16537a984708SDavid Chisnall
16547a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI
16557a984708SDavid Chisnall
165694e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
16577a984708SDavid Chisnallconst void*
165894e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
16597a984708SDavid Chisnall{
166094e3ee44SDavid Chisnall    if (__ti == typeid(_Fp))
1661*b5893f02SDimitry Andric        return &__f_.__target();
16627a984708SDavid Chisnall    return (const void*)0;
16637a984708SDavid Chisnall}
16647a984708SDavid Chisnall
166594e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
16667a984708SDavid Chisnallconst std::type_info&
166794e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
16687a984708SDavid Chisnall{
166994e3ee44SDavid Chisnall    return typeid(_Fp);
16707a984708SDavid Chisnall}
16717a984708SDavid Chisnall
16727a984708SDavid Chisnall#endif  // _LIBCPP_NO_RTTI
16737a984708SDavid Chisnall
1674*b5893f02SDimitry Andric// __value_func creates a value-type from a __func.
16757a984708SDavid Chisnall
1676*b5893f02SDimitry Andrictemplate <class _Fp> class __value_func;
1677*b5893f02SDimitry Andric
1678*b5893f02SDimitry Andrictemplate <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
16797a984708SDavid Chisnall{
1680cfdf2879SDavid Chisnall    typename aligned_storage<3 * sizeof(void*)>::type __buf_;
16817a984708SDavid Chisnall
1682*b5893f02SDimitry Andric    typedef __base<_Rp(_ArgTypes...)> __func;
1683*b5893f02SDimitry Andric    __func* __f_;
1684*b5893f02SDimitry Andric
1685*b5893f02SDimitry Andric    _LIBCPP_NO_CFI static __func* __as_base(void* p)
1686*b5893f02SDimitry Andric    {
1687*b5893f02SDimitry Andric        return reinterpret_cast<__func*>(p);
16887c82a1ecSDimitry Andric    }
16897c82a1ecSDimitry Andric
16907a984708SDavid Chisnall  public:
16917a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1692*b5893f02SDimitry Andric    __value_func() _NOEXCEPT : __f_(0) {}
16937a984708SDavid Chisnall
169494e3ee44SDavid Chisnall    template <class _Fp, class _Alloc>
1695*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc __a)
16967a984708SDavid Chisnall        : __f_(0)
16977a984708SDavid Chisnall    {
16987a984708SDavid Chisnall        typedef allocator_traits<_Alloc> __alloc_traits;
1699*b5893f02SDimitry Andric        typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
1700*b5893f02SDimitry Andric        typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
1701*b5893f02SDimitry Andric            _FunAlloc;
1702*b5893f02SDimitry Andric
17039729cf09SDimitry Andric        if (__function::__not_null(__f))
17047a984708SDavid Chisnall        {
1705*b5893f02SDimitry Andric            _FunAlloc __af(__a);
1706*b5893f02SDimitry Andric            if (sizeof(_Fun) <= sizeof(__buf_) &&
1707*b5893f02SDimitry Andric                is_nothrow_copy_constructible<_Fp>::value &&
1708*b5893f02SDimitry Andric                is_nothrow_copy_constructible<_FunAlloc>::value)
1709d72607e9SDimitry Andric            {
1710*b5893f02SDimitry Andric                __f_ =
1711*b5893f02SDimitry Andric                    ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af));
1712d72607e9SDimitry Andric            }
1713d72607e9SDimitry Andric            else
1714d72607e9SDimitry Andric            {
1715*b5893f02SDimitry Andric                typedef __allocator_destructor<_FunAlloc> _Dp;
1716*b5893f02SDimitry Andric                unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
1717*b5893f02SDimitry Andric                ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a));
17187a984708SDavid Chisnall                __f_ = __hold.release();
17197a984708SDavid Chisnall            }
17207a984708SDavid Chisnall        }
17217a984708SDavid Chisnall    }
17227a984708SDavid Chisnall
1723*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1724*b5893f02SDimitry Andric    __value_func(const __value_func& __f)
17257a984708SDavid Chisnall    {
1726*b5893f02SDimitry Andric        if (__f.__f_ == 0)
1727*b5893f02SDimitry Andric            __f_ = 0;
1728*b5893f02SDimitry Andric        else if ((void*)__f.__f_ == &__f.__buf_)
1729*b5893f02SDimitry Andric        {
1730*b5893f02SDimitry Andric            __f_ = __as_base(&__buf_);
1731*b5893f02SDimitry Andric            __f.__f_->__clone(__f_);
1732*b5893f02SDimitry Andric        }
1733*b5893f02SDimitry Andric        else
1734*b5893f02SDimitry Andric            __f_ = __f.__f_->__clone();
17357a984708SDavid Chisnall    }
17367a984708SDavid Chisnall
1737*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1738*b5893f02SDimitry Andric    __value_func(__value_func&& __f) _NOEXCEPT
1739*b5893f02SDimitry Andric    {
1740*b5893f02SDimitry Andric        if (__f.__f_ == 0)
1741*b5893f02SDimitry Andric            __f_ = 0;
1742*b5893f02SDimitry Andric        else if ((void*)__f.__f_ == &__f.__buf_)
1743*b5893f02SDimitry Andric        {
1744*b5893f02SDimitry Andric            __f_ = __as_base(&__buf_);
1745*b5893f02SDimitry Andric            __f.__f_->__clone(__f_);
1746*b5893f02SDimitry Andric        }
1747*b5893f02SDimitry Andric        else
1748*b5893f02SDimitry Andric        {
1749*b5893f02SDimitry Andric            __f_ = __f.__f_;
1750*b5893f02SDimitry Andric            __f.__f_ = 0;
1751*b5893f02SDimitry Andric        }
1752*b5893f02SDimitry Andric    }
1753*b5893f02SDimitry Andric
1754*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1755*b5893f02SDimitry Andric    ~__value_func()
1756*b5893f02SDimitry Andric    {
1757*b5893f02SDimitry Andric        if ((void*)__f_ == &__buf_)
1758*b5893f02SDimitry Andric            __f_->destroy();
1759*b5893f02SDimitry Andric        else if (__f_)
1760*b5893f02SDimitry Andric            __f_->destroy_deallocate();
1761*b5893f02SDimitry Andric    }
1762*b5893f02SDimitry Andric
1763*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1764*b5893f02SDimitry Andric    __value_func& operator=(__value_func&& __f)
17657a984708SDavid Chisnall    {
17664ba319b5SDimitry Andric        *this = nullptr;
17677a984708SDavid Chisnall        if (__f.__f_ == 0)
17687a984708SDavid Chisnall            __f_ = 0;
17697c82a1ecSDimitry Andric        else if ((void*)__f.__f_ == &__f.__buf_)
17707a984708SDavid Chisnall        {
17717c82a1ecSDimitry Andric            __f_ = __as_base(&__buf_);
17727a984708SDavid Chisnall            __f.__f_->__clone(__f_);
17737a984708SDavid Chisnall        }
17747a984708SDavid Chisnall        else
17757a984708SDavid Chisnall        {
17767a984708SDavid Chisnall            __f_ = __f.__f_;
17777a984708SDavid Chisnall            __f.__f_ = 0;
17787a984708SDavid Chisnall        }
1779936e9439SDimitry Andric        return *this;
17807a984708SDavid Chisnall    }
17817a984708SDavid Chisnall
1782*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1783*b5893f02SDimitry Andric    __value_func& operator=(nullptr_t)
17847a984708SDavid Chisnall    {
1785*b5893f02SDimitry Andric        __func* __f = __f_;
17867a984708SDavid Chisnall        __f_ = 0;
1787*b5893f02SDimitry Andric        if ((void*)__f == &__buf_)
1788*b5893f02SDimitry Andric            __f->destroy();
1789*b5893f02SDimitry Andric        else if (__f)
1790*b5893f02SDimitry Andric            __f->destroy_deallocate();
1791936e9439SDimitry Andric        return *this;
17927a984708SDavid Chisnall    }
17937a984708SDavid Chisnall
1794*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1795*b5893f02SDimitry Andric    _Rp operator()(_ArgTypes&&... __args) const
17967a984708SDavid Chisnall    {
1797*b5893f02SDimitry Andric        if (__f_ == 0)
1798*b5893f02SDimitry Andric            __throw_bad_function_call();
1799*b5893f02SDimitry Andric        return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...);
18007a984708SDavid Chisnall    }
18017a984708SDavid Chisnall
1802*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1803*b5893f02SDimitry Andric    void swap(__value_func& __f) _NOEXCEPT
18047a984708SDavid Chisnall    {
1805*b5893f02SDimitry Andric        if (&__f == this)
1806aed8d94eSDimitry Andric            return;
18077c82a1ecSDimitry Andric        if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_)
18087a984708SDavid Chisnall        {
18097a984708SDavid Chisnall            typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1810*b5893f02SDimitry Andric            __func* __t = __as_base(&__tempbuf);
18117a984708SDavid Chisnall            __f_->__clone(__t);
18127a984708SDavid Chisnall            __f_->destroy();
18137a984708SDavid Chisnall            __f_ = 0;
18147c82a1ecSDimitry Andric            __f.__f_->__clone(__as_base(&__buf_));
18157a984708SDavid Chisnall            __f.__f_->destroy();
18167a984708SDavid Chisnall            __f.__f_ = 0;
18177c82a1ecSDimitry Andric            __f_ = __as_base(&__buf_);
18187c82a1ecSDimitry Andric            __t->__clone(__as_base(&__f.__buf_));
18197a984708SDavid Chisnall            __t->destroy();
18207c82a1ecSDimitry Andric            __f.__f_ = __as_base(&__f.__buf_);
18217a984708SDavid Chisnall        }
18227c82a1ecSDimitry Andric        else if ((void*)__f_ == &__buf_)
18237a984708SDavid Chisnall        {
18247c82a1ecSDimitry Andric            __f_->__clone(__as_base(&__f.__buf_));
18257a984708SDavid Chisnall            __f_->destroy();
18267a984708SDavid Chisnall            __f_ = __f.__f_;
18277c82a1ecSDimitry Andric            __f.__f_ = __as_base(&__f.__buf_);
18287a984708SDavid Chisnall        }
18297c82a1ecSDimitry Andric        else if ((void*)__f.__f_ == &__f.__buf_)
18307a984708SDavid Chisnall        {
18317c82a1ecSDimitry Andric            __f.__f_->__clone(__as_base(&__buf_));
18327a984708SDavid Chisnall            __f.__f_->destroy();
18337a984708SDavid Chisnall            __f.__f_ = __f_;
18347c82a1ecSDimitry Andric            __f_ = __as_base(&__buf_);
18357a984708SDavid Chisnall        }
18367a984708SDavid Chisnall        else
18377a984708SDavid Chisnall            _VSTD::swap(__f_, __f.__f_);
18387a984708SDavid Chisnall    }
18397a984708SDavid Chisnall
1840*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1841*b5893f02SDimitry Andric    _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { return __f_ != 0; }
1842*b5893f02SDimitry Andric
1843*b5893f02SDimitry Andric#ifndef _LIBCPP_NO_RTTI
1844*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1845*b5893f02SDimitry Andric    const std::type_info& target_type() const _NOEXCEPT
1846*b5893f02SDimitry Andric    {
1847*b5893f02SDimitry Andric        if (__f_ == 0)
1848*b5893f02SDimitry Andric            return typeid(void);
1849*b5893f02SDimitry Andric        return __f_->target_type();
1850*b5893f02SDimitry Andric    }
1851*b5893f02SDimitry Andric
1852*b5893f02SDimitry Andric    template <typename _Tp>
1853*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
1854*b5893f02SDimitry Andric    {
1855*b5893f02SDimitry Andric        if (__f_ == 0)
1856*b5893f02SDimitry Andric            return 0;
1857*b5893f02SDimitry Andric        return (const _Tp*)__f_->target(typeid(_Tp));
1858*b5893f02SDimitry Andric    }
1859*b5893f02SDimitry Andric#endif // _LIBCPP_NO_RTTI
1860*b5893f02SDimitry Andric};
1861*b5893f02SDimitry Andric
1862*b5893f02SDimitry Andric// Storage for a functor object, to be used with __policy to manage copy and
1863*b5893f02SDimitry Andric// destruction.
1864*b5893f02SDimitry Andricunion __policy_storage
1865*b5893f02SDimitry Andric{
1866*b5893f02SDimitry Andric    mutable char __small[sizeof(void*) * 2];
1867*b5893f02SDimitry Andric    void* __large;
1868*b5893f02SDimitry Andric};
1869*b5893f02SDimitry Andric
1870*b5893f02SDimitry Andric// True if _Fun can safely be held in __policy_storage.__small.
1871*b5893f02SDimitry Andrictemplate <typename _Fun>
1872*b5893f02SDimitry Andricstruct __use_small_storage
1873*b5893f02SDimitry Andric    : public _VSTD::integral_constant<
1874*b5893f02SDimitry Andric          bool, sizeof(_Fun) <= sizeof(__policy_storage) &&
1875*b5893f02SDimitry Andric                    _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
1876*b5893f02SDimitry Andric                    _VSTD::is_trivially_copy_constructible<_Fun>::value &&
1877*b5893f02SDimitry Andric                    _VSTD::is_trivially_destructible<_Fun>::value> {};
1878*b5893f02SDimitry Andric
1879*b5893f02SDimitry Andric// Policy contains information about how to copy, destroy, and move the
1880*b5893f02SDimitry Andric// underlying functor. You can think of it as a vtable of sorts.
1881*b5893f02SDimitry Andricstruct __policy
1882*b5893f02SDimitry Andric{
1883*b5893f02SDimitry Andric    // Used to copy or destroy __large values. null for trivial objects.
1884*b5893f02SDimitry Andric    void* (*const __clone)(const void*);
1885*b5893f02SDimitry Andric    void (*const __destroy)(void*);
1886*b5893f02SDimitry Andric
1887*b5893f02SDimitry Andric    // True if this is the null policy (no value).
1888*b5893f02SDimitry Andric    const bool __is_null;
1889*b5893f02SDimitry Andric
1890*b5893f02SDimitry Andric    // The target type. May be null if RTTI is disabled.
1891*b5893f02SDimitry Andric    const std::type_info* const __type_info;
1892*b5893f02SDimitry Andric
1893*b5893f02SDimitry Andric    // Returns a pointer to a static policy object suitable for the functor
1894*b5893f02SDimitry Andric    // type.
1895*b5893f02SDimitry Andric    template <typename _Fun>
1896*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static const __policy* __create()
1897*b5893f02SDimitry Andric    {
1898*b5893f02SDimitry Andric        return __choose_policy<_Fun>(__use_small_storage<_Fun>());
1899*b5893f02SDimitry Andric    }
1900*b5893f02SDimitry Andric
1901*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1902*b5893f02SDimitry Andric    static const __policy* __create_empty()
1903*b5893f02SDimitry Andric    {
1904*b5893f02SDimitry Andric        static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr,
1905*b5893f02SDimitry Andric                                                             true,
1906*b5893f02SDimitry Andric#ifndef _LIBCPP_NO_RTTI
1907*b5893f02SDimitry Andric                                                             &typeid(void)
1908*b5893f02SDimitry Andric#else
1909*b5893f02SDimitry Andric                                                             nullptr
1910*b5893f02SDimitry Andric#endif
1911*b5893f02SDimitry Andric        };
1912*b5893f02SDimitry Andric        return &__policy_;
1913*b5893f02SDimitry Andric    }
1914*b5893f02SDimitry Andric
1915*b5893f02SDimitry Andric  private:
1916*b5893f02SDimitry Andric    template <typename _Fun> static void* __large_clone(const void* __s)
1917*b5893f02SDimitry Andric    {
1918*b5893f02SDimitry Andric        const _Fun* __f = static_cast<const _Fun*>(__s);
1919*b5893f02SDimitry Andric        return __f->__clone();
1920*b5893f02SDimitry Andric    }
1921*b5893f02SDimitry Andric
1922*b5893f02SDimitry Andric    template <typename _Fun> static void __large_destroy(void* __s)
1923*b5893f02SDimitry Andric    {
1924*b5893f02SDimitry Andric        typedef allocator_traits<typename _Fun::_Alloc> __alloc_traits;
1925*b5893f02SDimitry Andric        typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
1926*b5893f02SDimitry Andric            _FunAlloc;
1927*b5893f02SDimitry Andric        _Fun* __f = static_cast<_Fun*>(__s);
1928*b5893f02SDimitry Andric        _FunAlloc __a(__f->__allocator());
1929*b5893f02SDimitry Andric        __f->destroy();
1930*b5893f02SDimitry Andric        __a.deallocate(__f, 1);
1931*b5893f02SDimitry Andric    }
1932*b5893f02SDimitry Andric
1933*b5893f02SDimitry Andric    template <typename _Fun>
1934*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static const __policy*
1935*b5893f02SDimitry Andric        __choose_policy(/* is_small = */ false_type)
1936*b5893f02SDimitry Andric    {
1937*b5893f02SDimitry Andric        static const _LIBCPP_CONSTEXPR __policy __policy_ = {
1938*b5893f02SDimitry Andric            &__large_clone<_Fun>, &__large_destroy<_Fun>, false,
1939*b5893f02SDimitry Andric#ifndef _LIBCPP_NO_RTTI
1940*b5893f02SDimitry Andric            &typeid(typename _Fun::_Target)
1941*b5893f02SDimitry Andric#else
1942*b5893f02SDimitry Andric            nullptr
1943*b5893f02SDimitry Andric#endif
1944*b5893f02SDimitry Andric        };
1945*b5893f02SDimitry Andric        return &__policy_;
1946*b5893f02SDimitry Andric    }
1947*b5893f02SDimitry Andric
1948*b5893f02SDimitry Andric    template <typename _Fun>
1949*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static const __policy*
1950*b5893f02SDimitry Andric        __choose_policy(/* is_small = */ true_type)
1951*b5893f02SDimitry Andric    {
1952*b5893f02SDimitry Andric        static const _LIBCPP_CONSTEXPR __policy __policy_ = {
1953*b5893f02SDimitry Andric            nullptr, nullptr, false,
1954*b5893f02SDimitry Andric#ifndef _LIBCPP_NO_RTTI
1955*b5893f02SDimitry Andric            &typeid(typename _Fun::_Target)
1956*b5893f02SDimitry Andric#else
1957*b5893f02SDimitry Andric            nullptr
1958*b5893f02SDimitry Andric#endif
1959*b5893f02SDimitry Andric        };
1960*b5893f02SDimitry Andric        return &__policy_;
1961*b5893f02SDimitry Andric    }
1962*b5893f02SDimitry Andric};
1963*b5893f02SDimitry Andric
1964*b5893f02SDimitry Andric// Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
1965*b5893f02SDimitry Andric// faster for types that can be passed in registers.
1966*b5893f02SDimitry Andrictemplate <typename _Tp>
1967*b5893f02SDimitry Andricusing __fast_forward =
1968*b5893f02SDimitry Andric    typename _VSTD::conditional<_VSTD::is_scalar<_Tp>::value, _Tp, _Tp&&>::type;
1969*b5893f02SDimitry Andric
1970*b5893f02SDimitry Andric// __policy_invoker calls an instance of __alloc_func held in __policy_storage.
1971*b5893f02SDimitry Andric
1972*b5893f02SDimitry Andrictemplate <class _Fp> struct __policy_invoker;
1973*b5893f02SDimitry Andric
1974*b5893f02SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1975*b5893f02SDimitry Andricstruct __policy_invoker<_Rp(_ArgTypes...)>
1976*b5893f02SDimitry Andric{
1977*b5893f02SDimitry Andric    typedef _Rp (*__Call)(const __policy_storage*,
1978*b5893f02SDimitry Andric                          __fast_forward<_ArgTypes>...);
1979*b5893f02SDimitry Andric
1980*b5893f02SDimitry Andric    __Call __call_;
1981*b5893f02SDimitry Andric
1982*b5893f02SDimitry Andric    // Creates an invoker that throws bad_function_call.
1983*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1984*b5893f02SDimitry Andric    __policy_invoker() : __call_(&__call_empty) {}
1985*b5893f02SDimitry Andric
1986*b5893f02SDimitry Andric    // Creates an invoker that calls the given instance of __func.
1987*b5893f02SDimitry Andric    template <typename _Fun>
1988*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create()
1989*b5893f02SDimitry Andric    {
1990*b5893f02SDimitry Andric        return __policy_invoker(&__call_impl<_Fun>);
1991*b5893f02SDimitry Andric    }
1992*b5893f02SDimitry Andric
1993*b5893f02SDimitry Andric  private:
1994*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1995*b5893f02SDimitry Andric    explicit __policy_invoker(__Call __c) : __call_(__c) {}
1996*b5893f02SDimitry Andric
1997*b5893f02SDimitry Andric    static _Rp __call_empty(const __policy_storage*,
1998*b5893f02SDimitry Andric                            __fast_forward<_ArgTypes>...)
1999*b5893f02SDimitry Andric    {
2000*b5893f02SDimitry Andric        __throw_bad_function_call();
2001*b5893f02SDimitry Andric    }
2002*b5893f02SDimitry Andric
2003*b5893f02SDimitry Andric    template <typename _Fun>
2004*b5893f02SDimitry Andric    static _Rp __call_impl(const __policy_storage* __buf,
2005*b5893f02SDimitry Andric                           __fast_forward<_ArgTypes>... __args)
2006*b5893f02SDimitry Andric    {
2007*b5893f02SDimitry Andric        _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value
2008*b5893f02SDimitry Andric                                                ? &__buf->__small
2009*b5893f02SDimitry Andric                                                : __buf->__large);
2010*b5893f02SDimitry Andric        return (*__f)(_VSTD::forward<_ArgTypes>(__args)...);
2011*b5893f02SDimitry Andric    }
2012*b5893f02SDimitry Andric};
2013*b5893f02SDimitry Andric
2014*b5893f02SDimitry Andric// __policy_func uses a __policy and __policy_invoker to create a type-erased,
2015*b5893f02SDimitry Andric// copyable functor.
2016*b5893f02SDimitry Andric
2017*b5893f02SDimitry Andrictemplate <class _Fp> class __policy_func;
2018*b5893f02SDimitry Andric
2019*b5893f02SDimitry Andrictemplate <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
2020*b5893f02SDimitry Andric{
2021*b5893f02SDimitry Andric    // Inline storage for small objects.
2022*b5893f02SDimitry Andric    __policy_storage __buf_;
2023*b5893f02SDimitry Andric
2024*b5893f02SDimitry Andric    // Calls the value stored in __buf_. This could technically be part of
2025*b5893f02SDimitry Andric    // policy, but storing it here eliminates a level of indirection inside
2026*b5893f02SDimitry Andric    // operator().
2027*b5893f02SDimitry Andric    typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker;
2028*b5893f02SDimitry Andric    __invoker __invoker_;
2029*b5893f02SDimitry Andric
2030*b5893f02SDimitry Andric    // The policy that describes how to move / copy / destroy __buf_. Never
2031*b5893f02SDimitry Andric    // null, even if the function is empty.
2032*b5893f02SDimitry Andric    const __policy* __policy_;
2033*b5893f02SDimitry Andric
2034*b5893f02SDimitry Andric  public:
2035*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2036*b5893f02SDimitry Andric    __policy_func() : __policy_(__policy::__create_empty()) {}
2037*b5893f02SDimitry Andric
2038*b5893f02SDimitry Andric    template <class _Fp, class _Alloc>
2039*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a)
2040*b5893f02SDimitry Andric        : __policy_(__policy::__create_empty())
2041*b5893f02SDimitry Andric    {
2042*b5893f02SDimitry Andric        typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
2043*b5893f02SDimitry Andric        typedef allocator_traits<_Alloc> __alloc_traits;
2044*b5893f02SDimitry Andric        typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
2045*b5893f02SDimitry Andric            _FunAlloc;
2046*b5893f02SDimitry Andric
2047*b5893f02SDimitry Andric        if (__function::__not_null(__f))
2048*b5893f02SDimitry Andric        {
2049*b5893f02SDimitry Andric            __invoker_ = __invoker::template __create<_Fun>();
2050*b5893f02SDimitry Andric            __policy_ = __policy::__create<_Fun>();
2051*b5893f02SDimitry Andric
2052*b5893f02SDimitry Andric            _FunAlloc __af(__a);
2053*b5893f02SDimitry Andric            if (__use_small_storage<_Fun>())
2054*b5893f02SDimitry Andric            {
2055*b5893f02SDimitry Andric                ::new ((void*)&__buf_.__small)
2056*b5893f02SDimitry Andric                    _Fun(_VSTD::move(__f), _Alloc(__af));
2057*b5893f02SDimitry Andric            }
2058*b5893f02SDimitry Andric            else
2059*b5893f02SDimitry Andric            {
2060*b5893f02SDimitry Andric                typedef __allocator_destructor<_FunAlloc> _Dp;
2061*b5893f02SDimitry Andric                unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
2062*b5893f02SDimitry Andric                ::new ((void*)__hold.get())
2063*b5893f02SDimitry Andric                    _Fun(_VSTD::move(__f), _Alloc(__af));
2064*b5893f02SDimitry Andric                __buf_.__large = __hold.release();
2065*b5893f02SDimitry Andric            }
2066*b5893f02SDimitry Andric        }
2067*b5893f02SDimitry Andric    }
2068*b5893f02SDimitry Andric
2069*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2070*b5893f02SDimitry Andric    __policy_func(const __policy_func& __f)
2071*b5893f02SDimitry Andric        : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
2072*b5893f02SDimitry Andric          __policy_(__f.__policy_)
2073*b5893f02SDimitry Andric    {
2074*b5893f02SDimitry Andric        if (__policy_->__clone)
2075*b5893f02SDimitry Andric            __buf_.__large = __policy_->__clone(__f.__buf_.__large);
2076*b5893f02SDimitry Andric    }
2077*b5893f02SDimitry Andric
2078*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2079*b5893f02SDimitry Andric    __policy_func(__policy_func&& __f)
2080*b5893f02SDimitry Andric        : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
2081*b5893f02SDimitry Andric          __policy_(__f.__policy_)
2082*b5893f02SDimitry Andric    {
2083*b5893f02SDimitry Andric        if (__policy_->__destroy)
2084*b5893f02SDimitry Andric        {
2085*b5893f02SDimitry Andric            __f.__policy_ = __policy::__create_empty();
2086*b5893f02SDimitry Andric            __f.__invoker_ = __invoker();
2087*b5893f02SDimitry Andric        }
2088*b5893f02SDimitry Andric    }
2089*b5893f02SDimitry Andric
2090*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2091*b5893f02SDimitry Andric    ~__policy_func()
2092*b5893f02SDimitry Andric    {
2093*b5893f02SDimitry Andric        if (__policy_->__destroy)
2094*b5893f02SDimitry Andric            __policy_->__destroy(__buf_.__large);
2095*b5893f02SDimitry Andric    }
2096*b5893f02SDimitry Andric
2097*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2098*b5893f02SDimitry Andric    __policy_func& operator=(__policy_func&& __f)
2099*b5893f02SDimitry Andric    {
2100*b5893f02SDimitry Andric        *this = nullptr;
2101*b5893f02SDimitry Andric        __buf_ = __f.__buf_;
2102*b5893f02SDimitry Andric        __invoker_ = __f.__invoker_;
2103*b5893f02SDimitry Andric        __policy_ = __f.__policy_;
2104*b5893f02SDimitry Andric        __f.__policy_ = __policy::__create_empty();
2105*b5893f02SDimitry Andric        __f.__invoker_ = __invoker();
2106*b5893f02SDimitry Andric        return *this;
2107*b5893f02SDimitry Andric    }
2108*b5893f02SDimitry Andric
2109*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2110*b5893f02SDimitry Andric    __policy_func& operator=(nullptr_t)
2111*b5893f02SDimitry Andric    {
2112*b5893f02SDimitry Andric        const __policy* __p = __policy_;
2113*b5893f02SDimitry Andric        __policy_ = __policy::__create_empty();
2114*b5893f02SDimitry Andric        __invoker_ = __invoker();
2115*b5893f02SDimitry Andric        if (__p->__destroy)
2116*b5893f02SDimitry Andric            __p->__destroy(__buf_.__large);
2117*b5893f02SDimitry Andric        return *this;
2118*b5893f02SDimitry Andric    }
2119*b5893f02SDimitry Andric
2120*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2121*b5893f02SDimitry Andric    _Rp operator()(_ArgTypes&&... __args) const
2122*b5893f02SDimitry Andric    {
2123*b5893f02SDimitry Andric        return __invoker_.__call_(_VSTD::addressof(__buf_),
2124*b5893f02SDimitry Andric                                  _VSTD::forward<_ArgTypes>(__args)...);
2125*b5893f02SDimitry Andric    }
2126*b5893f02SDimitry Andric
2127*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2128*b5893f02SDimitry Andric    void swap(__policy_func& __f)
2129*b5893f02SDimitry Andric    {
2130*b5893f02SDimitry Andric        _VSTD::swap(__invoker_, __f.__invoker_);
2131*b5893f02SDimitry Andric        _VSTD::swap(__policy_, __f.__policy_);
2132*b5893f02SDimitry Andric        _VSTD::swap(__buf_, __f.__buf_);
2133*b5893f02SDimitry Andric    }
2134*b5893f02SDimitry Andric
2135*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2136*b5893f02SDimitry Andric    explicit operator bool() const _NOEXCEPT
2137*b5893f02SDimitry Andric    {
2138*b5893f02SDimitry Andric        return !__policy_->__is_null;
2139*b5893f02SDimitry Andric    }
2140*b5893f02SDimitry Andric
2141*b5893f02SDimitry Andric#ifndef _LIBCPP_NO_RTTI
2142*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2143*b5893f02SDimitry Andric    const std::type_info& target_type() const _NOEXCEPT
2144*b5893f02SDimitry Andric    {
2145*b5893f02SDimitry Andric        return *__policy_->__type_info;
2146*b5893f02SDimitry Andric    }
2147*b5893f02SDimitry Andric
2148*b5893f02SDimitry Andric    template <typename _Tp>
2149*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
2150*b5893f02SDimitry Andric    {
2151*b5893f02SDimitry Andric        if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)
2152*b5893f02SDimitry Andric            return nullptr;
2153*b5893f02SDimitry Andric        if (__policy_->__clone) // Out of line storage.
2154*b5893f02SDimitry Andric            return reinterpret_cast<const _Tp*>(__buf_.__large);
2155*b5893f02SDimitry Andric        else
2156*b5893f02SDimitry Andric            return reinterpret_cast<const _Tp*>(&__buf_.__small);
2157*b5893f02SDimitry Andric    }
2158*b5893f02SDimitry Andric#endif // _LIBCPP_NO_RTTI
2159*b5893f02SDimitry Andric};
2160*b5893f02SDimitry Andric
2161*b5893f02SDimitry Andric}  // __function
2162*b5893f02SDimitry Andric
2163*b5893f02SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2164*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
2165*b5893f02SDimitry Andric    : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
2166*b5893f02SDimitry Andric      public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
2167*b5893f02SDimitry Andric{
2168*b5893f02SDimitry Andric#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
2169*b5893f02SDimitry Andric    typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
2170*b5893f02SDimitry Andric#else
2171*b5893f02SDimitry Andric    typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
2172*b5893f02SDimitry Andric#endif
2173*b5893f02SDimitry Andric
2174*b5893f02SDimitry Andric    __func __f_;
2175*b5893f02SDimitry Andric
2176*b5893f02SDimitry Andric    template <class _Fp, bool = __lazy_and<
2177*b5893f02SDimitry Andric        integral_constant<bool, !is_same<__uncvref_t<_Fp>, function>::value>,
2178*b5893f02SDimitry Andric        __invokable<_Fp&, _ArgTypes...>
2179*b5893f02SDimitry Andric    >::value>
2180*b5893f02SDimitry Andric    struct __callable;
2181*b5893f02SDimitry Andric    template <class _Fp>
2182*b5893f02SDimitry Andric        struct __callable<_Fp, true>
2183*b5893f02SDimitry Andric        {
2184*b5893f02SDimitry Andric            static const bool value = is_same<void, _Rp>::value ||
2185*b5893f02SDimitry Andric                is_convertible<typename __invoke_of<_Fp&, _ArgTypes...>::type,
2186*b5893f02SDimitry Andric                               _Rp>::value;
2187*b5893f02SDimitry Andric        };
2188*b5893f02SDimitry Andric    template <class _Fp>
2189*b5893f02SDimitry Andric        struct __callable<_Fp, false>
2190*b5893f02SDimitry Andric        {
2191*b5893f02SDimitry Andric            static const bool value = false;
2192*b5893f02SDimitry Andric        };
2193*b5893f02SDimitry Andric
2194*b5893f02SDimitry Andric  template <class _Fp>
2195*b5893f02SDimitry Andric  using _EnableIfCallable = typename enable_if<__callable<_Fp>::value>::type;
2196*b5893f02SDimitry Andricpublic:
2197*b5893f02SDimitry Andric    typedef _Rp result_type;
2198*b5893f02SDimitry Andric
2199*b5893f02SDimitry Andric    // construct/copy/destroy:
2200*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2201*b5893f02SDimitry Andric    function() _NOEXCEPT { }
2202*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2203*b5893f02SDimitry Andric    function(nullptr_t) _NOEXCEPT {}
2204*b5893f02SDimitry Andric    function(const function&);
2205*b5893f02SDimitry Andric    function(function&&) _NOEXCEPT;
2206*b5893f02SDimitry Andric    template<class _Fp, class = _EnableIfCallable<_Fp>>
2207*b5893f02SDimitry Andric    function(_Fp);
2208*b5893f02SDimitry Andric
2209*b5893f02SDimitry Andric#if _LIBCPP_STD_VER <= 14
2210*b5893f02SDimitry Andric    template<class _Alloc>
2211*b5893f02SDimitry Andric      _LIBCPP_INLINE_VISIBILITY
2212*b5893f02SDimitry Andric      function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
2213*b5893f02SDimitry Andric    template<class _Alloc>
2214*b5893f02SDimitry Andric      _LIBCPP_INLINE_VISIBILITY
2215*b5893f02SDimitry Andric      function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
2216*b5893f02SDimitry Andric    template<class _Alloc>
2217*b5893f02SDimitry Andric      function(allocator_arg_t, const _Alloc&, const function&);
2218*b5893f02SDimitry Andric    template<class _Alloc>
2219*b5893f02SDimitry Andric      function(allocator_arg_t, const _Alloc&, function&&);
2220*b5893f02SDimitry Andric    template<class _Fp, class _Alloc, class = _EnableIfCallable<_Fp>>
2221*b5893f02SDimitry Andric      function(allocator_arg_t, const _Alloc& __a, _Fp __f);
2222*b5893f02SDimitry Andric#endif
2223*b5893f02SDimitry Andric
2224*b5893f02SDimitry Andric    function& operator=(const function&);
2225*b5893f02SDimitry Andric    function& operator=(function&&) _NOEXCEPT;
2226*b5893f02SDimitry Andric    function& operator=(nullptr_t) _NOEXCEPT;
2227*b5893f02SDimitry Andric    template<class _Fp, class = _EnableIfCallable<_Fp>>
2228*b5893f02SDimitry Andric    function& operator=(_Fp&&);
2229*b5893f02SDimitry Andric
2230*b5893f02SDimitry Andric    ~function();
2231*b5893f02SDimitry Andric
2232*b5893f02SDimitry Andric    // function modifiers:
2233*b5893f02SDimitry Andric    void swap(function&) _NOEXCEPT;
2234*b5893f02SDimitry Andric
2235*b5893f02SDimitry Andric#if _LIBCPP_STD_VER <= 14
2236*b5893f02SDimitry Andric    template<class _Fp, class _Alloc>
2237*b5893f02SDimitry Andric      _LIBCPP_INLINE_VISIBILITY
2238*b5893f02SDimitry Andric      void assign(_Fp&& __f, const _Alloc& __a)
2239*b5893f02SDimitry Andric        {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);}
2240*b5893f02SDimitry Andric#endif
2241*b5893f02SDimitry Andric
2242*b5893f02SDimitry Andric    // function capacity:
2243*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2244*b5893f02SDimitry Andric    _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
2245*b5893f02SDimitry Andric      return static_cast<bool>(__f_);
2246*b5893f02SDimitry Andric    }
2247*b5893f02SDimitry Andric
2248*b5893f02SDimitry Andric    // deleted overloads close possible hole in the type system
2249*b5893f02SDimitry Andric    template<class _R2, class... _ArgTypes2>
2250*b5893f02SDimitry Andric      bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
2251*b5893f02SDimitry Andric    template<class _R2, class... _ArgTypes2>
2252*b5893f02SDimitry Andric      bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
2253*b5893f02SDimitry Andricpublic:
2254*b5893f02SDimitry Andric    // function invocation:
2255*b5893f02SDimitry Andric    _Rp operator()(_ArgTypes...) const;
2256*b5893f02SDimitry Andric
2257*b5893f02SDimitry Andric#ifndef _LIBCPP_NO_RTTI
2258*b5893f02SDimitry Andric    // function target access:
2259*b5893f02SDimitry Andric    const std::type_info& target_type() const _NOEXCEPT;
2260*b5893f02SDimitry Andric    template <typename _Tp> _Tp* target() _NOEXCEPT;
2261*b5893f02SDimitry Andric    template <typename _Tp> const _Tp* target() const _NOEXCEPT;
2262*b5893f02SDimitry Andric#endif  // _LIBCPP_NO_RTTI
2263*b5893f02SDimitry Andric};
2264*b5893f02SDimitry Andric
2265*b5893f02SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2266*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
2267*b5893f02SDimitry Andric
2268*b5893f02SDimitry Andric#if _LIBCPP_STD_VER <= 14
2269*b5893f02SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2270*b5893f02SDimitry Andrictemplate <class _Alloc>
2271*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
2272*b5893f02SDimitry Andric                                     const function& __f) : __f_(__f.__f_) {}
2273*b5893f02SDimitry Andric#endif
2274*b5893f02SDimitry Andric
2275*b5893f02SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
2276*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT
2277*b5893f02SDimitry Andric    : __f_(_VSTD::move(__f.__f_)) {}
2278*b5893f02SDimitry Andric
2279*b5893f02SDimitry Andric#if _LIBCPP_STD_VER <= 14
2280*b5893f02SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2281*b5893f02SDimitry Andrictemplate <class _Alloc>
2282*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
2283*b5893f02SDimitry Andric                                      function&& __f)
2284*b5893f02SDimitry Andric    : __f_(_VSTD::move(__f.__f_)) {}
2285*b5893f02SDimitry Andric#endif
2286*b5893f02SDimitry Andric
2287*b5893f02SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
2288*b5893f02SDimitry Andrictemplate <class _Fp, class>
2289*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::function(_Fp __f)
2290*b5893f02SDimitry Andric    : __f_(_VSTD::move(__f), allocator<_Fp>()) {}
2291*b5893f02SDimitry Andric
2292*b5893f02SDimitry Andric#if _LIBCPP_STD_VER <= 14
2293*b5893f02SDimitry Andrictemplate <class _Rp, class... _ArgTypes>
2294*b5893f02SDimitry Andrictemplate <class _Fp, class _Alloc, class>
2295*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a,
2296*b5893f02SDimitry Andric                                      _Fp __f)
2297*b5893f02SDimitry Andric    : __f_(_VSTD::move(__f), __a) {}
2298*b5893f02SDimitry Andric#endif
2299*b5893f02SDimitry Andric
2300*b5893f02SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2301*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>&
2302*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::operator=(const function& __f)
2303*b5893f02SDimitry Andric{
2304*b5893f02SDimitry Andric    function(__f).swap(*this);
2305*b5893f02SDimitry Andric    return *this;
2306*b5893f02SDimitry Andric}
2307*b5893f02SDimitry Andric
2308*b5893f02SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2309*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>&
2310*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
2311*b5893f02SDimitry Andric{
2312*b5893f02SDimitry Andric    __f_ = std::move(__f.__f_);
2313*b5893f02SDimitry Andric    return *this;
2314*b5893f02SDimitry Andric}
2315*b5893f02SDimitry Andric
2316*b5893f02SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2317*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>&
2318*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
2319*b5893f02SDimitry Andric{
2320*b5893f02SDimitry Andric    __f_ = nullptr;
2321*b5893f02SDimitry Andric    return *this;
2322*b5893f02SDimitry Andric}
2323*b5893f02SDimitry Andric
2324*b5893f02SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2325*b5893f02SDimitry Andrictemplate <class _Fp, class>
2326*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>&
2327*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
2328*b5893f02SDimitry Andric{
2329*b5893f02SDimitry Andric    function(_VSTD::forward<_Fp>(__f)).swap(*this);
2330*b5893f02SDimitry Andric    return *this;
2331*b5893f02SDimitry Andric}
2332*b5893f02SDimitry Andric
2333*b5893f02SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2334*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::~function() {}
2335*b5893f02SDimitry Andric
2336*b5893f02SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2337*b5893f02SDimitry Andricvoid
2338*b5893f02SDimitry Andricfunction<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
2339*b5893f02SDimitry Andric{
2340*b5893f02SDimitry Andric    __f_.swap(__f.__f_);
2341*b5893f02SDimitry Andric}
2342*b5893f02SDimitry Andric
234394e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
234494e3ee44SDavid Chisnall_Rp
234594e3ee44SDavid Chisnallfunction<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
23467a984708SDavid Chisnall{
2347*b5893f02SDimitry Andric    return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
23487a984708SDavid Chisnall}
23497a984708SDavid Chisnall
23507a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI
23517a984708SDavid Chisnall
235294e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
23537a984708SDavid Chisnallconst std::type_info&
235494e3ee44SDavid Chisnallfunction<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
23557a984708SDavid Chisnall{
2356*b5893f02SDimitry Andric    return __f_.target_type();
23577a984708SDavid Chisnall}
23587a984708SDavid Chisnall
235994e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
236094e3ee44SDavid Chisnalltemplate <typename _Tp>
236194e3ee44SDavid Chisnall_Tp*
236294e3ee44SDavid Chisnallfunction<_Rp(_ArgTypes...)>::target() _NOEXCEPT
23637a984708SDavid Chisnall{
2364*b5893f02SDimitry Andric    return (_Tp*)(__f_.template target<_Tp>());
23657a984708SDavid Chisnall}
23667a984708SDavid Chisnall
236794e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
236894e3ee44SDavid Chisnalltemplate <typename _Tp>
236994e3ee44SDavid Chisnallconst _Tp*
237094e3ee44SDavid Chisnallfunction<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
23717a984708SDavid Chisnall{
2372*b5893f02SDimitry Andric    return __f_.template target<_Tp>();
23737a984708SDavid Chisnall}
23747a984708SDavid Chisnall
23757a984708SDavid Chisnall#endif  // _LIBCPP_NO_RTTI
23767a984708SDavid Chisnall
237794e3ee44SDavid Chisnalltemplate <class _Rp, class... _ArgTypes>
23787a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
23797a984708SDavid Chisnallbool
238094e3ee44SDavid Chisnalloperator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}
23817a984708SDavid Chisnall
238294e3ee44SDavid Chisnalltemplate <class _Rp, class... _ArgTypes>
23837a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
23847a984708SDavid Chisnallbool
238594e3ee44SDavid Chisnalloperator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;}
23867a984708SDavid Chisnall
238794e3ee44SDavid Chisnalltemplate <class _Rp, class... _ArgTypes>
23887a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
23897a984708SDavid Chisnallbool
239094e3ee44SDavid Chisnalloperator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;}
23917a984708SDavid Chisnall
239294e3ee44SDavid Chisnalltemplate <class _Rp, class... _ArgTypes>
23937a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
23947a984708SDavid Chisnallbool
239594e3ee44SDavid Chisnalloperator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}
23967a984708SDavid Chisnall
239794e3ee44SDavid Chisnalltemplate <class _Rp, class... _ArgTypes>
23987a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
23997a984708SDavid Chisnallvoid
240094e3ee44SDavid Chisnallswap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
24017a984708SDavid Chisnall{return __x.swap(__y);}
24027a984708SDavid Chisnall
2403540d2a8bSDimitry Andric#else // _LIBCPP_CXX03_LANG
24049729cf09SDimitry Andric
24059729cf09SDimitry Andric#include <__functional_03>
24069729cf09SDimitry Andric
24079729cf09SDimitry Andric#endif
24089729cf09SDimitry Andric
24099729cf09SDimitry Andric////////////////////////////////////////////////////////////////////////////////
24109729cf09SDimitry Andric//                                  BIND
24119729cf09SDimitry Andric//==============================================================================
24129729cf09SDimitry Andric
24137a984708SDavid Chisnalltemplate<class _Tp> struct __is_bind_expression : public false_type {};
2414aed8d94eSDimitry Andrictemplate<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_bind_expression
24157a984708SDavid Chisnall    : public __is_bind_expression<typename remove_cv<_Tp>::type> {};
24167a984708SDavid Chisnall
2417aed8d94eSDimitry Andric#if _LIBCPP_STD_VER > 14
2418aed8d94eSDimitry Andrictemplate <class _Tp>
241930785c0eSDimitry Andric_LIBCPP_INLINE_VAR constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value;
2420aed8d94eSDimitry Andric#endif
2421aed8d94eSDimitry Andric
24227a984708SDavid Chisnalltemplate<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
2423aed8d94eSDimitry Andrictemplate<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_placeholder
24247a984708SDavid Chisnall    : public __is_placeholder<typename remove_cv<_Tp>::type> {};
24257a984708SDavid Chisnall
2426aed8d94eSDimitry Andric#if _LIBCPP_STD_VER > 14
2427aed8d94eSDimitry Andrictemplate <class _Tp>
242830785c0eSDimitry Andric_LIBCPP_INLINE_VAR constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value;
2429aed8d94eSDimitry Andric#endif
2430aed8d94eSDimitry Andric
24317a984708SDavid Chisnallnamespace placeholders
24327a984708SDavid Chisnall{
24337a984708SDavid Chisnall
243494e3ee44SDavid Chisnalltemplate <int _Np> struct __ph {};
24357a984708SDavid Chisnall
24364ba319b5SDimitry Andric#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
24377c82a1ecSDimitry Andric_LIBCPP_FUNC_VIS extern const __ph<1>   _1;
24387c82a1ecSDimitry Andric_LIBCPP_FUNC_VIS extern const __ph<2>   _2;
24397c82a1ecSDimitry Andric_LIBCPP_FUNC_VIS extern const __ph<3>   _3;
24407c82a1ecSDimitry Andric_LIBCPP_FUNC_VIS extern const __ph<4>   _4;
24417c82a1ecSDimitry Andric_LIBCPP_FUNC_VIS extern const __ph<5>   _5;
24427c82a1ecSDimitry Andric_LIBCPP_FUNC_VIS extern const __ph<6>   _6;
24437c82a1ecSDimitry Andric_LIBCPP_FUNC_VIS extern const __ph<7>   _7;
24447c82a1ecSDimitry Andric_LIBCPP_FUNC_VIS extern const __ph<8>   _8;
24457c82a1ecSDimitry Andric_LIBCPP_FUNC_VIS extern const __ph<9>   _9;
24467c82a1ecSDimitry Andric_LIBCPP_FUNC_VIS extern const __ph<10> _10;
24477c82a1ecSDimitry Andric#else
244830785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr __ph<1>   _1{};
244930785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr __ph<2>   _2{};
245030785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr __ph<3>   _3{};
245130785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr __ph<4>   _4{};
245230785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr __ph<5>   _5{};
245330785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr __ph<6>   _6{};
245430785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr __ph<7>   _7{};
245530785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr __ph<8>   _8{};
245630785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr __ph<9>   _9{};
245730785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr __ph<10> _10{};
24584ba319b5SDimitry Andric#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
24597a984708SDavid Chisnall
24607a984708SDavid Chisnall}  // placeholders
24617a984708SDavid Chisnall
246294e3ee44SDavid Chisnalltemplate<int _Np>
246394e3ee44SDavid Chisnallstruct __is_placeholder<placeholders::__ph<_Np> >
246494e3ee44SDavid Chisnall    : public integral_constant<int, _Np> {};
24657a984708SDavid Chisnall
24669729cf09SDimitry Andric
2467540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
24689729cf09SDimitry Andric
24697a984708SDavid Chisnalltemplate <class _Tp, class _Uj>
24707a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
24717a984708SDavid Chisnall_Tp&
24727a984708SDavid Chisnall__mu(reference_wrapper<_Tp> __t, _Uj&)
24737a984708SDavid Chisnall{
24747a984708SDavid Chisnall    return __t.get();
24757a984708SDavid Chisnall}
24767a984708SDavid Chisnall
24777a984708SDavid Chisnalltemplate <class _Ti, class ..._Uj, size_t ..._Indx>
24787a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
24797a984708SDavid Chisnalltypename __invoke_of<_Ti&, _Uj...>::type
24807a984708SDavid Chisnall__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
24817a984708SDavid Chisnall{
2482d72607e9SDimitry Andric    return __ti(_VSTD::forward<_Uj>(_VSTD::get<_Indx>(__uj))...);
24837a984708SDavid Chisnall}
24847a984708SDavid Chisnall
24857a984708SDavid Chisnalltemplate <class _Ti, class ..._Uj>
24867a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
2487d72607e9SDimitry Andrictypename __lazy_enable_if
24887a984708SDavid Chisnall<
24897a984708SDavid Chisnall    is_bind_expression<_Ti>::value,
2490d72607e9SDimitry Andric    __invoke_of<_Ti&, _Uj...>
24917a984708SDavid Chisnall>::type
24927a984708SDavid Chisnall__mu(_Ti& __ti, tuple<_Uj...>& __uj)
24937a984708SDavid Chisnall{
24947a984708SDavid Chisnall    typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
24957a984708SDavid Chisnall    return  __mu_expand(__ti, __uj, __indices());
24967a984708SDavid Chisnall}
24977a984708SDavid Chisnall
24987a984708SDavid Chisnalltemplate <bool IsPh, class _Ti, class _Uj>
24997a984708SDavid Chisnallstruct __mu_return2 {};
25007a984708SDavid Chisnall
25017a984708SDavid Chisnalltemplate <class _Ti, class _Uj>
25027a984708SDavid Chisnallstruct __mu_return2<true, _Ti, _Uj>
25037a984708SDavid Chisnall{
25047a984708SDavid Chisnall    typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;
25057a984708SDavid Chisnall};
25067a984708SDavid Chisnall
25077a984708SDavid Chisnalltemplate <class _Ti, class _Uj>
25087a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
25097a984708SDavid Chisnalltypename enable_if
25107a984708SDavid Chisnall<
25117a984708SDavid Chisnall    0 < is_placeholder<_Ti>::value,
25127a984708SDavid Chisnall    typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type
25137a984708SDavid Chisnall>::type
25147a984708SDavid Chisnall__mu(_Ti&, _Uj& __uj)
25157a984708SDavid Chisnall{
25167a984708SDavid Chisnall    const size_t _Indx = is_placeholder<_Ti>::value - 1;
2517d72607e9SDimitry Andric    return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
25187a984708SDavid Chisnall}
25197a984708SDavid Chisnall
25207a984708SDavid Chisnalltemplate <class _Ti, class _Uj>
25217a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
25227a984708SDavid Chisnalltypename enable_if
25237a984708SDavid Chisnall<
25247a984708SDavid Chisnall    !is_bind_expression<_Ti>::value &&
25257a984708SDavid Chisnall    is_placeholder<_Ti>::value == 0 &&
25267a984708SDavid Chisnall    !__is_reference_wrapper<_Ti>::value,
25277a984708SDavid Chisnall    _Ti&
25287a984708SDavid Chisnall>::type
252994e3ee44SDavid Chisnall__mu(_Ti& __ti, _Uj&)
25307a984708SDavid Chisnall{
25317a984708SDavid Chisnall    return __ti;
25327a984708SDavid Chisnall}
25337a984708SDavid Chisnall
25347a984708SDavid Chisnalltemplate <class _Ti, bool IsReferenceWrapper, bool IsBindEx, bool IsPh,
25357a984708SDavid Chisnall          class _TupleUj>
2536*b5893f02SDimitry Andricstruct __mu_return_impl;
25377a984708SDavid Chisnall
25384bab9fd9SDavid Chisnalltemplate <bool _Invokable, class _Ti, class ..._Uj>
2539*b5893f02SDimitry Andricstruct __mu_return_invokable  // false
25404bab9fd9SDavid Chisnall{
25414bab9fd9SDavid Chisnall    typedef __nat type;
25424bab9fd9SDavid Chisnall};
25434bab9fd9SDavid Chisnall
25447a984708SDavid Chisnalltemplate <class _Ti, class ..._Uj>
2545*b5893f02SDimitry Andricstruct __mu_return_invokable<true, _Ti, _Uj...>
25467a984708SDavid Chisnall{
25477a984708SDavid Chisnall    typedef typename __invoke_of<_Ti&, _Uj...>::type type;
25487a984708SDavid Chisnall};
25497a984708SDavid Chisnall
25504bab9fd9SDavid Chisnalltemplate <class _Ti, class ..._Uj>
2551*b5893f02SDimitry Andricstruct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> >
2552*b5893f02SDimitry Andric    : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>
25534bab9fd9SDavid Chisnall{
25544bab9fd9SDavid Chisnall};
25554bab9fd9SDavid Chisnall
25567a984708SDavid Chisnalltemplate <class _Ti, class _TupleUj>
2557*b5893f02SDimitry Andricstruct __mu_return_impl<_Ti, false, false, true, _TupleUj>
25587a984708SDavid Chisnall{
25597a984708SDavid Chisnall    typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
25607a984708SDavid Chisnall                                   _TupleUj>::type&& type;
25617a984708SDavid Chisnall};
25627a984708SDavid Chisnall
25637a984708SDavid Chisnalltemplate <class _Ti, class _TupleUj>
2564*b5893f02SDimitry Andricstruct __mu_return_impl<_Ti, true, false, false, _TupleUj>
25657a984708SDavid Chisnall{
25667a984708SDavid Chisnall    typedef typename _Ti::type& type;
25677a984708SDavid Chisnall};
25687a984708SDavid Chisnall
25697a984708SDavid Chisnalltemplate <class _Ti, class _TupleUj>
2570*b5893f02SDimitry Andricstruct __mu_return_impl<_Ti, false, false, false, _TupleUj>
25717a984708SDavid Chisnall{
25727a984708SDavid Chisnall    typedef _Ti& type;
25737a984708SDavid Chisnall};
25747a984708SDavid Chisnall
25757a984708SDavid Chisnalltemplate <class _Ti, class _TupleUj>
25767a984708SDavid Chisnallstruct __mu_return
2577*b5893f02SDimitry Andric    : public __mu_return_impl<_Ti,
25787a984708SDavid Chisnall                              __is_reference_wrapper<_Ti>::value,
25797a984708SDavid Chisnall                              is_bind_expression<_Ti>::value,
25801bf9f7c1SDimitry Andric                              0 < is_placeholder<_Ti>::value &&
25811bf9f7c1SDimitry Andric                              is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value,
25827a984708SDavid Chisnall                              _TupleUj>
25837a984708SDavid Chisnall{
25847a984708SDavid Chisnall};
25857a984708SDavid Chisnall
258694e3ee44SDavid Chisnalltemplate <class _Fp, class _BoundArgs, class _TupleUj>
2587854fa44bSDimitry Andricstruct __is_valid_bind_return
25881bf9f7c1SDimitry Andric{
25891bf9f7c1SDimitry Andric    static const bool value = false;
25901bf9f7c1SDimitry Andric};
25911bf9f7c1SDimitry Andric
25921bf9f7c1SDimitry Andrictemplate <class _Fp, class ..._BoundArgs, class _TupleUj>
2593854fa44bSDimitry Andricstruct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
25941bf9f7c1SDimitry Andric{
25951bf9f7c1SDimitry Andric    static const bool value = __invokable<_Fp,
25961bf9f7c1SDimitry Andric                    typename __mu_return<_BoundArgs, _TupleUj>::type...>::value;
25971bf9f7c1SDimitry Andric};
25981bf9f7c1SDimitry Andric
25991bf9f7c1SDimitry Andrictemplate <class _Fp, class ..._BoundArgs, class _TupleUj>
2600854fa44bSDimitry Andricstruct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
26011bf9f7c1SDimitry Andric{
26021bf9f7c1SDimitry Andric    static const bool value = __invokable<_Fp,
26031bf9f7c1SDimitry Andric                    typename __mu_return<const _BoundArgs, _TupleUj>::type...>::value;
26041bf9f7c1SDimitry Andric};
26051bf9f7c1SDimitry Andric
26061bf9f7c1SDimitry Andrictemplate <class _Fp, class _BoundArgs, class _TupleUj,
2607854fa44bSDimitry Andric          bool = __is_valid_bind_return<_Fp, _BoundArgs, _TupleUj>::value>
26087a984708SDavid Chisnallstruct __bind_return;
26097a984708SDavid Chisnall
261094e3ee44SDavid Chisnalltemplate <class _Fp, class ..._BoundArgs, class _TupleUj>
26111bf9f7c1SDimitry Andricstruct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true>
26127a984708SDavid Chisnall{
26137a984708SDavid Chisnall    typedef typename __invoke_of
26147a984708SDavid Chisnall    <
261594e3ee44SDavid Chisnall        _Fp&,
26167a984708SDavid Chisnall        typename __mu_return
26177a984708SDavid Chisnall        <
26187a984708SDavid Chisnall            _BoundArgs,
26197a984708SDavid Chisnall            _TupleUj
26207a984708SDavid Chisnall        >::type...
26217a984708SDavid Chisnall    >::type type;
26227a984708SDavid Chisnall};
26237a984708SDavid Chisnall
262494e3ee44SDavid Chisnalltemplate <class _Fp, class ..._BoundArgs, class _TupleUj>
26251bf9f7c1SDimitry Andricstruct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true>
26267a984708SDavid Chisnall{
26277a984708SDavid Chisnall    typedef typename __invoke_of
26287a984708SDavid Chisnall    <
262994e3ee44SDavid Chisnall        _Fp&,
26307a984708SDavid Chisnall        typename __mu_return
26317a984708SDavid Chisnall        <
26327a984708SDavid Chisnall            const _BoundArgs,
26337a984708SDavid Chisnall            _TupleUj
26347a984708SDavid Chisnall        >::type...
26357a984708SDavid Chisnall    >::type type;
26367a984708SDavid Chisnall};
26377a984708SDavid Chisnall
263894e3ee44SDavid Chisnalltemplate <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
26397a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
264094e3ee44SDavid Chisnalltypename __bind_return<_Fp, _BoundArgs, _Args>::type
264194e3ee44SDavid Chisnall__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
26427a984708SDavid Chisnall                _Args&& __args)
26437a984708SDavid Chisnall{
26440f5676f4SDimitry Andric    return _VSTD::__invoke(__f, _VSTD::__mu(_VSTD::get<_Indx>(__bound_args), __args)...);
26457a984708SDavid Chisnall}
26467a984708SDavid Chisnall
264794e3ee44SDavid Chisnalltemplate<class _Fp, class ..._BoundArgs>
26487a984708SDavid Chisnallclass __bind
264994e3ee44SDavid Chisnall    : public __weak_result_type<typename decay<_Fp>::type>
26507a984708SDavid Chisnall{
26511bf9f7c1SDimitry Andricprotected:
265294e3ee44SDavid Chisnall    typedef typename decay<_Fp>::type _Fd;
26537a984708SDavid Chisnall    typedef tuple<typename decay<_BoundArgs>::type...> _Td;
26541bf9f7c1SDimitry Andricprivate:
26557a984708SDavid Chisnall    _Fd __f_;
26567a984708SDavid Chisnall    _Td __bound_args_;
26577a984708SDavid Chisnall
26587a984708SDavid Chisnall    typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
26597a984708SDavid Chisnallpublic:
2660936e9439SDimitry Andric    template <class _Gp, class ..._BA,
2661936e9439SDimitry Andric              class = typename enable_if
2662936e9439SDimitry Andric                               <
26634bab9fd9SDavid Chisnall                                  is_constructible<_Fd, _Gp>::value &&
26644bab9fd9SDavid Chisnall                                  !is_same<typename remove_reference<_Gp>::type,
26654bab9fd9SDavid Chisnall                                           __bind>::value
2666936e9439SDimitry Andric                               >::type>
26677a984708SDavid Chisnall      _LIBCPP_INLINE_VISIBILITY
266894e3ee44SDavid Chisnall      explicit __bind(_Gp&& __f, _BA&& ...__bound_args)
266994e3ee44SDavid Chisnall        : __f_(_VSTD::forward<_Gp>(__f)),
26707a984708SDavid Chisnall          __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}
26717a984708SDavid Chisnall
26727a984708SDavid Chisnall    template <class ..._Args>
26737a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
26747a984708SDavid Chisnall        typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type
26757a984708SDavid Chisnall        operator()(_Args&& ...__args)
26767a984708SDavid Chisnall        {
26770f5676f4SDimitry Andric            return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
26787a984708SDavid Chisnall                                  tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
26797a984708SDavid Chisnall        }
26807a984708SDavid Chisnall
26817a984708SDavid Chisnall    template <class ..._Args>
26827a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
26831bf9f7c1SDimitry Andric        typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type
26847a984708SDavid Chisnall        operator()(_Args&& ...__args) const
26857a984708SDavid Chisnall        {
26860f5676f4SDimitry Andric            return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
26877a984708SDavid Chisnall                                   tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
26887a984708SDavid Chisnall        }
26897a984708SDavid Chisnall};
26907a984708SDavid Chisnall
269194e3ee44SDavid Chisnalltemplate<class _Fp, class ..._BoundArgs>
269294e3ee44SDavid Chisnallstruct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {};
26937a984708SDavid Chisnall
269494e3ee44SDavid Chisnalltemplate<class _Rp, class _Fp, class ..._BoundArgs>
26957a984708SDavid Chisnallclass __bind_r
269694e3ee44SDavid Chisnall    : public __bind<_Fp, _BoundArgs...>
26977a984708SDavid Chisnall{
269894e3ee44SDavid Chisnall    typedef __bind<_Fp, _BoundArgs...> base;
26991bf9f7c1SDimitry Andric    typedef typename base::_Fd _Fd;
27001bf9f7c1SDimitry Andric    typedef typename base::_Td _Td;
27017a984708SDavid Chisnallpublic:
270294e3ee44SDavid Chisnall    typedef _Rp result_type;
27037a984708SDavid Chisnall
27047a984708SDavid Chisnall
27054bab9fd9SDavid Chisnall    template <class _Gp, class ..._BA,
27064bab9fd9SDavid Chisnall              class = typename enable_if
27074bab9fd9SDavid Chisnall                               <
27084bab9fd9SDavid Chisnall                                  is_constructible<_Fd, _Gp>::value &&
27094bab9fd9SDavid Chisnall                                  !is_same<typename remove_reference<_Gp>::type,
27104bab9fd9SDavid Chisnall                                           __bind_r>::value
27114bab9fd9SDavid Chisnall                               >::type>
27127a984708SDavid Chisnall      _LIBCPP_INLINE_VISIBILITY
271394e3ee44SDavid Chisnall      explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
271494e3ee44SDavid Chisnall        : base(_VSTD::forward<_Gp>(__f),
27157a984708SDavid Chisnall               _VSTD::forward<_BA>(__bound_args)...) {}
27167a984708SDavid Chisnall
27177a984708SDavid Chisnall    template <class ..._Args>
27187a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
27191bf9f7c1SDimitry Andric        typename enable_if
27201bf9f7c1SDimitry Andric        <
27211bf9f7c1SDimitry Andric            is_convertible<typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type,
2722854fa44bSDimitry Andric                           result_type>::value || is_void<_Rp>::value,
27237a984708SDavid Chisnall            result_type
27241bf9f7c1SDimitry Andric        >::type
27257a984708SDavid Chisnall        operator()(_Args&& ...__args)
27267a984708SDavid Chisnall        {
2727854fa44bSDimitry Andric            typedef __invoke_void_return_wrapper<_Rp> _Invoker;
2728854fa44bSDimitry Andric            return _Invoker::__call(static_cast<base&>(*this), _VSTD::forward<_Args>(__args)...);
27297a984708SDavid Chisnall        }
27307a984708SDavid Chisnall
27317a984708SDavid Chisnall    template <class ..._Args>
27327a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
27331bf9f7c1SDimitry Andric        typename enable_if
27341bf9f7c1SDimitry Andric        <
27351bf9f7c1SDimitry Andric            is_convertible<typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type,
2736854fa44bSDimitry Andric                           result_type>::value || is_void<_Rp>::value,
27377a984708SDavid Chisnall            result_type
27381bf9f7c1SDimitry Andric        >::type
27397a984708SDavid Chisnall        operator()(_Args&& ...__args) const
27407a984708SDavid Chisnall        {
2741854fa44bSDimitry Andric            typedef __invoke_void_return_wrapper<_Rp> _Invoker;
2742854fa44bSDimitry Andric            return _Invoker::__call(static_cast<base const&>(*this), _VSTD::forward<_Args>(__args)...);
27437a984708SDavid Chisnall        }
27447a984708SDavid Chisnall};
27457a984708SDavid Chisnall
274694e3ee44SDavid Chisnalltemplate<class _Rp, class _Fp, class ..._BoundArgs>
274794e3ee44SDavid Chisnallstruct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
27487a984708SDavid Chisnall
274994e3ee44SDavid Chisnalltemplate<class _Fp, class ..._BoundArgs>
27507a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
275194e3ee44SDavid Chisnall__bind<_Fp, _BoundArgs...>
275294e3ee44SDavid Chisnallbind(_Fp&& __f, _BoundArgs&&... __bound_args)
27537a984708SDavid Chisnall{
275494e3ee44SDavid Chisnall    typedef __bind<_Fp, _BoundArgs...> type;
275594e3ee44SDavid Chisnall    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
27567a984708SDavid Chisnall}
27577a984708SDavid Chisnall
275894e3ee44SDavid Chisnalltemplate<class _Rp, class _Fp, class ..._BoundArgs>
27597a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
276094e3ee44SDavid Chisnall__bind_r<_Rp, _Fp, _BoundArgs...>
276194e3ee44SDavid Chisnallbind(_Fp&& __f, _BoundArgs&&... __bound_args)
27627a984708SDavid Chisnall{
276394e3ee44SDavid Chisnall    typedef __bind_r<_Rp, _Fp, _BoundArgs...> type;
276494e3ee44SDavid Chisnall    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
27657a984708SDavid Chisnall}
27667a984708SDavid Chisnall
2767540d2a8bSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
2768854fa44bSDimitry Andric
2769854fa44bSDimitry Andric#if _LIBCPP_STD_VER > 14
27707c82a1ecSDimitry Andric
2771854fa44bSDimitry Andrictemplate <class _Fn, class ..._Args>
2772854fa44bSDimitry Andricresult_of_t<_Fn&&(_Args&&...)>
27737c82a1ecSDimitry Andricinvoke(_Fn&& __f, _Args&&... __args)
27747c82a1ecSDimitry Andric    noexcept(noexcept(_VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...)))
27757c82a1ecSDimitry Andric{
27767c82a1ecSDimitry Andric    return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
2777854fa44bSDimitry Andric}
27787c82a1ecSDimitry Andric
27797c82a1ecSDimitry Andrictemplate <class _DecayFunc>
2780aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __not_fn_imp {
27817c82a1ecSDimitry Andric  _DecayFunc __fd;
27827c82a1ecSDimitry Andric
27837c82a1ecSDimitry Andricpublic:
27847c82a1ecSDimitry Andric    __not_fn_imp() = delete;
27857c82a1ecSDimitry Andric
27867c82a1ecSDimitry Andric    template <class ..._Args>
27877c82a1ecSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
27887c82a1ecSDimitry Andric    auto operator()(_Args&& ...__args) &
27897c82a1ecSDimitry Andric            noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)))
27907c82a1ecSDimitry Andric        -> decltype(          !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))
27917c82a1ecSDimitry Andric        { return              !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); }
27927c82a1ecSDimitry Andric
27937c82a1ecSDimitry Andric    template <class ..._Args>
27947c82a1ecSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
27957c82a1ecSDimitry Andric    auto operator()(_Args&& ...__args) &&
27967c82a1ecSDimitry Andric            noexcept(noexcept(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)))
27977c82a1ecSDimitry Andric        -> decltype(          !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...))
27987c82a1ecSDimitry Andric        { return              !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); }
27997c82a1ecSDimitry Andric
28007c82a1ecSDimitry Andric    template <class ..._Args>
28017c82a1ecSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28027c82a1ecSDimitry Andric    auto operator()(_Args&& ...__args) const&
28037c82a1ecSDimitry Andric            noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)))
28047c82a1ecSDimitry Andric        -> decltype(          !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))
28057c82a1ecSDimitry Andric        { return              !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); }
28067c82a1ecSDimitry Andric
28077c82a1ecSDimitry Andric
28087c82a1ecSDimitry Andric    template <class ..._Args>
28097c82a1ecSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28107c82a1ecSDimitry Andric    auto operator()(_Args&& ...__args) const&&
28117c82a1ecSDimitry Andric            noexcept(noexcept(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)))
28127c82a1ecSDimitry Andric        -> decltype(          !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...))
28137c82a1ecSDimitry Andric        { return              !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); }
28147c82a1ecSDimitry Andric
28157c82a1ecSDimitry Andricprivate:
28167c82a1ecSDimitry Andric    template <class _RawFunc,
28177c82a1ecSDimitry Andric              class = enable_if_t<!is_same<decay_t<_RawFunc>, __not_fn_imp>::value>>
28187c82a1ecSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28197c82a1ecSDimitry Andric    explicit __not_fn_imp(_RawFunc&& __rf)
28207c82a1ecSDimitry Andric        : __fd(_VSTD::forward<_RawFunc>(__rf)) {}
28217c82a1ecSDimitry Andric
28227c82a1ecSDimitry Andric    template <class _RawFunc>
28237c82a1ecSDimitry Andric    friend inline _LIBCPP_INLINE_VISIBILITY
28247c82a1ecSDimitry Andric    __not_fn_imp<decay_t<_RawFunc>> not_fn(_RawFunc&&);
28257c82a1ecSDimitry Andric};
28267c82a1ecSDimitry Andric
28277c82a1ecSDimitry Andrictemplate <class _RawFunc>
28287c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
28297c82a1ecSDimitry Andric__not_fn_imp<decay_t<_RawFunc>> not_fn(_RawFunc&& __fn) {
28307c82a1ecSDimitry Andric    return __not_fn_imp<decay_t<_RawFunc>>(_VSTD::forward<_RawFunc>(__fn));
28317c82a1ecSDimitry Andric}
28327c82a1ecSDimitry Andric
2833854fa44bSDimitry Andric#endif
2834854fa44bSDimitry Andric
28357a984708SDavid Chisnall// struct hash<T*> in <memory>
28367a984708SDavid Chisnall
28374ba319b5SDimitry Andrictemplate <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
28384ba319b5SDimitry Andricpair<_ForwardIterator1, _ForwardIterator1> _LIBCPP_CONSTEXPR_AFTER_CXX11
28394ba319b5SDimitry Andric__search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
28404ba319b5SDimitry Andric         _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred,
28414ba319b5SDimitry Andric         forward_iterator_tag, forward_iterator_tag)
28424ba319b5SDimitry Andric{
28434ba319b5SDimitry Andric    if (__first2 == __last2)
28444ba319b5SDimitry Andric        return make_pair(__first1, __first1);  // Everything matches an empty sequence
28454ba319b5SDimitry Andric    while (true)
28464ba319b5SDimitry Andric    {
28474ba319b5SDimitry Andric        // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks
28484ba319b5SDimitry Andric        while (true)
28494ba319b5SDimitry Andric        {
28504ba319b5SDimitry Andric            if (__first1 == __last1)  // return __last1 if no element matches *__first2
28514ba319b5SDimitry Andric                return make_pair(__last1, __last1);
28524ba319b5SDimitry Andric            if (__pred(*__first1, *__first2))
28534ba319b5SDimitry Andric                break;
28544ba319b5SDimitry Andric            ++__first1;
28554ba319b5SDimitry Andric        }
28564ba319b5SDimitry Andric        // *__first1 matches *__first2, now match elements after here
28574ba319b5SDimitry Andric        _ForwardIterator1 __m1 = __first1;
28584ba319b5SDimitry Andric        _ForwardIterator2 __m2 = __first2;
28594ba319b5SDimitry Andric        while (true)
28604ba319b5SDimitry Andric        {
28614ba319b5SDimitry Andric            if (++__m2 == __last2)  // If pattern exhausted, __first1 is the answer (works for 1 element pattern)
28624ba319b5SDimitry Andric                return make_pair(__first1, __m1);
28634ba319b5SDimitry Andric            if (++__m1 == __last1)  // Otherwise if source exhaused, pattern not found
28644ba319b5SDimitry Andric                return make_pair(__last1, __last1);
28654ba319b5SDimitry Andric            if (!__pred(*__m1, *__m2))  // if there is a mismatch, restart with a new __first1
28664ba319b5SDimitry Andric            {
28674ba319b5SDimitry Andric                ++__first1;
28684ba319b5SDimitry Andric                break;
28694ba319b5SDimitry Andric            }  // else there is a match, check next elements
28704ba319b5SDimitry Andric        }
28714ba319b5SDimitry Andric    }
28724ba319b5SDimitry Andric}
28734ba319b5SDimitry Andric
28744ba319b5SDimitry Andrictemplate <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
28754ba319b5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11
28764ba319b5SDimitry Andricpair<_RandomAccessIterator1, _RandomAccessIterator1>
28774ba319b5SDimitry Andric__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
28784ba319b5SDimitry Andric         _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred,
28794ba319b5SDimitry Andric           random_access_iterator_tag, random_access_iterator_tag)
28804ba319b5SDimitry Andric{
28814ba319b5SDimitry Andric    typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1;
28824ba319b5SDimitry Andric    typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2;
28834ba319b5SDimitry Andric    // Take advantage of knowing source and pattern lengths.  Stop short when source is smaller than pattern
28844ba319b5SDimitry Andric    const _D2 __len2 = __last2 - __first2;
28854ba319b5SDimitry Andric    if (__len2 == 0)
28864ba319b5SDimitry Andric        return make_pair(__first1, __first1);
28874ba319b5SDimitry Andric    const _D1 __len1 = __last1 - __first1;
28884ba319b5SDimitry Andric    if (__len1 < __len2)
28894ba319b5SDimitry Andric        return make_pair(__last1, __last1);
28904ba319b5SDimitry Andric    const _RandomAccessIterator1 __s = __last1 - (__len2 - 1);  // Start of pattern match can't go beyond here
28914ba319b5SDimitry Andric
28924ba319b5SDimitry Andric    while (true)
28934ba319b5SDimitry Andric    {
28944ba319b5SDimitry Andric        while (true)
28954ba319b5SDimitry Andric        {
28964ba319b5SDimitry Andric            if (__first1 == __s)
28974ba319b5SDimitry Andric                return make_pair(__last1, __last1);
28984ba319b5SDimitry Andric            if (__pred(*__first1, *__first2))
28994ba319b5SDimitry Andric                break;
29004ba319b5SDimitry Andric            ++__first1;
29014ba319b5SDimitry Andric        }
29024ba319b5SDimitry Andric
29034ba319b5SDimitry Andric        _RandomAccessIterator1 __m1 = __first1;
29044ba319b5SDimitry Andric        _RandomAccessIterator2 __m2 = __first2;
29054ba319b5SDimitry Andric         while (true)
29064ba319b5SDimitry Andric         {
29074ba319b5SDimitry Andric             if (++__m2 == __last2)
29084ba319b5SDimitry Andric                 return make_pair(__first1, __first1 + __len2);
29094ba319b5SDimitry Andric             ++__m1;          // no need to check range on __m1 because __s guarantees we have enough source
29104ba319b5SDimitry Andric             if (!__pred(*__m1, *__m2))
29114ba319b5SDimitry Andric             {
29124ba319b5SDimitry Andric                 ++__first1;
29134ba319b5SDimitry Andric                 break;
29144ba319b5SDimitry Andric             }
29154ba319b5SDimitry Andric         }
29164ba319b5SDimitry Andric    }
29174ba319b5SDimitry Andric}
29184ba319b5SDimitry Andric
29194ba319b5SDimitry Andric#if _LIBCPP_STD_VER > 14
29204ba319b5SDimitry Andric
29214ba319b5SDimitry Andric// default searcher
29224ba319b5SDimitry Andrictemplate<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
29234ba319b5SDimitry Andricclass _LIBCPP_TYPE_VIS default_searcher {
29244ba319b5SDimitry Andricpublic:
29254ba319b5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29264ba319b5SDimitry Andric    default_searcher(_ForwardIterator __f, _ForwardIterator __l,
29274ba319b5SDimitry Andric                       _BinaryPredicate __p = _BinaryPredicate())
29284ba319b5SDimitry Andric        : __first_(__f), __last_(__l), __pred_(__p) {}
29294ba319b5SDimitry Andric
29304ba319b5SDimitry Andric    template <typename _ForwardIterator2>
29314ba319b5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29324ba319b5SDimitry Andric    pair<_ForwardIterator2, _ForwardIterator2>
29334ba319b5SDimitry Andric    operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
29344ba319b5SDimitry Andric    {
29354ba319b5SDimitry Andric        return _VSTD::__search(__f, __l, __first_, __last_, __pred_,
29364ba319b5SDimitry Andric            typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category(),
29374ba319b5SDimitry Andric            typename _VSTD::iterator_traits<_ForwardIterator2>::iterator_category());
29384ba319b5SDimitry Andric    }
29394ba319b5SDimitry Andric
29404ba319b5SDimitry Andricprivate:
29414ba319b5SDimitry Andric    _ForwardIterator __first_;
29424ba319b5SDimitry Andric    _ForwardIterator __last_;
29434ba319b5SDimitry Andric    _BinaryPredicate __pred_;
29444ba319b5SDimitry Andric    };
29454ba319b5SDimitry Andric
29464ba319b5SDimitry Andric#endif // _LIBCPP_STD_VER > 14
29474ba319b5SDimitry Andric
2948*b5893f02SDimitry Andric#if _LIBCPP_STD_VER > 17
2949*b5893f02SDimitry Andrictemplate <class _Tp>
2950*b5893f02SDimitry Andricusing unwrap_reference_t = typename unwrap_reference<_Tp>::type;
2951*b5893f02SDimitry Andric
2952*b5893f02SDimitry Andrictemplate <class _Tp>
2953*b5893f02SDimitry Andricusing unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
2954*b5893f02SDimitry Andric#endif // > C++17
2955*b5893f02SDimitry Andric
2956*b5893f02SDimitry Andrictemplate <class _Container, class _Predicate>
2957*b5893f02SDimitry Andricinline void __libcpp_erase_if_container( _Container& __c, _Predicate __pred)
2958*b5893f02SDimitry Andric{
2959*b5893f02SDimitry Andric	for (typename _Container::iterator __iter = __c.begin(), __last = __c.end(); __iter != __last;)
2960*b5893f02SDimitry Andric	{
2961*b5893f02SDimitry Andric		if (__pred(*__iter))
2962*b5893f02SDimitry Andric			__iter = __c.erase(__iter);
2963*b5893f02SDimitry Andric		else
2964*b5893f02SDimitry Andric			++__iter;
2965*b5893f02SDimitry Andric	}
2966*b5893f02SDimitry Andric}
2967*b5893f02SDimitry Andric
29687a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD
29697a984708SDavid Chisnall
29707a984708SDavid Chisnall#endif  // _LIBCPP_FUNCTIONAL
2971