From 9ed9f4c565fa6ee3212ea293d825db67b1a0c7da Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 16 Aug 2016 12:40:04 -0400 Subject: [PATCH] mp: Generalize function information retrieval Generalizes MemFnInfo to be compatible with all function types. Also adds type introspection for arguments, as well as helper templates for the common types supported by all partial specializations. --- src/common/mp.h | 57 +++++++++++++++++++++++---- src/frontend/decoder/arm.h | 2 +- src/frontend/decoder/decoder_detail.h | 4 +- src/frontend/decoder/thumb16.h | 2 +- src/frontend/decoder/thumb32.h | 2 +- src/frontend/decoder/vfp2.h | 2 +- 6 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/common/mp.h b/src/common/mp.h index 6e38cba0..8f72df69 100644 --- a/src/common/mp.h +++ b/src/common/mp.h @@ -6,21 +6,64 @@ #pragma once +#include #include "common/common_types.h" namespace Dynarmic { namespace mp { -template -struct MemFnInfo; +/// Used to provide information about an arbitrary function. +template +struct FunctionInfo; -/// This struct provides information about a member function pointer. -template -struct MemFnInfo { - using class_type = T; - using return_type = ReturnT; +/** + * Partial specialization for function types. + * + * This is used as the supporting base for all other specializations. + */ +template +struct FunctionInfo +{ + using return_type = R; static constexpr size_t args_count = sizeof...(Args); + + template + struct Parameter + { + static_assert(args_count != 0 && ParameterIndex < args_count - 1, "Non-existent function parameter index"); + using type = std::tuple_element_t>; + }; }; +/// Partial specialization for function pointers +template +struct FunctionInfo : public FunctionInfo +{ +}; + +/// Partial specialization for member function pointers. +template +struct FunctionInfo : public FunctionInfo +{ + using class_type = C; +}; + +/** + * Helper template for retrieving the type of a function parameter. + * + * @tparam Function An arbitrary function type. + * @tparam ParameterIndex Zero-based index indicating which parameter to get the type of. + */ +template +using parameter_type_t = typename FunctionInfo::template Parameter::type; + +/** + * Helper template for retrieving the return type of a function. + * + * @tparam Function The function type to get the return type of. + */ +template +using return_type_t = typename FunctionInfo::return_type; + } // namespace mp } // namespace Dynarmic diff --git a/src/frontend/decoder/arm.h b/src/frontend/decoder/arm.h index 6e5d3eb4..264bd2cf 100644 --- a/src/frontend/decoder/arm.h +++ b/src/frontend/decoder/arm.h @@ -22,7 +22,7 @@ namespace Arm { template struct ArmMatcher { - using CallRetT = typename mp::MemFnInfo::return_type; + using CallRetT = mp::return_type_t; ArmMatcher(const char* const name, u32 mask, u32 expect, std::function fn) : name(name), mask(mask), expect(expect), fn(fn) {} diff --git a/src/frontend/decoder/decoder_detail.h b/src/frontend/decoder/decoder_detail.h index 76a53b0a..d5f4d0ca 100644 --- a/src/frontend/decoder/decoder_detail.h +++ b/src/frontend/decoder/decoder_detail.h @@ -127,8 +127,8 @@ public: */ template static auto GetMatcher(FnT fn, const char* const name, const char* const bitstring) { - using Visitor = typename mp::MemFnInfo::class_type; - constexpr size_t args_count = mp::MemFnInfo::args_count; + using Visitor = typename mp::FunctionInfo::class_type; + constexpr size_t args_count = mp::FunctionInfo::args_count; using Iota = std::make_index_sequence; const auto mask_and_expect = GetMaskAndExpect(bitstring); diff --git a/src/frontend/decoder/thumb16.h b/src/frontend/decoder/thumb16.h index 2a1689f6..4c32c24b 100644 --- a/src/frontend/decoder/thumb16.h +++ b/src/frontend/decoder/thumb16.h @@ -20,7 +20,7 @@ namespace Arm { template struct Thumb16Matcher { - using CallRetT = typename mp::MemFnInfo::return_type; + using CallRetT = mp::return_type_t; Thumb16Matcher(const char* const name, u16 mask, u16 expect, std::function fn) : name(name), mask(mask), expect(expect), fn(fn) {} diff --git a/src/frontend/decoder/thumb32.h b/src/frontend/decoder/thumb32.h index 49bc7a77..381d5c64 100644 --- a/src/frontend/decoder/thumb32.h +++ b/src/frontend/decoder/thumb32.h @@ -20,7 +20,7 @@ namespace Arm { template struct Thumb32Matcher { - using CallRetT = typename mp::MemFnInfo::return_type; + using CallRetT = mp::return_type_t; Thumb32Matcher(const char* const name, u32 mask, u32 expect, std::function fn) : name(name), mask(mask), expect(expect), fn(fn) {} diff --git a/src/frontend/decoder/vfp2.h b/src/frontend/decoder/vfp2.h index 7fe85a6f..d3aa110f 100644 --- a/src/frontend/decoder/vfp2.h +++ b/src/frontend/decoder/vfp2.h @@ -20,7 +20,7 @@ namespace Arm { template struct VFP2Matcher { - using CallRetT = typename mp::MemFnInfo::return_type; + using CallRetT = mp::return_type_t; VFP2Matcher(const char* const name, u32 mask, u32 expect, std::function fn) : name(name), mask(mask), expect(expect), fn(fn) {}