// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_FUNCTIONAL_BASE
#define _LIBCPP_FUNCTIONAL_BASE

#include <__config>
#include <type_traits>
#include <typeinfo>
#include <exception>

#pragma GCC system_header

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Arg, class _Result>
struct _LIBCPP_VISIBLE unary_function
{
    typedef _Arg    argument_type;
    typedef _Result result_type;
};

template <class _Arg1, class _Arg2, class _Result>
struct _LIBCPP_VISIBLE binary_function
{
    typedef _Arg1   first_argument_type;
    typedef _Arg2   second_argument_type;
    typedef _Result result_type;
};

template <class _Tp> struct _LIBCPP_VISIBLE hash;

template <class _Tp>
struct __has_result_type
{
private:
    struct __two {char _; char __;};
    template <class _Up> static __two __test(...);
    template <class _Up> static char __test(typename _Up::result_type* = 0);
public:
    static const bool value = sizeof(__test<_Tp>(0)) == 1;
};

#ifdef _LIBCPP_HAS_NO_VARIADICS

#include <__functional_base_03>

#else  // _LIBCPP_HAS_NO_VARIADICS

// __weak_result_type

template <class _Tp>
struct __derives_from_unary_function
{
private:
    struct __two {char _; char __;};
    static __two __test(...);
    template <class _A, class _R>
        static unary_function<_A, _R>
        __test(const volatile unary_function<_A, _R>*);
public:
    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
    typedef decltype(__test((_Tp*)0)) type;
};

template <class _Tp>
struct __derives_from_binary_function
{
private:
    struct __two {char _; char __;};
    static __two __test(...);
    template <class _A1, class _A2, class _R>
        static binary_function<_A1, _A2, _R>
        __test(const volatile binary_function<_A1, _A2, _R>*);
public:
    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
    typedef decltype(__test((_Tp*)0)) type;
};

template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
struct __maybe_derive_from_unary_function  // bool is true
    : public __derives_from_unary_function<_Tp>::type
{
};

template <class _Tp>
struct __maybe_derive_from_unary_function<_Tp, false>
{
};

template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
struct __maybe_derive_from_binary_function  // bool is true
    : public __derives_from_binary_function<_Tp>::type
{
};

template <class _Tp>
struct __maybe_derive_from_binary_function<_Tp, false>
{
};

template <class _Tp, bool = __has_result_type<_Tp>::value>
struct __weak_result_type_imp // bool is true
    : public __maybe_derive_from_unary_function<_Tp>,
      public __maybe_derive_from_binary_function<_Tp>
{
    typedef typename _Tp::result_type result_type;
};

template <class _Tp>
struct __weak_result_type_imp<_Tp, false>
    : public __maybe_derive_from_unary_function<_Tp>,
      public __maybe_derive_from_binary_function<_Tp>
{
};

template <class _Tp>
struct __weak_result_type
    : public __weak_result_type_imp<_Tp>
{
};

// 0 argument case

template <class _R>
struct __weak_result_type<_R ()>
{
    typedef _R result_type;
};

template <class _R>
struct __weak_result_type<_R (&)()>
{
    typedef _R result_type;
};

template <class _R>
struct __weak_result_type<_R (*)()>
{
    typedef _R result_type;
};

// 1 argument case

template <class _R, class _A1>
struct __weak_result_type<_R (_A1)>
    : public unary_function<_A1, _R>
{
};

template <class _R, class _A1>
struct __weak_result_type<_R (&)(_A1)>
    : public unary_function<_A1, _R>
{
};

template <class _R, class _A1>
struct __weak_result_type<_R (*)(_A1)>
    : public unary_function<_A1, _R>
{
};

template <class _R, class _C>
struct __weak_result_type<_R (_C::*)()>
    : public unary_function<_C*, _R>
{
};

template <class _R, class _C>
struct __weak_result_type<_R (_C::*)() const>
    : public unary_function<const _C*, _R>
{
};

template <class _R, class _C>
struct __weak_result_type<_R (_C::*)() volatile>
    : public unary_function<volatile _C*, _R>
{
};

template <class _R, class _C>
struct __weak_result_type<_R (_C::*)() const volatile>
    : public unary_function<const volatile _C*, _R>
{
};

// 2 argument case

template <class _R, class _A1, class _A2>
struct __weak_result_type<_R (_A1, _A2)>
    : public binary_function<_A1, _A2, _R>
{
};

template <class _R, class _A1, class _A2>
struct __weak_result_type<_R (*)(_A1, _A2)>
    : public binary_function<_A1, _A2, _R>
{
};

template <class _R, class _A1, class _A2>
struct __weak_result_type<_R (&)(_A1, _A2)>
    : public binary_function<_A1, _A2, _R>
{
};

template <class _R, class _C, class _A1>
struct __weak_result_type<_R (_C::*)(_A1)>
    : public binary_function<_C*, _A1, _R>
{
};

template <class _R, class _C, class _A1>
struct __weak_result_type<_R (_C::*)(_A1) const>
    : public binary_function<const _C*, _A1, _R>
{
};

template <class _R, class _C, class _A1>
struct __weak_result_type<_R (_C::*)(_A1) volatile>
    : public binary_function<volatile _C*, _A1, _R>
{
};

template <class _R, class _C, class _A1>
struct __weak_result_type<_R (_C::*)(_A1) const volatile>
    : public binary_function<const volatile _C*, _A1, _R>
{
};

// 3 or more arguments

template <class _R, class _A1, class _A2, class _A3, class ..._A4>
struct __weak_result_type<_R (_A1, _A2, _A3, _A4...)>
{
    typedef _R result_type;
};

template <class _R, class _A1, class _A2, class _A3, class ..._A4>
struct __weak_result_type<_R (&)(_A1, _A2, _A3, _A4...)>
{
    typedef _R result_type;
};

template <class _R, class _A1, class _A2, class _A3, class ..._A4>
struct __weak_result_type<_R (*)(_A1, _A2, _A3, _A4...)>
{
    typedef _R result_type;
};

template <class _R, class _C, class _A1, class _A2, class ..._A3>
struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...)>
{
    typedef _R result_type;
};

template <class _R, class _C, class _A1, class _A2, class ..._A3>
struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...) const>
{
    typedef _R result_type;
};

template <class _R, class _C, class _A1, class _A2, class ..._A3>
struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...) volatile>
{
    typedef _R result_type;
};

template <class _R, class _C, class _A1, class _A2, class ..._A3>
struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...) const volatile>
{
    typedef _R result_type;
};

// __invoke

// first bullet

template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    sizeof...(_Param) == sizeof...(_Arg) &&
    is_base_of<_T, typename remove_reference<_T1>::type>::value,
    _R
>::type
__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg)
{
    return (_STD::forward<_T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
}

template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    sizeof...(_Param) == sizeof...(_Arg) &&
    is_base_of<_T, typename remove_reference<_T1>::type>::value,
    _R
>::type
__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg)
{
    return (_STD::forward<const _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
}

template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    sizeof...(_Param) == sizeof...(_Arg) &&
    is_base_of<_T, typename remove_reference<_T1>::type>::value,
    _R
>::type
__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg)
{
    return (_STD::forward<volatile _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
}

template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    sizeof...(_Param) == sizeof...(_Arg) &&
    is_base_of<_T, typename remove_reference<_T1>::type>::value,
    _R
>::type
__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg)
{
    return (_STD::forward<const volatile _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
}

// second bullet

template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    sizeof...(_Param) == sizeof...(_Arg) &&
    !is_base_of<_T, typename remove_reference<_T1>::type>::value,
    _R
>::type
__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg)
{
    return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
}

template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    sizeof...(_Param) == sizeof...(_Arg) &&
    !is_base_of<_T, typename remove_reference<_T1>::type>::value,
    _R
>::type
__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg)
{
    return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
}

template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    sizeof...(_Param) == sizeof...(_Arg) &&
    !is_base_of<_T, typename remove_reference<_T1>::type>::value,
    _R
>::type
__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg)
{
    return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
}

template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    sizeof...(_Param) == sizeof...(_Arg) &&
    !is_base_of<_T, typename remove_reference<_T1>::type>::value,
    _R
>::type
__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg)
{
    return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
}

// third bullet

template <class _R, class _T, class _T1>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    is_base_of<_T, typename remove_reference<_T1>::type>::value,
    typename __apply_cv<_T1, _R>::type&&
>::type
__invoke(_R _T::* __f, _T1&& __t1)
{
    return _STD::forward<_T1>(__t1).*__f;
}

// forth bullet

template <class _T1, class _R, bool>
struct __4th_helper
{
};

template <class _T1, class _R>
struct __4th_helper<_T1, _R, true>
{
    typedef typename __apply_cv<decltype(*_STD::declval<_T1>()), _R>::type type;
};

template <class _R, class _T, class _T1>
inline _LIBCPP_INLINE_VISIBILITY
typename __4th_helper<_T1, _R,
                      !is_base_of<_T,
                                  typename remove_reference<_T1>::type
                                 >::value
                     >::type&&
__invoke(_R _T::* __f, _T1&& __t1)
{
    return (*_STD::forward<_T1>(__t1)).*__f;
}

// fifth bullet

template <class _F, class ..._T>
inline _LIBCPP_INLINE_VISIBILITY
typename result_of<_F(_T...)>::type
__invoke(_F&& __f, _T&& ...__t)
{
    return _STD::forward<_F>(__f)(_STD::forward<_T>(__t)...);
}

template <class _Tp, class ..._Args>
struct __invoke_return
{
    typedef decltype(__invoke(_STD::declval<_Tp>(), _STD::declval<_Args>()...)) type;
};

template <class _Tp>
class _LIBCPP_VISIBLE reference_wrapper
    : public __weak_result_type<_Tp>
{
public:
    // types
    typedef _Tp type;
private:
    type* __f_;

public:
    // construct/copy/destroy
    _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) : __f_(&__f) {}
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
#endif

    // access
    _LIBCPP_INLINE_VISIBILITY operator type&    () const {return *__f_;}
    _LIBCPP_INLINE_VISIBILITY          type& get() const {return *__f_;}

    // invoke
    template <class... _ArgTypes>
       _LIBCPP_INLINE_VISIBILITY
       typename __invoke_return<type&, _ArgTypes...>::type
          operator() (_ArgTypes&&... __args) const
          {
              return __invoke(get(), _STD::forward<_ArgTypes>(__args)...);
          }
};

template <class _Tp> struct ____is_reference_wrapper : public false_type {};
template <class _Tp> struct ____is_reference_wrapper<reference_wrapper<_Tp> > : public true_type {};
template <class _Tp> struct __is_reference_wrapper
    : public ____is_reference_wrapper<typename remove_cv<_Tp>::type> {};

template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
reference_wrapper<_Tp>
ref(_Tp& __t)
{
    return reference_wrapper<_Tp>(__t);
}

template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
reference_wrapper<_Tp>
ref(reference_wrapper<_Tp> __t)
{
    return ref(__t.get());
}

template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
reference_wrapper<const _Tp>
cref(const _Tp& __t)
{
    return reference_wrapper<const _Tp>(__t);
}

template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
reference_wrapper<const _Tp>
cref(reference_wrapper<_Tp> __t)
{
    return cref(__t.get());
}

#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS

template <class _Tp> void ref(const _Tp&& __t) = delete;
template <class _Tp> void cref(const _Tp&& __t) = delete;

#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS

template <class _Tp> void ref(const _Tp&& __t);// = delete;
template <class _Tp> void cref(const _Tp&& __t);// = delete;

#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS

#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES

#endif  // _LIBCPP_HAS_NO_VARIADICS

_LIBCPP_END_NAMESPACE_STD

#endif  // _LIBCPP_FUNCTIONAL_BASE
