aboutsummaryrefslogtreecommitdiff
path: root/source/10-common/Enum.hpp
blob: 8ad75baba273db0260e50df779c73a3d1192d2f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#pragma once

#include <initializer_list>
#include <type_traits>

template <class TEnum>
class EnumFlags {
public:
	using Enum = TEnum;
	using Underlying = std::underlying_type_t<TEnum>;

private:
	Underlying mValue;

public:
	EnumFlags()
		: mValue{ 0 } {
	}

	EnumFlags(TEnum e)
		: mValue{ static_cast<Underlying>(1) << static_cast<Underlying>(e) } {
	}

	bool IsSet(EnumFlags mask) const {
		return (mValue & mask.mValue) == mask.mValue;
	}

	bool IsSet(std::initializer_list<TEnum> enums) {
		EnumFlags flags;
		for (auto& e : enums) {
			flags.mValue |= static_cast<Underlying>(e);
		}
		return IsSet(flags);
	}

	bool IsSetExclusive(EnumFlags mask) const {
		return mValue == mask.mValue;
	}

	bool IsSetExclusive(std::initializer_list<TEnum> enums) {
		EnumFlags flags;
		for (auto& e : enums) {
			flags.mValue |= static_cast<Underlying>(e);
		}
		return IsSetExclusive(flags);
	}

	void SetOn(EnumFlags mask) {
		mValue |= mask.mValue;
	}

	void SetOff(EnumFlags mask) {
		mValue &= ~mask.mValue;
	}

	void Set(EnumFlags mask, bool enabled) {
		if (enabled) {
			SetOn(mask);
		} else {
			SetOff(mask);
		}
	}

	EnumFlags& operator|=(EnumFlags that) {
		mValue |= that.mValue;
		return *this;
	}

	EnumFlags& operator&=(EnumFlags that) {
		mValue &= that.mValue;
		return *this;
	}

	EnumFlags& operator^=(EnumFlags that) {
		mValue ^= that.mValue;
		return *this;
	}

	EnumFlags& operator|=(TEnum e) {
		mValue |= 1 << static_cast<Underlying>(e);
		return *this;
	}

	EnumFlags& operator&=(TEnum e) {
		mValue &= 1 << static_cast<Underlying>(e);
		return *this;
	}

	EnumFlags& operator^=(TEnum e) {
		mValue ^= 1 << static_cast<Underlying>(e);
		return *this;
	}

	EnumFlags operator|(EnumFlags that) const { return EnumFlags(mValue | that.mValue); }
	EnumFlags operator&(EnumFlags that) const { return EnumFlags(mValue & that.mValue); }
	EnumFlags operator^(EnumFlags that) const { return EnumFlags(mValue ^ that.mValue); }

	EnumFlags operator|(TEnum e) const { return EnumFlags(mValue | 1 << static_cast<Underlying>(e)); }
	EnumFlags operator&(TEnum e) const { return EnumFlags(mValue & 1 << static_cast<Underlying>(e)); }
	EnumFlags operator^(TEnum e) const { return EnumFlags(mValue ^ 1 << static_cast<Underlying>(e)); }

	EnumFlags operator~() const { return EnumFlags(~mValue); }
};