This is a class that acts as an unsigned integer with a variable amount of bits.
#include <iostream>
#include <cstdint>
// any amount of bits inteter
// note: stores with size of uint64_t
template <uint8_t bits_g>
class uintx_t {
private:
uint64_t Val;
uint8_t bits;
constexpr inline uint64_t _formatBits(
const uint64_t& val,
const uint16_t& _bits
) {return val & UINT64_MAX >> (64-_bits);}
public:
uintx_t(const int64_t& val) {
bits = bits_g;
if (bits > 64) bits = 64;
else if (bits < 1 ) bits = 1;
Val = _formatBits(val, bits);
}
void operator= (uintx_t& val) {
Val = _formatBits(val.Val, bits);
}
void operator= (const int64_t& val) {
Val = _formatBits(val, bits);
}
bool operator== (const int64_t& val) {
return (Val == val);
}
bool operator!= (const int64_t& val) {
return (Val != val);
}
bool operator> (const int64_t& val) {
return (Val > val);
}
bool operator< (const int64_t& val) {
return (Val < val);
}
bool operator>= (const int64_t& val) {
return (Val >= val);
}
bool operator<= (const int64_t& val) {
return (Val <= val);
}
int64_t operator+ (const int64_t& val) {
return (_formatBits(Val + val, bits));
}
int64_t operator- (const int64_t& val) {
return (_formatBits(Val - val, bits));
}
int64_t operator* (const int64_t& val) {
return (_formatBits(Val * val, bits));
}
int64_t operator/ (const int64_t& val) {
return (_formatBits(Val / val, bits));
}
int64_t operator% (const int64_t& val) {
return (_formatBits(Val % val, bits));
}
int64_t operator| (const int64_t& val) {
return (_formatBits(Val | val, bits));
}
int64_t operator& (const int64_t& val) {
return (_formatBits(Val & val, bits));
}
int64_t operator^ (const int64_t& val) {
return (_formatBits(Val ^ val, bits));
}
int64_t operator<< (const int64_t& val) {
return (_formatBits(Val << val, bits));
}
int64_t operator>> (const int64_t& val) {
return (_formatBits(Val >> val, bits));
}
uintx_t& operator++ () {
Val = _formatBits(++Val, bits);
return *this;
}
uintx_t& operator-- () {
Val = _formatBits(--Val, bits);
return *this;
}
uintx_t operator++ (int) {
Val = _formatBits(++Val, bits);
return *this;
}
uintx_t operator-- (int) {
Val = _formatBits(--Val, bits);
return *this;
}
void operator+= (const int64_t& val) {
Val = _formatBits(Val+val, bits);
}
void operator-= (const int64_t& val) {
Val = _formatBits(Val-val, bits);
}
void operator*= (const int64_t& val) {
Val = _formatBits(Val*val, bits);
}
void operator/= (const int64_t& val) {
Val = _formatBits(Val/val, bits);
}
void operator%= (const int64_t& val) {
Val = _formatBits(Val%val, bits);
}
void operator|= (const int64_t& val) {
Val = _formatBits(Val|val, bits);
}
void operator&= (const int64_t& val) {
Val = _formatBits(Val&val, bits);
}
void operator^= (const int64_t& val) {
Val = _formatBits(Val^val, bits);
}
void operator<<= (const int64_t& val) {
Val = _formatBits(Val<<val, bits);
}
void operator>>= (const int64_t& val) {
Val = _formatBits(Val>>val, bits);
}
friend std::ostream& operator<< (
std::ostream& os,
uintx_t& UX
) {
os << std::to_string(UX.Val);
return os;
}
template <typename T>
explicit operator T() const {
return (T)Val;
}
};
The issue I have with this right now is that overloading an operator with another uintx_t
doesn't work without having it casted to another type. I tried to overload the operators specifically for uintx_t
but since 2 objects could have differing amount of bits, I couldn't figure out how to get it to work.