SkCallableTraits.h 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright 2018 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef SkCallableTraits_DEFINED
  8. #define SkCallableTraits_DEFINED
  9. #include <type_traits>
  10. #include <tuple>
  11. template <typename R, typename... Args> struct sk_base_callable_traits {
  12. using return_type = R;
  13. static constexpr std::size_t arity = sizeof...(Args);
  14. template <std::size_t N> struct argument {
  15. static_assert(N < arity, "");
  16. using type = typename std::tuple_element<N, std::tuple<Args...>>::type;
  17. };
  18. };
  19. #define SK_CALLABLE_TRAITS__COMMA ,
  20. #define SK_CALLABLE_TRAITS__VARARGS(quals, _) \
  21. SK_CALLABLE_TRAITS__INSTANCE(quals,) \
  22. SK_CALLABLE_TRAITS__INSTANCE(quals, SK_CALLABLE_TRAITS__COMMA ...)
  23. #ifdef __cpp_noexcept_function_type
  24. #define SK_CALLABLE_TRAITS__NE_VARARGS(quals, _) \
  25. SK_CALLABLE_TRAITS__VARARGS(quals,) \
  26. SK_CALLABLE_TRAITS__VARARGS(quals noexcept,)
  27. #else
  28. #define SK_CALLABLE_TRAITS__NE_VARARGS(quals, _) \
  29. SK_CALLABLE_TRAITS__VARARGS(quals,)
  30. #endif
  31. #define SK_CALLABLE_TRAITS__REF_NE_VARARGS(quals, _) \
  32. SK_CALLABLE_TRAITS__NE_VARARGS(quals,) \
  33. SK_CALLABLE_TRAITS__NE_VARARGS(quals &,) \
  34. SK_CALLABLE_TRAITS__NE_VARARGS(quals &&,)
  35. #define SK_CALLABLE_TRAITS__CV_REF_NE_VARARGS() \
  36. SK_CALLABLE_TRAITS__REF_NE_VARARGS(,) \
  37. SK_CALLABLE_TRAITS__REF_NE_VARARGS(const,) \
  38. SK_CALLABLE_TRAITS__REF_NE_VARARGS(volatile,) \
  39. SK_CALLABLE_TRAITS__REF_NE_VARARGS(const volatile,)
  40. /** Infer the return_type and argument<N> of a callable type T. */
  41. template <typename T> struct SkCallableTraits : SkCallableTraits<decltype(&T::operator())> {};
  42. // function (..., (const, volatile), (&, &&), noexcept)
  43. #define SK_CALLABLE_TRAITS__INSTANCE(quals, varargs) \
  44. template <typename R, typename... Args> \
  45. struct SkCallableTraits<R(Args... varargs) quals> : sk_base_callable_traits<R, Args...> {};
  46. SK_CALLABLE_TRAITS__CV_REF_NE_VARARGS()
  47. #undef SK_CALLABLE_TRAITS__INSTANCE
  48. // pointer to function (..., noexcept)
  49. #define SK_CALLABLE_TRAITS__INSTANCE(quals, varargs) \
  50. template <typename R, typename... Args> \
  51. struct SkCallableTraits<R(*)(Args... varargs) quals> : sk_base_callable_traits<R, Args...> {};
  52. SK_CALLABLE_TRAITS__NE_VARARGS(,)
  53. #undef SK_CALLABLE_TRAITS__INSTANCE
  54. // pointer to method (..., (const, volatile), (&, &&), noexcept)
  55. #define SK_CALLABLE_TRAITS__INSTANCE(quals, varargs) \
  56. template <typename T, typename R, typename... Args> \
  57. struct SkCallableTraits<R(T::*)(Args... varargs) quals> : sk_base_callable_traits<R, Args...> {};
  58. SK_CALLABLE_TRAITS__CV_REF_NE_VARARGS()
  59. #undef SK_CALLABLE_TRAITS__INSTANCE
  60. // pointer to field
  61. template <typename T, typename R>
  62. struct SkCallableTraits<R T::*> : sk_base_callable_traits<typename std::add_lvalue_reference<R>::type> {};
  63. #undef SK_CALLABLE_TRAITS__CV_REF_NE_VARARGS
  64. #undef SK_CALLABLE_TRAITS__REF_NE_VARARGS
  65. #undef SK_CALLABLE_TRAITS__NE_VARARGS
  66. #undef SK_CALLABLE_TRAITS__VARARGS
  67. #undef SK_CALLABLE_TRAITS__COMMA
  68. #endif