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.
This commit is contained in:
parent
439619c827
commit
9ed9f4c565
6 changed files with 56 additions and 13 deletions
|
@ -6,21 +6,64 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Dynarmic {
|
namespace Dynarmic {
|
||||||
namespace mp {
|
namespace mp {
|
||||||
|
|
||||||
template<typename MemFnT>
|
/// Used to provide information about an arbitrary function.
|
||||||
struct MemFnInfo;
|
template <typename Function>
|
||||||
|
struct FunctionInfo;
|
||||||
|
|
||||||
/// This struct provides information about a member function pointer.
|
/**
|
||||||
template<typename T, typename ReturnT, typename ...Args>
|
* Partial specialization for function types.
|
||||||
struct MemFnInfo<ReturnT (T::*)(Args...)> {
|
*
|
||||||
using class_type = T;
|
* This is used as the supporting base for all other specializations.
|
||||||
using return_type = ReturnT;
|
*/
|
||||||
|
template <typename R, typename... Args>
|
||||||
|
struct FunctionInfo<R(Args...)>
|
||||||
|
{
|
||||||
|
using return_type = R;
|
||||||
static constexpr size_t args_count = sizeof...(Args);
|
static constexpr size_t args_count = sizeof...(Args);
|
||||||
|
|
||||||
|
template <size_t ParameterIndex>
|
||||||
|
struct Parameter
|
||||||
|
{
|
||||||
|
static_assert(args_count != 0 && ParameterIndex < args_count - 1, "Non-existent function parameter index");
|
||||||
|
using type = std::tuple_element_t<ParameterIndex, std::tuple<Args...>>;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Partial specialization for function pointers
|
||||||
|
template <typename R, typename... Args>
|
||||||
|
struct FunctionInfo<R(*)(Args...)> : public FunctionInfo<R(Args...)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Partial specialization for member function pointers.
|
||||||
|
template <typename C, typename R, typename... Args>
|
||||||
|
struct FunctionInfo<R(C::*)(Args...)> : public FunctionInfo<R(Args...)>
|
||||||
|
{
|
||||||
|
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 <typename Function, size_t ParameterIndex>
|
||||||
|
using parameter_type_t = typename FunctionInfo<Function>::template Parameter<ParameterIndex>::type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper template for retrieving the return type of a function.
|
||||||
|
*
|
||||||
|
* @tparam Function The function type to get the return type of.
|
||||||
|
*/
|
||||||
|
template <typename Function>
|
||||||
|
using return_type_t = typename FunctionInfo<Function>::return_type;
|
||||||
|
|
||||||
} // namespace mp
|
} // namespace mp
|
||||||
} // namespace Dynarmic
|
} // namespace Dynarmic
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace Arm {
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename Visitor>
|
||||||
struct ArmMatcher {
|
struct ArmMatcher {
|
||||||
using CallRetT = typename mp::MemFnInfo<decltype(&Visitor::arm_UDF)>::return_type;
|
using CallRetT = mp::return_type_t<decltype(&Visitor::arm_UDF)>;
|
||||||
|
|
||||||
ArmMatcher(const char* const name, u32 mask, u32 expect, std::function<CallRetT(Visitor&, u32)> fn)
|
ArmMatcher(const char* const name, u32 mask, u32 expect, std::function<CallRetT(Visitor&, u32)> fn)
|
||||||
: name(name), mask(mask), expect(expect), fn(fn) {}
|
: name(name), mask(mask), expect(expect), fn(fn) {}
|
||||||
|
|
|
@ -127,8 +127,8 @@ public:
|
||||||
*/
|
*/
|
||||||
template<typename FnT>
|
template<typename FnT>
|
||||||
static auto GetMatcher(FnT fn, const char* const name, const char* const bitstring) {
|
static auto GetMatcher(FnT fn, const char* const name, const char* const bitstring) {
|
||||||
using Visitor = typename mp::MemFnInfo<FnT>::class_type;
|
using Visitor = typename mp::FunctionInfo<FnT>::class_type;
|
||||||
constexpr size_t args_count = mp::MemFnInfo<FnT>::args_count;
|
constexpr size_t args_count = mp::FunctionInfo<FnT>::args_count;
|
||||||
using Iota = std::make_index_sequence<args_count>;
|
using Iota = std::make_index_sequence<args_count>;
|
||||||
|
|
||||||
const auto mask_and_expect = GetMaskAndExpect(bitstring);
|
const auto mask_and_expect = GetMaskAndExpect(bitstring);
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace Arm {
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename Visitor>
|
||||||
struct Thumb16Matcher {
|
struct Thumb16Matcher {
|
||||||
using CallRetT = typename mp::MemFnInfo<decltype(&Visitor::thumb16_UDF)>::return_type;
|
using CallRetT = mp::return_type_t<decltype(&Visitor::thumb16_UDF)>;
|
||||||
|
|
||||||
Thumb16Matcher(const char* const name, u16 mask, u16 expect, std::function<CallRetT(Visitor&, u16)> fn)
|
Thumb16Matcher(const char* const name, u16 mask, u16 expect, std::function<CallRetT(Visitor&, u16)> fn)
|
||||||
: name(name), mask(mask), expect(expect), fn(fn) {}
|
: name(name), mask(mask), expect(expect), fn(fn) {}
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace Arm {
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename Visitor>
|
||||||
struct Thumb32Matcher {
|
struct Thumb32Matcher {
|
||||||
using CallRetT = typename mp::MemFnInfo<decltype(&Visitor::thumb32_UDF)>::return_type;
|
using CallRetT = mp::return_type_t<decltype(&Visitor::thumb32_UDF)>;
|
||||||
|
|
||||||
Thumb32Matcher(const char* const name, u32 mask, u32 expect, std::function<CallRetT(Visitor&, u32)> fn)
|
Thumb32Matcher(const char* const name, u32 mask, u32 expect, std::function<CallRetT(Visitor&, u32)> fn)
|
||||||
: name(name), mask(mask), expect(expect), fn(fn) {}
|
: name(name), mask(mask), expect(expect), fn(fn) {}
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace Arm {
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename Visitor>
|
||||||
struct VFP2Matcher {
|
struct VFP2Matcher {
|
||||||
using CallRetT = typename mp::MemFnInfo<decltype(&Visitor::vfp2_VADD)>::return_type;
|
using CallRetT = mp::return_type_t<decltype(&Visitor::vfp2_VADD)>;
|
||||||
|
|
||||||
VFP2Matcher(const char* const name, u32 mask, u32 expect, std::function<CallRetT(Visitor&, u32)> fn)
|
VFP2Matcher(const char* const name, u32 mask, u32 expect, std::function<CallRetT(Visitor&, u32)> fn)
|
||||||
: name(name), mask(mask), expect(expect), fn(fn) {}
|
: name(name), mask(mask), expect(expect), fn(fn) {}
|
||||||
|
|
Loading…
Reference in a new issue