1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef HIVIEW_NAPI_UTIL 17 #define HIVIEW_NAPI_UTIL 18 #include <utility> 19 20 namespace util { 21 template <typename ReturnType, typename... Args> 22 struct function_traits_defs { 23 static constexpr size_t arity = sizeof...(Args); 24 25 using result_type = ReturnType; 26 27 template <size_t i> 28 struct arg { 29 using type = typename std::tuple_element<i, std::tuple<Args...>>::type; 30 }; 31 }; 32 33 template <typename T> 34 struct function_traits_impl; 35 36 template <typename ReturnType, typename... Args> 37 struct function_traits_impl<ReturnType(Args...)> 38 : function_traits_defs<ReturnType, Args...> {}; 39 40 template <typename ReturnType, typename... Args> 41 struct function_traits_impl<ReturnType(*)(Args...)> 42 : function_traits_defs<ReturnType, Args...> {}; 43 44 template <typename ClassType, typename ReturnType, typename... Args> 45 struct function_traits_impl<ReturnType(ClassType::*)(Args...)> 46 : function_traits_defs<ReturnType, Args...> {}; 47 48 template <typename ClassType, typename ReturnType, typename... Args> 49 struct function_traits_impl<ReturnType(ClassType::*)(Args...) const> 50 : function_traits_defs<ReturnType, Args...> {}; 51 52 template <typename ClassType, typename ReturnType, typename... Args> 53 struct function_traits_impl<ReturnType(ClassType::*)(Args...) const&> 54 : function_traits_defs<ReturnType, Args...> {}; 55 56 template <typename ClassType, typename ReturnType, typename... Args> 57 struct function_traits_impl<ReturnType(ClassType::*)(Args...) const&&> 58 : function_traits_defs<ReturnType, Args...> {}; 59 60 template <typename ClassType, typename ReturnType, typename... Args> 61 struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile> 62 : function_traits_defs<ReturnType, Args...> {}; 63 64 template <typename ClassType, typename ReturnType, typename... Args> 65 struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile&> 66 : function_traits_defs<ReturnType, Args...> {}; 67 68 template <typename ClassType, typename ReturnType, typename... Args> 69 struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile&&> 70 : function_traits_defs<ReturnType, Args...> {}; 71 72 template <typename ClassType, typename ReturnType, typename... Args> 73 struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile> 74 : function_traits_defs<ReturnType, Args...> {}; 75 76 template <typename ClassType, typename ReturnType, typename... Args> 77 struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile&> 78 : function_traits_defs<ReturnType, Args...> {}; 79 80 template <typename ClassType, typename ReturnType, typename... Args> 81 struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile&&> 82 : function_traits_defs<ReturnType, Args...> {}; 83 84 template <typename T, typename V = void> 85 struct function_traits 86 : function_traits_impl<T> {}; 87 88 template <typename T> 89 struct function_traits<T, decltype((void)&T::operator())> 90 : function_traits_impl<decltype(&T::operator())> {}; 91 92 template <size_t... Indices> 93 struct indices { 94 using next = indices<Indices..., sizeof...(Indices)>; 95 }; 96 template <size_t N> 97 struct build_indices { 98 using type = typename build_indices<N - 1>::type::next; 99 }; 100 template <> 101 struct build_indices<0> { 102 using type = indices<>; 103 }; 104 template <size_t N> 105 using BuildIndices = typename build_indices<N>::type; 106 107 namespace details { 108 template <typename FuncType, 109 typename VecType, 110 size_t... I, 111 typename Traits = function_traits<FuncType>, 112 typename ReturnT = typename Traits::result_type> 113 ReturnT do_call(FuncType& func, VecType& args, indices<I...>) 114 { 115 return func(args[I]...); 116 } 117 } // namespace details 118 119 template < 120 typename FuncType, 121 typename VecType, 122 typename Traits = function_traits<FuncType>, 123 typename ReturnT = typename Traits::result_type> 124 ReturnT unpack_caller(FuncType& func, VecType& args) 125 { 126 return details::do_call(func, args, BuildIndices<Traits::arity>()); 127 } 128 } // namespace util 129 #endif // HIVIEW_NAPI_UTIL 130