tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FunctionTypeTraits.h (3941B)


      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/. */
      6 
      7 #ifndef mozilla_FunctionTypeTraits_h
      8 #define mozilla_FunctionTypeTraits_h
      9 
     10 #include <cstddef> /* for size_t */
     11 
     12 namespace mozilla {
     13 
     14 // Main FunctionTypeTraits declaration, taking one template argument.
     15 //
     16 // Given a function type, FunctionTypeTraits will expose the following members:
     17 // - ReturnType: Return type.
     18 // - arity: Number of parameters (size_t).
     19 // - ParameterType<N>: Type of the Nth** parameter, 0-indexed.
     20 //
     21 // ** `ParameterType<N>` with `N` >= `arity` is allowed and gives `void`.
     22 // This prevents compilation errors when trying to access a type outside of the
     23 // function's parameters, which is useful for parameters checks, e.g.:
     24 //   template<typename F>
     25 //   auto foo(F&&)
     26 //    -> enable_if(FunctionTypeTraits<F>::arity == 1 &&
     27 //                 is_same<FunctionTypeTraits<F>::template ParameterType<0>,
     28 //                         int>::value,
     29 //                 void)
     30 //   {
     31 //     // This function will only be enabled if `F` takes one `int`.
     32 //     // Without the permissive ParameterType<any N>, it wouldn't even compile.
     33 //
     34 // Note: FunctionTypeTraits does not work with generic lambdas `[](auto&) {}`,
     35 // because parameter types cannot be known until an actual invocation when types
     36 // are inferred from the given arguments.
     37 template <typename T>
     38 struct FunctionTypeTraits;
     39 
     40 // Remove reference and pointer wrappers, if any.
     41 template <typename T>
     42 struct FunctionTypeTraits<T&> : FunctionTypeTraits<T> {};
     43 template <typename T>
     44 struct FunctionTypeTraits<T&&> : FunctionTypeTraits<T> {};
     45 template <typename T>
     46 struct FunctionTypeTraits<T*> : FunctionTypeTraits<T> {};
     47 
     48 // Extract `operator()` function from callables (e.g. lambdas, std::function).
     49 template <typename T>
     50 struct FunctionTypeTraits : FunctionTypeTraits<decltype(&T::operator())> {};
     51 
     52 namespace detail {
     53 template <size_t N, typename... As>
     54 struct SafePackElement;
     55 
     56 template <size_t N>
     57 struct SafePackElement<N> {
     58  using type = void;
     59 };
     60 
     61 template <typename A, typename... As>
     62 struct SafePackElement<0, A, As...> {
     63  using type = A;
     64 };
     65 
     66 template <size_t N, typename A, typename... As>
     67 struct SafePackElement<N, A, As...> : SafePackElement<N - 1, As...> {};
     68 
     69 template <size_t N, typename... As>
     70 using SafePackElementType = typename SafePackElement<N, As...>::type;
     71 
     72 }  // namespace detail
     73 
     74 // Specialization for free functions.
     75 template <typename R, typename... As>
     76 struct FunctionTypeTraits<R(As...)> {
     77  using ReturnType = R;
     78  static constexpr size_t arity = sizeof...(As);
     79  template <size_t N>
     80  using ParameterType = detail::SafePackElementType<N, As...>;
     81 };
     82 
     83 // Specialization for non-const member functions.
     84 template <typename C, typename R, typename... As>
     85 struct FunctionTypeTraits<R (C::*)(As...)> : FunctionTypeTraits<R(As...)> {};
     86 
     87 // Specialization for const member functions.
     88 template <typename C, typename R, typename... As>
     89 struct FunctionTypeTraits<R (C::*)(As...) const>
     90    : FunctionTypeTraits<R(As...)> {};
     91 
     92 #ifdef NS_HAVE_STDCALL
     93 // Specialization for __stdcall free functions.
     94 template <typename R, typename... As>
     95 struct FunctionTypeTraits<R NS_STDCALL(As...)> : FunctionTypeTraits<R(As...)> {
     96 };
     97 
     98 // Specialization for __stdcall non-const member functions.
     99 template <typename C, typename R, typename... As>
    100 struct FunctionTypeTraits<R (NS_STDCALL C::*)(As...)>
    101    : FunctionTypeTraits<R(As...)> {};
    102 
    103 // Specialization for __stdcall const member functions.
    104 template <typename C, typename R, typename... As>
    105 struct FunctionTypeTraits<R (NS_STDCALL C::*)(As...) const>
    106    : FunctionTypeTraits<R(As...)> {};
    107 #endif  // NS_HAVE_STDCALL
    108 
    109 }  // namespace mozilla
    110 
    111 #endif  // mozilla_FunctionTypeTraits_h