| /* | |
| * Copyright 2018 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef SkCallableTraits_DEFINED | |
| #define SkCallableTraits_DEFINED | |
| #include <type_traits> | |
| #include <tuple> | |
| template <typename R, typename... Args> struct sk_base_callable_traits { | |
| using return_type = R; | |
| static constexpr std::size_t arity = sizeof...(Args); | |
| template <std::size_t N> struct argument { | |
| static_assert(N < arity, ""); | |
| using type = typename std::tuple_element<N, std::tuple<Args...>>::type; | |
| }; | |
| }; | |
| #define SK_CALLABLE_TRAITS__COMMA , | |
| #define SK_CALLABLE_TRAITS__VARARGS(quals, _) \ | |
| SK_CALLABLE_TRAITS__INSTANCE(quals,) \ | |
| SK_CALLABLE_TRAITS__INSTANCE(quals, SK_CALLABLE_TRAITS__COMMA ...) | |
| #ifdef __cpp_noexcept_function_type | |
| #define SK_CALLABLE_TRAITS__NE_VARARGS(quals, _) \ | |
| SK_CALLABLE_TRAITS__VARARGS(quals,) \ | |
| SK_CALLABLE_TRAITS__VARARGS(quals noexcept,) | |
| #else | |
| #define SK_CALLABLE_TRAITS__NE_VARARGS(quals, _) \ | |
| SK_CALLABLE_TRAITS__VARARGS(quals,) | |
| #endif | |
| #define SK_CALLABLE_TRAITS__REF_NE_VARARGS(quals, _) \ | |
| SK_CALLABLE_TRAITS__NE_VARARGS(quals,) \ | |
| SK_CALLABLE_TRAITS__NE_VARARGS(quals &,) \ | |
| SK_CALLABLE_TRAITS__NE_VARARGS(quals &&,) | |
| #define SK_CALLABLE_TRAITS__CV_REF_NE_VARARGS() \ | |
| SK_CALLABLE_TRAITS__REF_NE_VARARGS(,) \ | |
| SK_CALLABLE_TRAITS__REF_NE_VARARGS(const,) \ | |
| SK_CALLABLE_TRAITS__REF_NE_VARARGS(volatile,) \ | |
| SK_CALLABLE_TRAITS__REF_NE_VARARGS(const volatile,) | |
| /** Infer the return_type and argument<N> of a callable type T. */ | |
| template <typename T> struct SkCallableTraits : SkCallableTraits<decltype(&T::operator())> {}; | |
| // function (..., (const, volatile), (&, &&), noexcept) | |
| #define SK_CALLABLE_TRAITS__INSTANCE(quals, varargs) \ | |
| template <typename R, typename... Args> \ | |
| struct SkCallableTraits<R(Args... varargs) quals> : sk_base_callable_traits<R, Args...> {}; | |
| SK_CALLABLE_TRAITS__CV_REF_NE_VARARGS() | |
| #undef SK_CALLABLE_TRAITS__INSTANCE | |
| // pointer to function (..., noexcept) | |
| #define SK_CALLABLE_TRAITS__INSTANCE(quals, varargs) \ | |
| template <typename R, typename... Args> \ | |
| struct SkCallableTraits<R(*)(Args... varargs) quals> : sk_base_callable_traits<R, Args...> {}; | |
| SK_CALLABLE_TRAITS__NE_VARARGS(,) | |
| #undef SK_CALLABLE_TRAITS__INSTANCE | |
| // pointer to method (..., (const, volatile), (&, &&), noexcept) | |
| #define SK_CALLABLE_TRAITS__INSTANCE(quals, varargs) \ | |
| template <typename T, typename R, typename... Args> \ | |
| struct SkCallableTraits<R(T::*)(Args... varargs) quals> : sk_base_callable_traits<R, Args...> {}; | |
| SK_CALLABLE_TRAITS__CV_REF_NE_VARARGS() | |
| #undef SK_CALLABLE_TRAITS__INSTANCE | |
| // pointer to field | |
| template <typename T, typename R> | |
| struct SkCallableTraits<R T::*> : sk_base_callable_traits<typename std::add_lvalue_reference<R>::type> {}; | |
| #undef SK_CALLABLE_TRAITS__CV_REF_NE_VARARGS | |
| #undef SK_CALLABLE_TRAITS__REF_NE_VARARGS | |
| #undef SK_CALLABLE_TRAITS__NE_VARARGS | |
| #undef SK_CALLABLE_TRAITS__VARARGS | |
| #undef SK_CALLABLE_TRAITS__COMMA | |
| #endif |