diff options
| author | 2016-02-13 21:10:05 -0500 | |
|---|---|---|
| committer | 2016-02-13 21:10:05 -0500 | |
| commit | 0d086616d1af239b8e41b246bea3c1ef85fc907f (patch) | |
| tree | 0dc7778532b0e2d1c5acd0224266b8a67d961155 /src/common/bit_field.h | |
| parent | Merge pull request #1264 from bunnei/fragment-lighting-hw (diff) | |
| parent | BitField: Make trivially copyable and remove assignment operator (diff) | |
| download | yuzu-0d086616d1af239b8e41b246bea3c1ef85fc907f.tar.gz yuzu-0d086616d1af239b8e41b246bea3c1ef85fc907f.tar.xz yuzu-0d086616d1af239b8e41b246bea3c1ef85fc907f.zip | |
Merge pull request #1406 from MerryMage/bitfield2
BitField: Make trivially copyable and remove assignment operator.
Diffstat (limited to 'src/common/bit_field.h')
| -rw-r--r-- | src/common/bit_field.h | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/src/common/bit_field.h b/src/common/bit_field.h index 66689f398..600e0c70c 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h | |||
| @@ -115,29 +115,24 @@ template<std::size_t position, std::size_t bits, typename T> | |||
| 115 | struct BitField | 115 | struct BitField |
| 116 | { | 116 | { |
| 117 | private: | 117 | private: |
| 118 | // This constructor might be considered ambiguous: | 118 | // We hide the copy assigment operator here, because the default copy |
| 119 | // Would it initialize the storage or just the bitfield? | 119 | // assignment would copy the full storage value, rather than just the bits |
| 120 | // Hence, delete it. Use the assignment operator to set bitfield values! | 120 | // relevant to this particular bit field. |
| 121 | BitField(T val) = delete; | 121 | // We don't delete it because we want BitField to be trivially copyable. |
| 122 | BitField& operator=(const BitField&) = default; | ||
| 122 | 123 | ||
| 123 | public: | 124 | public: |
| 125 | // This constructor and assignment operator might be considered ambiguous: | ||
| 126 | // Would they initialize the storage or just the bitfield? | ||
| 127 | // Hence, delete them. Use the Assign method to set bitfield values! | ||
| 128 | BitField(T val) = delete; | ||
| 129 | BitField& operator=(T val) = delete; | ||
| 130 | |||
| 124 | // Force default constructor to be created | 131 | // Force default constructor to be created |
| 125 | // so that we can use this within unions | 132 | // so that we can use this within unions |
| 126 | BitField() = default; | 133 | BitField() = default; |
| 127 | 134 | ||
| 128 | // We explicitly delete the copy assigment operator here, because the | 135 | FORCE_INLINE operator T() const { |
| 129 | // default copy assignment would copy the full storage value, rather than | ||
| 130 | // just the bits relevant to this particular bit field. | ||
| 131 | BitField& operator=(const BitField&) = delete; | ||
| 132 | |||
| 133 | FORCE_INLINE BitField& operator=(T val) | ||
| 134 | { | ||
| 135 | Assign(val); | ||
| 136 | return *this; | ||
| 137 | } | ||
| 138 | |||
| 139 | FORCE_INLINE operator T() const | ||
| 140 | { | ||
| 141 | return Value(); | 136 | return Value(); |
| 142 | } | 137 | } |
| 143 | 138 | ||
| @@ -145,8 +140,7 @@ public: | |||
| 145 | storage = (storage & ~GetMask()) | (((StorageType)value << position) & GetMask()); | 140 | storage = (storage & ~GetMask()) | (((StorageType)value << position) & GetMask()); |
| 146 | } | 141 | } |
| 147 | 142 | ||
| 148 | FORCE_INLINE T Value() const | 143 | FORCE_INLINE T Value() const { |
| 149 | { | ||
| 150 | if (std::numeric_limits<T>::is_signed) | 144 | if (std::numeric_limits<T>::is_signed) |
| 151 | { | 145 | { |
| 152 | std::size_t shift = 8 * sizeof(T)-bits; | 146 | std::size_t shift = 8 * sizeof(T)-bits; |
| @@ -159,8 +153,7 @@ public: | |||
| 159 | } | 153 | } |
| 160 | 154 | ||
| 161 | // TODO: we may want to change this to explicit operator bool() if it's bug-free in VS2015 | 155 | // TODO: we may want to change this to explicit operator bool() if it's bug-free in VS2015 |
| 162 | FORCE_INLINE bool ToBool() const | 156 | FORCE_INLINE bool ToBool() const { |
| 163 | { | ||
| 164 | return Value() != 0; | 157 | return Value() != 0; |
| 165 | } | 158 | } |
| 166 | 159 | ||
| @@ -176,8 +169,7 @@ private: | |||
| 176 | // Unsigned version of StorageType | 169 | // Unsigned version of StorageType |
| 177 | typedef typename std::make_unsigned<StorageType>::type StorageTypeU; | 170 | typedef typename std::make_unsigned<StorageType>::type StorageTypeU; |
| 178 | 171 | ||
| 179 | FORCE_INLINE StorageType GetMask() const | 172 | FORCE_INLINE StorageType GetMask() const { |
| 180 | { | ||
| 181 | return (((StorageTypeU)~0) >> (8 * sizeof(T)-bits)) << position; | 173 | return (((StorageTypeU)~0) >> (8 * sizeof(T)-bits)) << position; |
| 182 | } | 174 | } |
| 183 | 175 | ||
| @@ -189,6 +181,10 @@ private: | |||
| 189 | static_assert(position < 8 * sizeof(T), "Invalid position"); | 181 | static_assert(position < 8 * sizeof(T), "Invalid position"); |
| 190 | static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); | 182 | static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); |
| 191 | static_assert(bits > 0, "Invalid number of bits"); | 183 | static_assert(bits > 0, "Invalid number of bits"); |
| 192 | static_assert(std::is_standard_layout<T>::value, "Invalid base type"); | 184 | static_assert(std::is_pod<T>::value, "Invalid base type"); |
| 193 | }; | 185 | }; |
| 194 | #pragma pack() | 186 | #pragma pack() |
| 187 | |||
| 188 | #if (__GNUC__ >= 5) || defined __clang__ || defined _MSC_VER | ||
| 189 | static_assert(std::is_trivially_copyable<BitField<0, 1, u32>>::value, "BitField must be trivially copyable"); | ||
| 190 | #endif | ||