From cc7b2a0ab83f2b11f2c7ba59da10084f29a392d2 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Wed, 10 Nov 2021 14:29:27 +0530 Subject: [PATCH] Introduce `OffsetMember` for offset-based union members The offset of a member in a structure was determined by its relative position and compiler alignment. This is unoptimal for larger structures such as those found in GPU Engines that are primarily named by offset rather than relative positioning and end up requiring a massive amount of padding to function as is. A solution to this problem was simply to supply member offsets directly which can be done by using `OffsetMember` alongside a `union`. --- app/src/main/cpp/skyline/common/utils.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/app/src/main/cpp/skyline/common/utils.h b/app/src/main/cpp/skyline/common/utils.h index b37f124d..c7a2c22c 100644 --- a/app/src/main/cpp/skyline/common/utils.h +++ b/app/src/main/cpp/skyline/common/utils.h @@ -55,7 +55,7 @@ namespace skyline::util { return static_cast(item); } - template + template concept IsPointerOrUnsignedIntegral = (std::is_unsigned_v && std::is_integral_v) || std::is_pointer_v; /** @@ -231,4 +231,24 @@ namespace skyline::util { To BitCast(const From &from) { return *reinterpret_cast(&from); } + + /** + * @brief A utility type for placing elements by offset in unions rather than relative position in structs + * @tparam PadType The type of a unit of padding, total size of padding is `sizeof(PadType) * Offset` + */ + template + struct OffsetMember { + private: + PadType _pad_[Offset]; + ValueType value; + + public: + ValueType &operator*() { + return value; + } + + ValueType *operator->() { + return &value; + } + }; }