#pragma once #include template struct BasicEnum { using Self = TSelf; using ValueType = int; int value; BasicEnum() : value{ 0 } {} BasicEnum(int value) : value{ value } {} /// Comparsion between 2 values of enum. Useful for situations like `a == b` where both a and b are TSelf. friend auto operator<=>(const TSelf& a, const TSelf& b) { return a.value <=> b.value; } /// Comparsion between a enum and a raw value. Useful for situations like `a == TSelf::Option` where a is a enum and TSelf::Option is a raw value. friend auto operator<=>(const TSelf& self, int value) { return self.value <=> value; } operator int() const { return value; } operator bool() const { return value; } }; #define ENUM(Name) struct Name : public BasicEnum #define ENUM_MEMBERS() \ enum Enum : int; \ operator Enum() const { return (Enum)value; } \ using BasicEnum::BasicEnum; \ enum Enum : int template struct BasicFlag { using Self = TSelf; using ValueType = int; int value; BasicFlag() : value{ 0 } {} BasicFlag(int value) : value{ value } {} bool IsSet(TSelf mask) const { return (value & mask.value) == mask.value; } bool IsSetExclusive(TSelf mask) const { return value == mask.value; } void Set(TSelf mask, bool state) { if (state) { value = (int)(value | mask.value); } else { value = (int)(value & ~mask.value); } } /// Comparsion between 2 values of flag. Useful for situations like `a == b` where both a and b are TSelf. friend bool operator==(const TSelf& a, const TSelf& b) { return a.value == b.value; } friend auto operator<=>(const TSelf& a, const TSelf& b) { return a.value <=> b.value; } /// Comparsion between a flag and a raw value. Useful for situations like `a == TSelf::Option` where a is a flag and TSelf::Option is a raw value. friend bool operator==(const TSelf& self, int value) { return self.value == value; } friend auto operator<=>(const TSelf& self, int value) { return self.value <=> value; } friend TSelf operator&(const TSelf& a, const TSelf& b) { return TSelf(a.value & b.value); } friend TSelf operator|(const TSelf& a, const TSelf& b) { return TSelf(a.value | b.value); } friend TSelf operator^(const TSelf& a, const TSelf& b) { return TSelf(a.value ^ b.value); } TSelf operator~() const { return TSelf(~value); } TSelf& operator&=(int that) { value = value & that; return *this; } TSelf& operator|=(int that) { value = value | that; return *this; } TSelf& operator^=(int that) { value = value ^ that; return *this; } };