///////////////////////////////////////////////////////////////////////////// // Copyright (c) Electronic Arts Inc. All rights reserved. ///////////////////////////////////////////////////////////////////////////// #ifndef EASTL_INTERNAL_MEM_FN_H #define EASTL_INTERNAL_MEM_FN_H #if defined(EA_PRAGMA_ONCE_SUPPORTED) #pragma once #endif //////////////////////////////////////////////////////////////////////////////// // The code in this file is a modification of the libcxx implementation. We copy // the license information here as required. // // We implement only enough of mem_fn to implement eastl::function. //////////////////////////////////////////////////////////////////////////////// //===------------------------ functional ----------------------------------===// // // 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. // //===----------------------------------------------------------------------===// namespace eastl { // // apply_cv // template ::type>::value, bool = is_volatile::type>::value> struct apply_cv { typedef U type; }; template struct apply_cv { typedef const U type; }; template struct apply_cv { typedef volatile U type; }; template struct apply_cv { typedef const volatile U type; }; template struct apply_cv { typedef U& type; }; template struct apply_cv { typedef const U& type; }; template struct apply_cv { typedef volatile U& type; }; template struct apply_cv { typedef const volatile U& type; }; // // has_result_type // template struct has_result_type { private: template static eastl::no_type test(...); template static eastl::yes_type test(typename U::result_type* = 0); public: static const bool value = sizeof(test(0)) == sizeof(eastl::yes_type); }; // // derives_from_unary_function // derives_from_binary_function // template struct derives_from_unary_function { private: static eastl::no_type test(...); template static unary_function test(const volatile unary_function*); public: static const bool value = !is_same::value; typedef decltype(test((T*)0)) type; }; template struct derives_from_binary_function { private: static eastl::no_type test(...); template static binary_function test(const volatile binary_function*); public: static const bool value = !is_same::value; typedef decltype(test((T*)0)) type; }; // // maybe_derives_from_unary_function // maybe_derives_from_binary_function // template ::value> struct maybe_derive_from_unary_function // bool is true : public derives_from_unary_function::type { }; template struct maybe_derive_from_unary_function { }; template ::value> struct maybe_derive_from_binary_function // bool is true : public derives_from_binary_function::type { }; template struct maybe_derive_from_binary_function { }; // // weak_result_type_imp // template ::value> struct weak_result_type_imp // bool is true : public maybe_derive_from_unary_function, public maybe_derive_from_binary_function { typedef typename T::result_type result_type; }; template struct weak_result_type_imp : public maybe_derive_from_unary_function, public maybe_derive_from_binary_function { }; // // weak_result_type // template struct weak_result_type : public weak_result_type_imp { }; // 0 argument case template struct weak_result_type { typedef R result_type; }; template struct weak_result_type { typedef R result_type; }; template struct weak_result_type { typedef R result_type; }; // 1 argument case template struct weak_result_type : public unary_function { }; template struct weak_result_type : public unary_function { }; template struct weak_result_type : public unary_function { }; template struct weak_result_type : public unary_function { }; template struct weak_result_type : public unary_function { }; template struct weak_result_type : public unary_function { }; template struct weak_result_type : public unary_function { }; // 2 argument case template struct weak_result_type : public binary_function { }; template struct weak_result_type : public binary_function { }; template struct weak_result_type : public binary_function { }; template struct weak_result_type : public binary_function { }; template struct weak_result_type : public binary_function { }; template struct weak_result_type : public binary_function { }; template struct weak_result_type : public binary_function { }; // 3 or more arguments #if EASTL_VARIADIC_TEMPLATES_ENABLED template struct weak_result_type { typedef R result_type; }; template struct weak_result_type { typedef R result_type; }; template struct weak_result_type { typedef R result_type; }; template struct weak_result_type { typedef R result_type; }; template struct weak_result_type { typedef R result_type; }; template struct weak_result_type { typedef R result_type; }; template struct weak_result_type { typedef R result_type; }; #endif //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // mem_fn_impl // template class mem_fn_impl #if defined(_MSC_VER) && (_MSC_VER >= 1900) // VS2015 or later // Due to a (seemingly random) internal compiler error on VS2013 we disable eastl::unary_function and // binary_function support for eastl::mem_fn as its not widely (if at all) used. If you require this support // on VS2013 or below please contact us. : public weak_result_type #endif { public: typedef T type; private: type func; public: EASTL_FORCE_INLINE mem_fn_impl(type _func) : func(_func) {} #if EASTL_VARIADIC_TEMPLATES_ENABLED template typename invoke_result::type operator()(ArgTypes&&... args) const { return invoke(func, eastl::forward(args)...); } #else typename invoke_result::type operator()() const { return invoke_impl(func); } template typename invoke_result0::type operator()(A0& a0) const { return invoke(func, a0); } template typename invoke_result1::type operator()(A0& a0, A1& a1) const { return invoke(func, a0, a1); } template typename invoke_result2::type operator()(A0& a0, A1& a1, A2& a2) const { return invoke(func, a0, a1, a2); } #endif }; // mem_fn_impl //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // mem_fn -> mem_fn_impl adapters // template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R T::*pm) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)()) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0)) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0, A1)) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0, A1, A2)) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)() const) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0) const) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0, A1) const) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0, A1, A2) const) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)() volatile) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0) volatile) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0, A1) volatile) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0, A1, A2) volatile) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)() const volatile) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0) const volatile) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0, A1) const volatile) { return mem_fn_impl(pm); } template EASTL_FORCE_INLINE mem_fn_impl mem_fn(R (T::*pm)(A0, A1, A2) const volatile) { return mem_fn_impl(pm); } } // namespace eastl #endif // EASTL_INTERNAL_MEM_FN_H