| /* |
| * Copyright (c) 2022 Arteris, Inc. and its applicable licensors and |
| * affiliates. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer; |
| * redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution; |
| * neither the name of the copyright holders nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef BASE_TYPETRAITS_HH |
| #define BASE_TYPETRAITS_HH |
| |
| #include <tuple> |
| #include <type_traits> |
| |
| namespace gem5 |
| { |
| |
| /* |
| * Type traits that enable inspecting the signature of a member function based |
| * on a pointer to that function. Specifically, these type traits provide a |
| * class_t, a return_t and a argsTuple_t alias that correspond respectively to |
| * the class that the function is a member of, the return type of the member |
| * function and the list of parameters types packed in a tuple. Convenience |
| * Convenience template aliases are also provided. |
| * |
| * Example, assuming "struct Struct {void foo(int, bool);};": |
| * - MemberFunctionClass_t<&Struct::foo> is Struct. |
| * - MemberFunctionReturn_t<&Struct::foo> is void. |
| * - MemberFunctionArgsTuple_t<&Struct::foo> is std::tuple<int, bool>. |
| */ |
| |
| template<typename F> |
| struct MemberFunctionSignature; |
| template<typename C, typename R, class... A> |
| struct MemberFunctionSignature<R(C::*)(A...)> |
| { |
| using class_t = C; |
| using return_t = R; |
| using argsTuple_t = std::tuple<A...>; |
| }; |
| template<typename C, typename R, class... A> |
| struct MemberFunctionSignature<R(C::*)(A...) const> |
| { |
| using class_t = std::add_const_t<C>; |
| using return_t = R; |
| using argsTuple_t = std::tuple<A...>; |
| }; |
| template<typename C, typename R, class... A> |
| struct MemberFunctionSignature<R(C::*)(A...) volatile> |
| { |
| using class_t = std::add_volatile_t<C>; |
| using return_t = R; |
| using argsTuple_t = std::tuple<A...>; |
| }; |
| template<typename C, typename R, class... A> |
| struct MemberFunctionSignature<R(C::*)(A...) const volatile> |
| { |
| using class_t = std::add_cv_t<C>; |
| using return_t = R; |
| using argsTuple_t = std::tuple<A...>; |
| }; |
| template<auto F> |
| using MemberFunctionClass_t = |
| typename MemberFunctionSignature<decltype(F)>::class_t; |
| |
| template<auto F> |
| using MemberFunctionReturn_t = |
| typename MemberFunctionSignature<decltype(F)>::return_t; |
| |
| template<auto F> |
| using MemberFunctionArgsTuple_t = |
| typename MemberFunctionSignature<decltype(F)>::argsTuple_t; |
| |
| |
| // iterable type trait |
| template <typename, typename = void> |
| struct is_iterable: std::false_type {}; |
| |
| template <typename T> |
| struct is_iterable<T, |
| std::void_t<decltype(begin(std::declval<T>())), |
| decltype(end(std::declval<T>()))>>: std::true_type {}; |
| |
| template <typename T> |
| constexpr bool is_iterable_v = is_iterable<T>::value; |
| |
| // std::hash-enabled type trait |
| template <typename, typename = void> |
| struct is_std_hash_enabled: std::false_type {}; |
| |
| template <typename T> |
| struct is_std_hash_enabled<T, |
| std::void_t<decltype(std::hash<T>())>>: std::true_type {}; |
| |
| template <typename T> |
| constexpr bool is_std_hash_enabled_v = is_std_hash_enabled<T>::value; |
| |
| } // namespace gem5 |
| |
| #endif // BASE_TYPETRAITS_HH |