diff options
Diffstat (limited to 'src/common/bit_field.h')
| -rw-r--r-- | src/common/bit_field.h | 12 |
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) |
| 111 | template <std::size_t Position, std::size_t Bits, typename T> | 112 | template <std::size_t Position, std::size_t Bits, typename T, typename EndianTag = LETag> |
| 112 | struct BitField { | 113 | struct BitField { |
| 113 | private: | 114 | private: |
| 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 | |||
| 130 | public: | 133 | public: |
| 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 | ||
| 186 | private: | 189 | private: |
| 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 | |||
| 202 | template <std::size_t Position, std::size_t Bits, typename T> | ||
| 203 | using BitFieldBE = BitField<Position, Bits, T, BETag>; | ||