summaryrefslogtreecommitdiff
path: root/src/common/bit_field.h
diff options
context:
space:
mode:
authorGravatar Weiyi Wang2019-01-25 12:16:23 -0500
committerGravatar fearlessTobi2019-02-06 17:29:39 +0100
commit6b81ceb060a0e985380bc33d2f51dcc76aad3eb3 (patch)
treec24e09bdd88947696f7ea6827f18a10a847df8bb /src/common/bit_field.h
parentcommon/swap: remove default value for swap type internal storage (diff)
downloadyuzu-6b81ceb060a0e985380bc33d2f51dcc76aad3eb3.tar.gz
yuzu-6b81ceb060a0e985380bc33d2f51dcc76aad3eb3.tar.xz
yuzu-6b81ceb060a0e985380bc33d2f51dcc76aad3eb3.zip
common/bitfield: make it endianness-aware
Diffstat (limited to 'src/common/bit_field.h')
-rw-r--r--src/common/bit_field.h12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/common/bit_field.h b/src/common/bit_field.h
index 21e07925d..bd9e21e1e 100644
--- a/src/common/bit_field.h
+++ b/src/common/bit_field.h
@@ -34,6 +34,7 @@
34#include <limits> 34#include <limits>
35#include <type_traits> 35#include <type_traits>
36#include "common/common_funcs.h" 36#include "common/common_funcs.h"
37#include "common/swap.h"
37 38
38/* 39/*
39 * Abstract bitfield class 40 * Abstract bitfield class
@@ -108,7 +109,7 @@
108 * symptoms. 109 * symptoms.
109 */ 110 */
110#pragma pack(1) 111#pragma pack(1)
111template <std::size_t Position, std::size_t Bits, typename T> 112template <std::size_t Position, std::size_t Bits, typename T, typename EndianTag = LETag>
112struct BitField { 113struct BitField {
113private: 114private:
114 // We hide the copy assigment operator here, because the default copy 115 // We hide the copy assigment operator here, because the default copy
@@ -127,6 +128,8 @@ private:
127 // We store the value as the unsigned type to avoid undefined behaviour on value shifting 128 // We store the value as the unsigned type to avoid undefined behaviour on value shifting
128 using StorageType = std::make_unsigned_t<UnderlyingType>; 129 using StorageType = std::make_unsigned_t<UnderlyingType>;
129 130
131 using StorageTypeWithEndian = typename AddEndian<StorageType, EndianTag>::type;
132
130public: 133public:
131 /// Constants to allow limited introspection of fields if needed 134 /// Constants to allow limited introspection of fields if needed
132 static constexpr std::size_t position = Position; 135 static constexpr std::size_t position = Position;
@@ -172,7 +175,7 @@ public:
172 } 175 }
173 176
174 constexpr FORCE_INLINE void Assign(const T& value) { 177 constexpr FORCE_INLINE void Assign(const T& value) {
175 storage = (storage & ~mask) | FormatValue(value); 178 storage = (static_cast<StorageType>(storage) & ~mask) | FormatValue(value);
176 } 179 }
177 180
178 constexpr T Value() const { 181 constexpr T Value() const {
@@ -184,7 +187,7 @@ public:
184 } 187 }
185 188
186private: 189private:
187 StorageType storage; 190 StorageTypeWithEndian storage;
188 191
189 static_assert(bits + position <= 8 * sizeof(T), "Bitfield out of range"); 192 static_assert(bits + position <= 8 * sizeof(T), "Bitfield out of range");
190 193
@@ -195,3 +198,6 @@ private:
195 static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable in a BitField"); 198 static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable in a BitField");
196}; 199};
197#pragma pack() 200#pragma pack()
201
202template <std::size_t Position, std::size_t Bits, typename T>
203using BitFieldBE = BitField<Position, Bits, T, BETag>;