mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
Change BitfieldExtract to use a pointer to the bitfield member
This commit is contained in:
@ -155,8 +155,8 @@ public:
|
||||
|
||||
constexpr T Value() const { return Value(std::is_signed<T>()); }
|
||||
constexpr operator T() const { return Value(); }
|
||||
constexpr std::size_t StartBit() const { return position; }
|
||||
constexpr std::size_t NumBits() const { return bits; }
|
||||
static constexpr std::size_t StartBit() { return position; }
|
||||
static constexpr std::size_t NumBits() { return bits; }
|
||||
|
||||
private:
|
||||
// Unsigned version of StorageType
|
||||
|
@ -125,6 +125,7 @@ add_library(common
|
||||
TraversalClient.cpp
|
||||
TraversalClient.h
|
||||
TraversalProto.h
|
||||
TypeUtils.h
|
||||
UPnP.cpp
|
||||
UPnP.h
|
||||
VariantUtil.h
|
||||
|
70
Source/Core/Common/TypeUtils.h
Normal file
70
Source/Core/Common/TypeUtils.h
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright 2021 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace Common
|
||||
{
|
||||
template <typename>
|
||||
struct MemberPointerInfo;
|
||||
// Helper to get information about a pointer to a data member.
|
||||
// See https://en.cppreference.com/w/cpp/language/pointer#Pointers_to_members
|
||||
// This template takes the type for a member pointer.
|
||||
template <typename M, typename O>
|
||||
struct MemberPointerInfo<M O::*>
|
||||
{
|
||||
using MemberType = M;
|
||||
using ObjectType = O;
|
||||
};
|
||||
|
||||
// This template takes a specific member pointer.
|
||||
template <auto member_pointer>
|
||||
using MemberType = typename MemberPointerInfo<decltype(member_pointer)>::MemberType;
|
||||
|
||||
// This template takes a specific member pointer.
|
||||
template <auto member_pointer>
|
||||
using ObjectType = typename MemberPointerInfo<decltype(member_pointer)>::ObjectType;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <int x>
|
||||
struct Data
|
||||
{
|
||||
static constexpr int GetX() { return x; }
|
||||
};
|
||||
struct Foo
|
||||
{
|
||||
Data<1> a;
|
||||
Data<2> b;
|
||||
int c;
|
||||
};
|
||||
struct Bar : Foo
|
||||
{
|
||||
int d;
|
||||
};
|
||||
|
||||
static_assert(std::is_same_v<MemberType<&Foo::a>, Data<1>>);
|
||||
static_assert(MemberType<&Foo::a>::GetX() == 1);
|
||||
static_assert(std::is_same_v<MemberType<&Foo::b>, Data<2>>);
|
||||
static_assert(MemberType<&Foo::b>::GetX() == 2);
|
||||
static_assert(std::is_same_v<MemberType<&Foo::c>, int>);
|
||||
|
||||
static_assert(std::is_same_v<ObjectType<&Foo::a>, Foo>);
|
||||
static_assert(std::is_same_v<ObjectType<&Foo::b>, Foo>);
|
||||
static_assert(std::is_same_v<ObjectType<&Foo::c>, Foo>);
|
||||
|
||||
static_assert(std::is_same_v<MemberType<&Foo::c>, MemberPointerInfo<int Foo::*>::MemberType>);
|
||||
static_assert(std::is_same_v<ObjectType<&Foo::c>, MemberPointerInfo<int Foo::*>::ObjectType>);
|
||||
|
||||
static_assert(std::is_same_v<MemberType<&Bar::c>, int>);
|
||||
static_assert(std::is_same_v<MemberType<&Bar::d>, int>);
|
||||
|
||||
static_assert(std::is_same_v<ObjectType<&Bar::d>, Bar>);
|
||||
// Somewhat unexpected behavior:
|
||||
static_assert(std::is_same_v<ObjectType<&Bar::c>, Foo>);
|
||||
static_assert(!std::is_same_v<ObjectType<&Bar::c>, Bar>);
|
||||
} // namespace detail
|
||||
} // namespace Common
|
Reference in New Issue
Block a user