-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathEnumHelp.h
230 lines (210 loc) · 10.1 KB
/
EnumHelp.h
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
///
/// macro BEGIN_ENUM
///
/// BEGIN_ENUM is used to create a C++ 'struct' type around an enum, providing
/// a scope for the enum instead of being defined at the global namespace.
/// Combined with the helper macros of BEGIN_ENUM_BYTE(), ..., this enforces
/// that the enum will only be given the intended allocated storage instead of
/// the default storage of a full 4-byte 'int'.
///
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
#define BEGIN_ENUM(name, storage) \
struct name \
{ \
enum _E : storage; \
\
inline name() \
{ \
_value = (storage) 0; \
} \
\
inline name(_E src) \
{ \
_value = (storage) src; \
} \
\
inline name(storage n) \
{ \
_value = n; \
} \
\
inline name(int n) \
{ \
/* */ \
/* This is needed to enable operations such as "m_value &= ~Flags::Member; */ \
/* */ \
\
_value = (storage) n; \
AssertMsg(((int) _value) == n, "Ensure no truncation"); \
} \
\
inline void operator =(_E e) \
{ \
_value = (storage) e; \
} \
\
inline void operator =(storage n) \
{ \
_value = n; \
} \
\
inline bool operator ==(_E e) const \
{ \
return ((_E) _value) == e; \
} \
\
inline bool operator !=(_E e) const \
{ \
return ((_E) _value) != e; \
} \
\
inline bool operator <(_E e) const \
{ \
return ((_E) _value) < e; \
} \
\
inline bool operator <=(_E e) const \
{ \
return ((_E) _value) <= e; \
} \
\
inline bool operator >(_E e) const \
{ \
return ((_E) _value) > e; \
} \
\
inline bool operator >=(_E e) const \
{ \
return ((_E) _value) >= e; \
} \
\
inline _E operator &(_E e) const \
{ \
return (_E) (((_E) _value) & e); \
} \
\
inline _E operator |(name e) const \
{ \
return (_E) (_value | e._value); \
} \
\
inline void operator |=(name e) \
{ \
_value = _value | e._value; \
} \
\
inline void operator &=(name e) \
{ \
_value = _value & e._value; \
} \
\
inline void operator &=(_E e) \
{ \
_value = _value & ((storage) e); \
} \
\
inline operator _E() const \
{ \
return (_E) _value; \
} \
\
enum _E : storage \
{ \
#define BEGIN_ENUM_BYTE(name) BEGIN_ENUM(name, byte)
#define BEGIN_ENUM_USHORT(name) BEGIN_ENUM(name, uint16)
#define BEGIN_ENUM_UINT(name) BEGIN_ENUM(name, uint32)
#define END_ENUM_BYTE() \
Force8BitPadding = (byte) 0xffU \
}; \
\
byte _value; \
}; \
#define END_ENUM_USHORT() \
Force16BitPadding = (uint16) 0xffffU \
}; \
\
uint16 _value; \
}; \
#define END_ENUM_UINT() \
Force32BitPadding = (uint32) 0xffffffffU \
}; \
\
uint32 _value; \
};
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
///
/// macro PREVENT_ASSIGN
///
/// PREVENT_ASSIGN is used within a C++ type definition to define and
/// explicitly hide the "operator =()" method, preventing it from accidentally
/// being called by the program. If these are not explicitly defined, the C++
/// compiler will implicitly define them, which usually leads to unintended
/// behavior.
///
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
#define PREVENT_ASSIGN(ClassName) \
private: \
ClassName & operator =(const ClassName & rhs);
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
///
/// macro PREVENT_COPY
///
/// PREVENT_COPY is used within a C++ type definition to define and explicitly
/// hide the "C++ copy constructor" and "operator =()" methods, preventing them
/// from accidentally being called by the program. If these are not explicitly
/// defined, the C++ compiler will implicitly define them, which usually leads
/// to unintended behavior.
///
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
#define PREVENT_COPYCONSTRUCT(ClassName) \
private: \
ClassName(const ClassName & copy);
#define PREVENT_COPY(ClassName) \
PREVENT_COPYCONSTRUCT(ClassName); \
PREVENT_ASSIGN(ClassName);
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
///
/// macro PREVENT_STANDALONE_HEAPINSTANCE
///
/// PREVENT_STANDALONE_HEAPINSTANCE is used within a C++ type definition to
/// define and explicitly the new operator, preventing them from accidentally
/// being instantiated in the heap by itself. This also ensures that the
/// correct destructor will always be called without using virtual destructors.
///
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
#define PREVENT_STANDALONE_HEAPINSTANCE() \
private: \
static void * operator new(size_t size);
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
///
/// macro DECLARE_OBJECT
///
/// DECLARE_OBJECT sets up a class that derives from RcObject, RecyclableObject or
/// ZnObject:
/// - Prevent "C++ copy constructor" and "operator =()" methods.
/// - Must be allocated on heap. Because the copy constructor is hidden, this
/// requires an empty default constructor to be declared.
///
///----------------------------------------------------------------------------
///----------------------------------------------------------------------------
#define DECLARE_OBJECT(ClassName) \
public: \
inline ClassName() { } \
private: \
ClassName(const ClassName & copy); \
ClassName & operator =(const ClassName & rhs);