Update configs. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release ba=release
[gecko.git] / mfbt / FunctionTypeTraits.h
blob83b3bc971ac6bc9009b94a280f537482286508ff
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_FunctionTypeTraits_h
8 #define mozilla_FunctionTypeTraits_h
10 #include <cstddef> /* for size_t */
11 #include <tuple>
13 namespace mozilla {
15 // Main FunctionTypeTraits declaration, taking one template argument.
17 // Given a function type, FunctionTypeTraits will expose the following members:
18 // - ReturnType: Return type.
19 // - arity: Number of parameters (size_t).
20 // - ParameterType<N>: Type of the Nth** parameter, 0-indexed.
22 // ** `ParameterType<N>` with `N` >= `arity` is allowed and gives `void`.
23 // This prevents compilation errors when trying to access a type outside of the
24 // function's parameters, which is useful for parameters checks, e.g.:
25 // template<typename F>
26 // auto foo(F&&)
27 // -> enable_if(FunctionTypeTraits<F>::arity == 1 &&
28 // is_same<FunctionTypeTraits<F>::template ParameterType<0>,
29 // int>::value,
30 // void)
31 // {
32 // // This function will only be enabled if `F` takes one `int`.
33 // // Without the permissive ParameterType<any N>, it wouldn't even compile.
35 // Note: FunctionTypeTraits does not work with generic lambdas `[](auto&) {}`,
36 // because parameter types cannot be known until an actual invocation when types
37 // are inferred from the given arguments.
38 template <typename T>
39 struct FunctionTypeTraits;
41 // Remove reference and pointer wrappers, if any.
42 template <typename T>
43 struct FunctionTypeTraits<T&> : public FunctionTypeTraits<T> {};
44 template <typename T>
45 struct FunctionTypeTraits<T&&> : public FunctionTypeTraits<T> {};
46 template <typename T>
47 struct FunctionTypeTraits<T*> : public FunctionTypeTraits<T> {};
49 // Extract `operator()` function from callables (e.g. lambdas, std::function).
50 template <typename T>
51 struct FunctionTypeTraits
52 : public FunctionTypeTraits<decltype(&T::operator())> {};
54 namespace detail {
56 // If `safe`, retrieve the `N`th type from `As`, otherwise `void`.
57 // See top description for reason.
58 template <bool safe, size_t N, typename... As>
59 struct TupleElementSafe;
60 template <size_t N, typename... As>
61 struct TupleElementSafe<true, N, As...> {
62 using Type = typename std::tuple_element<N, std::tuple<As...>>::type;
64 template <size_t N, typename... As>
65 struct TupleElementSafe<false, N, As...> {
66 using Type = void;
69 template <typename R, typename... As>
70 struct FunctionTypeTraitsHelper {
71 using ReturnType = R;
72 static constexpr size_t arity = sizeof...(As);
73 template <size_t N>
74 using ParameterType =
75 typename TupleElementSafe<(N < sizeof...(As)), N, As...>::Type;
78 } // namespace detail
80 // Specialization for free functions.
81 template <typename R, typename... As>
82 struct FunctionTypeTraits<R(As...)>
83 : detail::FunctionTypeTraitsHelper<R, As...> {};
85 // Specialization for non-const member functions.
86 template <typename C, typename R, typename... As>
87 struct FunctionTypeTraits<R (C::*)(As...)>
88 : detail::FunctionTypeTraitsHelper<R, As...> {};
90 // Specialization for const member functions.
91 template <typename C, typename R, typename... As>
92 struct FunctionTypeTraits<R (C::*)(As...) const>
93 : detail::FunctionTypeTraitsHelper<R, As...> {};
95 #ifdef NS_HAVE_STDCALL
96 // Specialization for __stdcall free functions.
97 template <typename R, typename... As>
98 struct FunctionTypeTraits<R NS_STDCALL(As...)>
99 : detail::FunctionTypeTraitsHelper<R, As...> {};
101 // Specialization for __stdcall non-const member functions.
102 template <typename C, typename R, typename... As>
103 struct FunctionTypeTraits<R (NS_STDCALL C::*)(As...)>
104 : detail::FunctionTypeTraitsHelper<R, As...> {};
106 // Specialization for __stdcall const member functions.
107 template <typename C, typename R, typename... As>
108 struct FunctionTypeTraits<R (NS_STDCALL C::*)(As...) const>
109 : detail::FunctionTypeTraitsHelper<R, As...> {};
110 #endif // NS_HAVE_STDCALL
112 } // namespace mozilla
114 #endif // mozilla_FunctionTypeTraits_h