diff options
author | Tony Wasserka <neobrainx@gmail.com> | 2014-07-17 12:23:54 +0200 |
---|---|---|
committer | Tony Wasserka <neobrainx@gmail.com> | 2014-07-17 12:23:54 +0200 |
commit | b6213784a4706d6d70ed6425e417d0c22bfc3fc8 (patch) | |
tree | 9e43235f35576d5bf966b78e36a36d2d119b898f | |
parent | Merge pull request #29 from bunnei/address-arbiters (diff) | |
parent | BitField: Cast enum values to proper integer type. (diff) | |
download | yuzu-b6213784a4706d6d70ed6425e417d0c22bfc3fc8.tar yuzu-b6213784a4706d6d70ed6425e417d0c22bfc3fc8.tar.gz yuzu-b6213784a4706d6d70ed6425e417d0c22bfc3fc8.tar.bz2 yuzu-b6213784a4706d6d70ed6425e417d0c22bfc3fc8.tar.lz yuzu-b6213784a4706d6d70ed6425e417d0c22bfc3fc8.tar.xz yuzu-b6213784a4706d6d70ed6425e417d0c22bfc3fc8.tar.zst yuzu-b6213784a4706d6d70ed6425e417d0c22bfc3fc8.zip |
-rw-r--r-- | src/common/bit_field.h | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/common/bit_field.h b/src/common/bit_field.h index dfd00d198..b6f0179c6 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h @@ -124,14 +124,35 @@ public: // so that we can use this within unions BitField() = default; +#ifndef _WIN32 + // We explicitly delete the copy assigment operator here, because the + // default copy assignment would copy the full storage value, rather than + // just the bits relevant to this particular bit field. + // Ideally, we would just implement the copy assignment to copy only the + // relevant bits, but this requires compiler support for unrestricted + // unions. + // MSVC 2013 has no support for this, hence we disable this code on + // Windows (so that the default copy assignment operator will be used). + // For any C++11 conformant compiler we delete the operator to make sure + // we never use this inappropriate operator to begin with. + // TODO: Implement this operator properly once all target compilers + // support unrestricted unions. + BitField& operator=(const BitField&) = delete; +#endif + __forceinline BitField& operator=(T val) { - storage = (storage & ~GetMask()) | ((val << position) & GetMask()); + storage = (storage & ~GetMask()) | (((StorageType)val << position) & GetMask()); return *this; } __forceinline operator T() const { + return Value(); + } + + __forceinline T Value() const + { if (std::numeric_limits<T>::is_signed) { std::size_t shift = 8 * sizeof(T)-bits; @@ -168,5 +189,6 @@ private: static_assert(position < 8 * sizeof(T), "Invalid position"); static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); static_assert(bits > 0, "Invalid number of bits"); + static_assert(std::is_standard_layout<T>::value, "Invalid base type"); }; #pragma pack() |