#pragma once #include "../../core/Defines.h" #include #include #include "../../core/BitHelper.h" // Sort of like signed int, but the sign is stored in the first bit of the value, instead of storing it as 0xFFFFFFFF struct SignedIntMaterial { private: const static unsigned VALUE_MASK = 0x7FFFFFFF; const static unsigned SIGN_MASK = 0x80000000; unsigned mValue; inline unsigned GetValue() const { return mValue & VALUE_MASK; } inline void SetValue(unsigned value) { mValue &= ~VALUE_MASK; mValue |= value & VALUE_MASK; } inline bool IsNegative() const { return (mValue & SIGN_MASK) != 0; } inline void SetIsNegative(bool isNegative) { mValue &= ~SIGN_MASK; if (isNegative) mValue |= SIGN_MASK; } public: SignedIntMaterial() : mValue(0) {} SignedIntMaterial(unsigned value, bool negative) { SetValue(value); SetIsNegative(negative); } SignedIntMaterial(int value) : SignedIntMaterial(abs(value), value < 0) {} ~SignedIntMaterial() {} SignedIntMaterial& operator=(const int& source) { mValue = source; return *this; } std::vector Serialize() { return BitHelper::SplitInBytes(this->operator unsigned()); } operator unsigned() const { return (unsigned)mValue; } operator int() const { return (int)GetValue() * (IsNegative() ? -1 : 1); } bool operator==(const SignedIntMaterial& other) const { return mValue == other.mValue; } bool operator!=(const SignedIntMaterial& other) const { return !(*this == other); } bool operator<(const SignedIntMaterial& other) const { return this->operator int() < (int)other; } }; // Perfect hash namespace std { template<> struct hash { size_t operator()(SignedIntMaterial const &value) const { return (unsigned)value; } }; }