Просмотр исходного кода

Merge pull request #30 from neobrain/bitfield_work

BitField additions and fixes
Tony Wasserka 12 лет назад
Родитель
Сommit
b6213784a4
1 измененных файлов с 23 добавлено и 1 удалено
  1. 23 1
      src/common/bit_field.h

+ 23 - 1
src/common/bit_field.h

@@ -124,13 +124,34 @@ 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)
         {
@@ -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()