diff options
| author | Léo Lam <leo@leolam.fr> | 2021-05-08 00:21:15 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-08 00:21:15 +0200 |
| commit | a6f6211ddeaa87fee5009df7ba467ef733fa3fcf (patch) | |
| tree | f0677c763f4960d8373b2bb424a4d93ead8a0df3 /Source/Core/Common | |
| parent | 049b92b7ef51b8aaa0f3a9370c3e8bccd44d185b (diff) | |
| parent | 0f7c9ef76783ac8c93d3fb099b43cede1e6915f4 (diff) | |
Merge pull request #9633 from Pokechu22/BitfieldExtract-pointer-to-member
Change BitfieldExtract to use a pointer to the bitfield member
Diffstat (limited to 'Source/Core/Common')
| -rw-r--r-- | Source/Core/Common/BitField.h | 4 | ||||
| -rw-r--r-- | Source/Core/Common/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | Source/Core/Common/TypeUtils.h | 70 |
3 files changed, 73 insertions, 2 deletions
diff --git a/Source/Core/Common/BitField.h b/Source/Core/Common/BitField.h index e7af066d2f..b3a3a41cbc 100644 --- a/Source/Core/Common/BitField.h +++ b/Source/Core/Common/BitField.h @@ -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 diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 4846601305..fc955c1487 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -125,6 +125,7 @@ add_library(common TraversalClient.cpp TraversalClient.h TraversalProto.h + TypeUtils.h UPnP.cpp UPnP.h VariantUtil.h diff --git a/Source/Core/Common/TypeUtils.h b/Source/Core/Common/TypeUtils.h new file mode 100644 index 0000000000..c87bd3f546 --- /dev/null +++ b/Source/Core/Common/TypeUtils.h @@ -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 |
