2
0

EnumHelp.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. ///----------------------------------------------------------------------------
  7. ///----------------------------------------------------------------------------
  8. ///
  9. /// macro BEGIN_ENUM
  10. ///
  11. /// BEGIN_ENUM is used to create a C++ 'struct' type around an enum, providing
  12. /// a scope for the enum instead of being defined at the global namespace.
  13. /// Combined with the helper macros of BEGIN_ENUM_BYTE(), ..., this enforces
  14. /// that the enum will only be given the intended allocated storage instead of
  15. /// the default storage of a full 4-byte 'int'.
  16. ///
  17. ///----------------------------------------------------------------------------
  18. ///----------------------------------------------------------------------------
  19. #define BEGIN_ENUM(name, storage) \
  20. struct name \
  21. { \
  22. enum _E : storage; \
  23. \
  24. inline name() \
  25. { \
  26. _value = (storage) 0; \
  27. } \
  28. \
  29. inline name(_E src) \
  30. { \
  31. _value = (storage) src; \
  32. } \
  33. \
  34. inline name(storage n) \
  35. { \
  36. _value = n; \
  37. } \
  38. \
  39. inline name(int n) \
  40. { \
  41. /* */ \
  42. /* This is needed to enable operations such as "m_value &= ~Flags::Member; */ \
  43. /* */ \
  44. \
  45. _value = (storage) n; \
  46. AssertMsg(((int) _value) == n, "Ensure no truncation"); \
  47. } \
  48. \
  49. inline void operator =(_E e) \
  50. { \
  51. _value = (storage) e; \
  52. } \
  53. \
  54. inline void operator =(storage n) \
  55. { \
  56. _value = n; \
  57. } \
  58. \
  59. inline bool operator ==(_E e) const \
  60. { \
  61. return ((_E) _value) == e; \
  62. } \
  63. \
  64. inline bool operator !=(_E e) const \
  65. { \
  66. return ((_E) _value) != e; \
  67. } \
  68. \
  69. inline bool operator <(_E e) const \
  70. { \
  71. return ((_E) _value) < e; \
  72. } \
  73. \
  74. inline bool operator <=(_E e) const \
  75. { \
  76. return ((_E) _value) <= e; \
  77. } \
  78. \
  79. inline bool operator >(_E e) const \
  80. { \
  81. return ((_E) _value) > e; \
  82. } \
  83. \
  84. inline bool operator >=(_E e) const \
  85. { \
  86. return ((_E) _value) >= e; \
  87. } \
  88. \
  89. inline _E operator &(_E e) const \
  90. { \
  91. return (_E) (((_E) _value) & e); \
  92. } \
  93. \
  94. inline _E operator |(name e) const \
  95. { \
  96. return (_E) (_value | e._value); \
  97. } \
  98. \
  99. inline void operator |=(name e) \
  100. { \
  101. _value = _value | e._value; \
  102. } \
  103. \
  104. inline void operator &=(name e) \
  105. { \
  106. _value = _value & e._value; \
  107. } \
  108. \
  109. inline void operator &=(_E e) \
  110. { \
  111. _value = _value & ((storage) e); \
  112. } \
  113. \
  114. inline operator _E() const \
  115. { \
  116. return (_E) _value; \
  117. } \
  118. \
  119. enum _E : storage \
  120. { \
  121. #define BEGIN_ENUM_BYTE(name) BEGIN_ENUM(name, byte)
  122. #define BEGIN_ENUM_USHORT(name) BEGIN_ENUM(name, uint16)
  123. #define BEGIN_ENUM_UINT(name) BEGIN_ENUM(name, uint32)
  124. #define END_ENUM_BYTE() \
  125. Force8BitPadding = (byte) 0xffU \
  126. }; \
  127. \
  128. byte _value; \
  129. }; \
  130. #define END_ENUM_USHORT() \
  131. Force16BitPadding = (uint16) 0xffffU \
  132. }; \
  133. \
  134. uint16 _value; \
  135. }; \
  136. #define END_ENUM_UINT() \
  137. Force32BitPadding = (uint32) 0xffffffffU \
  138. }; \
  139. \
  140. uint32 _value; \
  141. };
  142. ///----------------------------------------------------------------------------
  143. ///----------------------------------------------------------------------------
  144. ///
  145. /// macro PREVENT_ASSIGN
  146. ///
  147. /// PREVENT_ASSIGN is used within a C++ type definition to define and
  148. /// explicitly hide the "operator =()" method, preventing it from accidentally
  149. /// being called by the program. If these are not explicitly defined, the C++
  150. /// compiler will implicitly define them, which usually leads to unintended
  151. /// behavior.
  152. ///
  153. ///----------------------------------------------------------------------------
  154. ///----------------------------------------------------------------------------
  155. #define PREVENT_ASSIGN(ClassName) \
  156. private: \
  157. ClassName & operator =(const ClassName & rhs);
  158. ///----------------------------------------------------------------------------
  159. ///----------------------------------------------------------------------------
  160. ///
  161. /// macro PREVENT_COPY
  162. ///
  163. /// PREVENT_COPY is used within a C++ type definition to define and explicitly
  164. /// hide the "C++ copy constructor" and "operator =()" methods, preventing them
  165. /// from accidentally being called by the program. If these are not explicitly
  166. /// defined, the C++ compiler will implicitly define them, which usually leads
  167. /// to unintended behavior.
  168. ///
  169. ///----------------------------------------------------------------------------
  170. ///----------------------------------------------------------------------------
  171. #define PREVENT_COPYCONSTRUCT(ClassName) \
  172. private: \
  173. ClassName(const ClassName & copy);
  174. #define PREVENT_COPY(ClassName) \
  175. PREVENT_COPYCONSTRUCT(ClassName); \
  176. PREVENT_ASSIGN(ClassName);
  177. ///----------------------------------------------------------------------------
  178. ///----------------------------------------------------------------------------
  179. ///
  180. /// macro PREVENT_STANDALONE_HEAPINSTANCE
  181. ///
  182. /// PREVENT_STANDALONE_HEAPINSTANCE is used within a C++ type definition to
  183. /// define and explicitly the new operator, preventing them from accidentally
  184. /// being instantiated in the heap by itself. This also ensures that the
  185. /// correct destructor will always be called without using virtual destructors.
  186. ///
  187. ///----------------------------------------------------------------------------
  188. ///----------------------------------------------------------------------------
  189. #define PREVENT_STANDALONE_HEAPINSTANCE() \
  190. private: \
  191. static void * operator new(size_t size);
  192. ///----------------------------------------------------------------------------
  193. ///----------------------------------------------------------------------------
  194. ///
  195. /// macro DECLARE_OBJECT
  196. ///
  197. /// DECLARE_OBJECT sets up a class that derives from RcObject, RecyclableObject or
  198. /// ZnObject:
  199. /// - Prevent "C++ copy constructor" and "operator =()" methods.
  200. /// - Must be allocated on heap. Because the copy constructor is hidden, this
  201. /// requires an empty default constructor to be declared.
  202. ///
  203. ///----------------------------------------------------------------------------
  204. ///----------------------------------------------------------------------------
  205. #define DECLARE_OBJECT(ClassName) \
  206. public: \
  207. inline ClassName() { } \
  208. private: \
  209. ClassName(const ClassName & copy); \
  210. ClassName & operator =(const ClassName & rhs);