FlagSet.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. //
  2. // Copyright (c) 2008-2020 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include <type_traits>
  24. namespace Urho3D
  25. {
  26. /// Make bitwise operators (| & ^ ~) automatically construct FlagSet from Enum.
  27. #define URHO3D_AUTOMATIC_FLAGSET(Enum) \
  28. inline Urho3D::FlagSet<Enum> operator | (const Enum lhs, const Enum rhs) { return Urho3D::FlagSet<Enum>(lhs) | rhs; } \
  29. inline Urho3D::FlagSet<Enum> operator & (const Enum lhs, const Enum rhs) { return Urho3D::FlagSet<Enum>(lhs) & rhs; } \
  30. inline Urho3D::FlagSet<Enum> operator ^ (const Enum lhs, const Enum rhs) { return Urho3D::FlagSet<Enum>(lhs) ^ rhs; } \
  31. inline Urho3D::FlagSet<Enum> operator ~ (const Enum rhs) { return ~Urho3D::FlagSet<Enum>(rhs); }
  32. /// Declare FlagSet for specific enum and create operators for automatic FlagSet construction.
  33. #define URHO3D_FLAGSET(enumName, flagsetName) \
  34. URHO3D_AUTOMATIC_FLAGSET(enumName); \
  35. using flagsetName = Urho3D::FlagSet<enumName>
  36. /// A set of flags defined by an Enum.
  37. template <class E>
  38. class FlagSet
  39. {
  40. public:
  41. /// Enum type.
  42. using Enum = E;
  43. /// Integer type.
  44. using Integer = typename std::underlying_type<Enum>::type;
  45. public:
  46. /// Ctor by integer.
  47. explicit FlagSet(Integer value)
  48. : value_(value)
  49. {
  50. }
  51. /// Empty constructor.
  52. FlagSet() = default;
  53. /// Copy constructor.
  54. FlagSet(const FlagSet& another) = default;
  55. /// Construct from Enum value.
  56. FlagSet(const Enum value)
  57. : value_(static_cast<Integer>(value))
  58. {
  59. }
  60. /// Assignment operator from flagset.
  61. FlagSet& operator = (const FlagSet& rhs) = default;
  62. /// Bitwise AND against Enum value.
  63. FlagSet& operator &= (const Enum value)
  64. {
  65. value_ &= static_cast<Integer>(value);
  66. return *this;
  67. }
  68. /// Bitwise AND against flagset value.
  69. FlagSet& operator &= (const FlagSet value)
  70. {
  71. value_ &= value.value_;
  72. return *this;
  73. }
  74. /// Bitwise OR against Enum value.
  75. FlagSet& operator |= (const Enum value)
  76. {
  77. value_ |= static_cast<Integer>(value);
  78. return *this;
  79. }
  80. /// Bitwise OR against flagset value.
  81. FlagSet& operator |= (const FlagSet value)
  82. {
  83. value_ |= value.value_;
  84. return *this;
  85. }
  86. /// Bitwise XOR against Enum value.
  87. FlagSet& operator ^= (const Enum value)
  88. {
  89. value_ ^= static_cast<Integer>(value);
  90. return *this;
  91. }
  92. /// Bitwise XOR against flagset value.
  93. FlagSet& operator ^= (const FlagSet value)
  94. {
  95. value_ ^= value.value_;
  96. return *this;
  97. }
  98. /// Bitwise AND against Enum value.
  99. FlagSet operator & (const Enum value) const
  100. {
  101. return FlagSet(value_ & static_cast<Integer>(value));
  102. }
  103. /// Bitwise AND against flagset value.
  104. FlagSet operator & (const FlagSet value) const
  105. {
  106. return FlagSet(value_ & value.value_);
  107. }
  108. /// Bitwise OR against Enum value.
  109. FlagSet operator | (const Enum value) const
  110. {
  111. return FlagSet(value_ | static_cast<Integer>(value));
  112. }
  113. /// Bitwise OR against flagset value.
  114. FlagSet operator | (const FlagSet value) const
  115. {
  116. return FlagSet(value_ | value.value_);
  117. }
  118. /// Bitwise XOR against Enum value.
  119. FlagSet operator ^ (const Enum value) const
  120. {
  121. return FlagSet(value_ ^ static_cast<Integer>(value));
  122. }
  123. /// Bitwise XOR against flagset value.
  124. FlagSet operator ^ (const FlagSet value) const
  125. {
  126. return FlagSet(value_ ^ value.value_);
  127. }
  128. /// Bitwise negation.
  129. FlagSet operator ~ () const
  130. {
  131. return FlagSet(~value_);
  132. }
  133. /// Boolean negation.
  134. bool operator ! () const
  135. {
  136. return !value_;
  137. }
  138. /// Returns true if any flag is set.
  139. explicit operator bool () const
  140. {
  141. return value_ != 0;
  142. }
  143. /// Cast to underlying type of enum.
  144. operator Integer() const
  145. {
  146. return value_;
  147. }
  148. /// Cast to enum value.
  149. explicit operator Enum() const
  150. {
  151. return static_cast<Enum>(value_);
  152. }
  153. /// Cast to double. Used by Lua bindings.
  154. explicit operator double() const
  155. {
  156. return static_cast<double>(value_);
  157. }
  158. /// Equality check against enum value.
  159. bool operator ==(Enum rhs) const
  160. {
  161. return value_ == static_cast<Integer>(rhs);
  162. }
  163. /// Equality check against another flagset.
  164. bool operator ==(FlagSet rhs) const
  165. {
  166. return value_ == rhs.value_;
  167. }
  168. /// Non-equality check against enum value.
  169. bool operator !=(Enum rhs) const
  170. {
  171. return !(*this == rhs);
  172. }
  173. /// Non-equality check against another flagset value.
  174. bool operator !=(FlagSet rhs) const
  175. {
  176. return !(*this == rhs);
  177. }
  178. /// Return true if specified enum value is set.
  179. inline bool Test(const Enum value) const
  180. {
  181. return Test(static_cast<Integer>(value));
  182. }
  183. /// Return true if specified bits are set.
  184. inline bool Test(const Integer flags) const
  185. {
  186. return (value_ & flags) == flags && (flags != 0 || value_ == flags);
  187. }
  188. /// Return underlying integer (constant).
  189. Integer AsInteger() const { return value_; }
  190. /// Return underlying integer (non-constant).
  191. Integer& AsInteger() { return value_; }
  192. /// Return hash value.
  193. unsigned ToHash() const { return static_cast<unsigned>(value_); }
  194. protected:
  195. /// Value.
  196. Integer value_ = 0;
  197. };
  198. }