Files
CDAG/Research/scene/Material/SignedIntMaterial.h

89 lines
1.8 KiB
C++

#pragma once
#include "../../core/Defines.h"
#include <functional>
#include <vector>
#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<unsigned8> 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<SignedIntMaterial>
{
size_t operator()(SignedIntMaterial const &value) const
{
return (unsigned)value;
}
};
}