aboutsummaryrefslogtreecommitdiff
path: root/include/EASTL/internal/mem_fn.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/EASTL/internal/mem_fn.h')
-rw-r--r--include/EASTL/internal/mem_fn.h304
1 files changed, 304 insertions, 0 deletions
diff --git a/include/EASTL/internal/mem_fn.h b/include/EASTL/internal/mem_fn.h
new file mode 100644
index 0000000..1d3e7b3
--- /dev/null
+++ b/include/EASTL/internal/mem_fn.h
@@ -0,0 +1,304 @@
+/////////////////////////////////////////////////////////////////////////////
+// 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 <class T, class U,
+ bool = is_const<typename remove_reference<T>::type>::value,
+ bool = is_volatile<typename remove_reference<T>::type>::value>
+ struct apply_cv { typedef U type; };
+
+ template <class T, class U> struct apply_cv<T, U, true, false> { typedef const U type; };
+ template <class T, class U> struct apply_cv<T, U, false, true> { typedef volatile U type; };
+ template <class T, class U> struct apply_cv<T, U, true, true> { typedef const volatile U type; };
+ template <class T, class U> struct apply_cv<T&, U, false, false> { typedef U& type; };
+ template <class T, class U> struct apply_cv<T&, U, true, false> { typedef const U& type; };
+ template <class T, class U> struct apply_cv<T&, U, false, true> { typedef volatile U& type; };
+ template <class T, class U> struct apply_cv<T&, U, true, true> { typedef const volatile U& type; };
+
+
+
+ //
+ // has_result_type
+ //
+ template <class T>
+ struct has_result_type
+ {
+ private:
+ template <class U>
+ static eastl::no_type test(...);
+
+ template <class U>
+ static eastl::yes_type test(typename U::result_type* = 0);
+
+ public:
+ static const bool value = sizeof(test<T>(0)) == sizeof(eastl::yes_type);
+ };
+
+
+
+ //
+ // derives_from_unary_function
+ // derives_from_binary_function
+ //
+ template <class T>
+ struct derives_from_unary_function
+ {
+ private:
+ static eastl::no_type 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((T*)0)), eastl::no_type>::value;
+ typedef decltype(test((T*)0)) type;
+ };
+
+ template <class T>
+ struct derives_from_binary_function
+ {
+ private:
+ static eastl::no_type 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((T*)0)), eastl::no_type>::value;
+ typedef decltype(test((T*)0)) type;
+ };
+
+
+
+ //
+ // maybe_derives_from_unary_function
+ // maybe_derives_from_binary_function
+ //
+ template <class T, bool = derives_from_unary_function<T>::value>
+ struct maybe_derive_from_unary_function // bool is true
+ : public derives_from_unary_function<T>::type { };
+
+ template <class T>
+ struct maybe_derive_from_unary_function<T, false> { };
+
+ template <class T, bool = derives_from_binary_function<T>::value>
+ struct maybe_derive_from_binary_function // bool is true
+ : public derives_from_binary_function<T>::type { };
+
+ template <class T>
+ struct maybe_derive_from_binary_function<T, false> { };
+
+
+
+ //
+ // weak_result_type_imp
+ //
+ template <class T, bool = has_result_type<T>::value>
+ struct weak_result_type_imp // bool is true
+ : public maybe_derive_from_unary_function<T>,
+ public maybe_derive_from_binary_function<T>
+ {
+ typedef typename T::result_type result_type;
+ };
+
+ template <class T>
+ struct weak_result_type_imp<T, false> : public maybe_derive_from_unary_function<T>,
+ public maybe_derive_from_binary_function<T> { };
+
+
+
+ //
+ // weak_result_type
+ //
+ template <class T>
+ struct weak_result_type : public weak_result_type_imp<T> { };
+
+ // 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
+#if EASTL_VARIADIC_TEMPLATES_ENABLED
+ 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; };
+#endif
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // mem_fn_impl
+ //
+ template <class T>
+ 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<T>
+#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 <class... ArgTypes>
+ typename invoke_result<type, ArgTypes...>::type operator()(ArgTypes&&... args) const
+ {
+ return invoke(func, eastl::forward<ArgTypes>(args)...);
+ }
+#else
+ typename invoke_result<type>::type operator()() const { return invoke_impl(func); }
+
+ template <class A0>
+ typename invoke_result0<type, A0>::type operator()(A0& a0) const
+ {
+ return invoke(func, a0);
+ }
+
+ template <class A0, class A1>
+ typename invoke_result1<type, A0, A1>::type operator()(A0& a0, A1& a1) const
+ {
+ return invoke(func, a0, a1);
+ }
+
+ template <class A0, class A1, class A2>
+ typename invoke_result2<type, A0, A1, A2>::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 <class R, class T>
+ EASTL_FORCE_INLINE mem_fn_impl<R T::*> mem_fn(R T::*pm)
+ { return mem_fn_impl<R T::*>(pm); }
+
+ template <class R, class T>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)()> mem_fn(R (T::*pm)())
+ { return mem_fn_impl<R (T::*)()>(pm); }
+
+ template <class R, class T, class A0>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0)> mem_fn(R (T::*pm)(A0))
+ { return mem_fn_impl<R (T::*)(A0)>(pm); }
+
+ template <class R, class T, class A0, class A1>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1)> mem_fn(R (T::*pm)(A0, A1))
+ { return mem_fn_impl<R (T::*)(A0, A1)>(pm); }
+
+ template <class R, class T, class A0, class A1, class A2>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1, A2)> mem_fn(R (T::*pm)(A0, A1, A2))
+ { return mem_fn_impl<R (T::*)(A0, A1, A2)>(pm); }
+
+ template <class R, class T>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)() const> mem_fn(R (T::*pm)() const)
+ { return mem_fn_impl<R (T::*)() const>(pm); }
+
+ template <class R, class T, class A0>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0) const> mem_fn(R (T::*pm)(A0) const)
+ { return mem_fn_impl<R (T::*)(A0) const>(pm); }
+
+ template <class R, class T, class A0, class A1>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1) const> mem_fn(R (T::*pm)(A0, A1) const)
+ { return mem_fn_impl<R (T::*)(A0, A1) const>(pm); }
+
+ template <class R, class T, class A0, class A1, class A2>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1, A2) const> mem_fn(R (T::*pm)(A0, A1, A2) const)
+ { return mem_fn_impl<R (T::*)(A0, A1, A2) const>(pm); }
+
+ template <class R, class T>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)() volatile> mem_fn(R (T::*pm)() volatile)
+ { return mem_fn_impl<R (T::*)() volatile>(pm); }
+
+ template <class R, class T, class A0>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0) volatile> mem_fn(R (T::*pm)(A0) volatile)
+ { return mem_fn_impl<R (T::*)(A0) volatile>(pm); }
+
+ template <class R, class T, class A0, class A1>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1) volatile> mem_fn(R (T::*pm)(A0, A1) volatile)
+ { return mem_fn_impl<R (T::*)(A0, A1) volatile>(pm); }
+
+ template <class R, class T, class A0, class A1, class A2>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1, A2) volatile> mem_fn(R (T::*pm)(A0, A1, A2) volatile)
+ { return mem_fn_impl<R (T::*)(A0, A1, A2) volatile>(pm); }
+
+ template <class R, class T>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)() const volatile> mem_fn(R (T::*pm)() const volatile)
+ { return mem_fn_impl<R (T::*)() const volatile>(pm); }
+
+ template <class R, class T, class A0>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0) const volatile> mem_fn(R (T::*pm)(A0) const volatile)
+ { return mem_fn_impl<R (T::*)(A0) const volatile>(pm); }
+
+ template <class R, class T, class A0, class A1>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1) const volatile> mem_fn(R (T::*pm)(A0, A1) const volatile)
+ { return mem_fn_impl<R (T::*)(A0, A1) const volatile>(pm); }
+
+ template <class R, class T, class A0, class A1, class A2>
+ EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1, A2) const volatile> mem_fn(R (T::*pm)(A0, A1, A2) const volatile)
+ { return mem_fn_impl<R (T::*)(A0, A1, A2) const volatile>(pm); }
+
+} // namespace eastl
+
+#endif // EASTL_INTERNAL_MEM_FN_H