function.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #pragma once
  2. #include "typetraits.h"
  3. #include "typelist.h"
  4. #include <functional>
  5. namespace NPrivate {
  6. template <class F>
  7. struct TRemoveClassImpl {
  8. using TSignature = F;
  9. };
  10. #define Y_EMPTY_REF_QUALIFIER
  11. #define Y_FOR_EACH_REF_QUALIFIERS_COMBINATION(XX) \
  12. XX(Y_EMPTY_REF_QUALIFIER) \
  13. XX(&) \
  14. XX(&&) \
  15. XX(const) \
  16. XX(const&) \
  17. XX(const&&)
  18. #define Y_DECLARE_REMOVE_CLASS_IMPL(qualifiers) \
  19. template <typename C, typename R, typename... Args> \
  20. struct TRemoveClassImpl<R (C::*)(Args...) qualifiers> { \
  21. typedef R TSignature(Args...); \
  22. };
  23. Y_FOR_EACH_REF_QUALIFIERS_COMBINATION(Y_DECLARE_REMOVE_CLASS_IMPL)
  24. #undef Y_DECLARE_REMOVE_CLASS_IMPL
  25. template <class T>
  26. struct TRemoveNoExceptImpl {
  27. using Type = T;
  28. };
  29. template <typename R, typename... Args>
  30. struct TRemoveNoExceptImpl<R(Args...) noexcept> {
  31. using Type = R(Args...);
  32. };
  33. #define Y_DECLARE_REMOVE_NOEXCEPT_IMPL(qualifiers) \
  34. template <typename R, typename C, typename... Args> \
  35. struct TRemoveNoExceptImpl<R (C::*)(Args...) qualifiers noexcept> { \
  36. using Type = R (C::*)(Args...); \
  37. };
  38. Y_FOR_EACH_REF_QUALIFIERS_COMBINATION(Y_DECLARE_REMOVE_NOEXCEPT_IMPL)
  39. #undef Y_DECLARE_REMOVE_NOEXCEPT_IMPL
  40. #undef Y_FOR_EACH_REF_QUALIFIERS_COMBINATION
  41. #undef Y_EMPTY_REF_QUALIFIER
  42. template <class T>
  43. using TRemoveNoExcept = typename TRemoveNoExceptImpl<T>::Type;
  44. template <class F>
  45. using TRemoveClass = typename TRemoveClassImpl<TRemoveNoExcept<F>>::TSignature;
  46. template <class C>
  47. struct TFuncInfo {
  48. using TSignature = TRemoveClass<decltype(&C::operator())>;
  49. };
  50. template <class R, typename... Args>
  51. struct TFuncInfo<R(Args...)> {
  52. using TResult = R;
  53. typedef R TSignature(Args...);
  54. };
  55. }
  56. template <class C>
  57. using TFunctionSignature = typename ::NPrivate::TFuncInfo<::NPrivate::TRemoveClass<std::remove_reference_t<std::remove_pointer_t<C>>>>::TSignature;
  58. template <typename F>
  59. struct TCallableTraits: public TCallableTraits<TFunctionSignature<F>> {
  60. };
  61. template <typename R, typename... Args>
  62. struct TCallableTraits<R(Args...)> {
  63. using TResult = R;
  64. using TArgs = TTypeList<Args...>;
  65. typedef R TSignature(Args...);
  66. };
  67. template <typename C>
  68. using TFunctionResult = typename TCallableTraits<C>::TResult;
  69. template <typename C>
  70. using TFunctionArgs = typename TCallableTraits<C>::TArgs;
  71. template <typename C, size_t N>
  72. struct TFunctionArgImpl {
  73. using TArgs = TFunctionArgs<C>;
  74. using TResult = typename TArgs::template TGet<N>;
  75. };
  76. template <typename C, size_t N>
  77. using TFunctionArg = typename TFunctionArgImpl<C, N>::TResult;
  78. // temporary before std::apply appearance
  79. template <typename F, typename Tuple, size_t... I>
  80. auto ApplyImpl(F&& f, Tuple&& t, std::index_sequence<I...>) {
  81. return f(std::get<I>(std::forward<Tuple>(t))...);
  82. }
  83. // change to std::apply after c++ 17
  84. template <typename F, typename Tuple>
  85. auto Apply(F&& f, Tuple&& t) {
  86. return ApplyImpl(f, t, std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{});
  87. }
  88. // change to std::apply after c++ 17
  89. template <typename F>
  90. auto Apply(F&& f, std::tuple<>) {
  91. return f();
  92. }