huangcm
2025-08-25 f350412dc55c15118d0a7925d1071877498e5e24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
 * 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>
 
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