BitFlags.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: BitFlags.h /////////////////////////////////////////////////////////////////////////
  24. // Author: Steven Johnson, March 2002
  25. // Desc:
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. #pragma once
  28. #ifndef __BitFlags_H_
  29. #define __BitFlags_H_
  30. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  31. #include "Common/STLTypedefs.h"
  32. class INI;
  33. class Xfer;
  34. class AsciiString;
  35. //-------------------------------------------------------------------------------------------------
  36. /*
  37. BitFlags is a wrapper class that exists primarily because of a flaw in std::bitset<>.
  38. Although quite useful, it has horribly non-useful constructor, which (1) don't let
  39. us initialize stuff in useful ways, and (2) provide a default constructor that implicitly
  40. converts ints into bitsets in a "wrong" way (ie, it treats the int as a mask, not an index).
  41. So we wrap to correct this, but leave the bitset "exposed" so that we can use all the non-ctor
  42. functions on it directly (since it doesn't overload operator= to do the "wrong" thing, strangley enough)
  43. */
  44. template <size_t NUMBITS>
  45. class BitFlags
  46. {
  47. private:
  48. std::bitset<NUMBITS> m_bits;
  49. static const char* s_bitNameList[];
  50. public:
  51. /*
  52. just a little syntactic sugar so that there is no "foo = 0" compatible constructor
  53. */
  54. enum BogusInitType
  55. {
  56. kInit = 0
  57. };
  58. inline BitFlags()
  59. {
  60. }
  61. inline BitFlags(BogusInitType k, Int idx1)
  62. {
  63. m_bits.set(idx1);
  64. }
  65. inline BitFlags(BogusInitType k, Int idx1, Int idx2)
  66. {
  67. m_bits.set(idx1);
  68. m_bits.set(idx2);
  69. }
  70. inline BitFlags(BogusInitType k, Int idx1, Int idx2, Int idx3)
  71. {
  72. m_bits.set(idx1);
  73. m_bits.set(idx2);
  74. m_bits.set(idx3);
  75. }
  76. inline BitFlags(BogusInitType k, Int idx1, Int idx2, Int idx3, Int idx4)
  77. {
  78. m_bits.set(idx1);
  79. m_bits.set(idx2);
  80. m_bits.set(idx3);
  81. m_bits.set(idx4);
  82. }
  83. inline BitFlags(BogusInitType k, Int idx1, Int idx2, Int idx3, Int idx4, Int idx5)
  84. {
  85. m_bits.set(idx1);
  86. m_bits.set(idx2);
  87. m_bits.set(idx3);
  88. m_bits.set(idx4);
  89. m_bits.set(idx5);
  90. }
  91. inline BitFlags(BogusInitType k,
  92. Int idx1,
  93. Int idx2,
  94. Int idx3,
  95. Int idx4,
  96. Int idx5,
  97. Int idx6,
  98. Int idx7,
  99. Int idx8,
  100. Int idx9,
  101. Int idx10,
  102. Int idx11,
  103. Int idx12
  104. )
  105. {
  106. m_bits.set(idx1);
  107. m_bits.set(idx2);
  108. m_bits.set(idx3);
  109. m_bits.set(idx4);
  110. m_bits.set(idx5);
  111. m_bits.set(idx6);
  112. m_bits.set(idx7);
  113. m_bits.set(idx8);
  114. m_bits.set(idx9);
  115. m_bits.set(idx10);
  116. m_bits.set(idx11);
  117. m_bits.set(idx12);
  118. }
  119. inline Bool operator==(const BitFlags& that) const
  120. {
  121. return this->m_bits == that.m_bits;
  122. }
  123. inline Bool operator!=(const BitFlags& that) const
  124. {
  125. return this->m_bits != that.m_bits;
  126. }
  127. inline void set(Int i, Int val = 1)
  128. {
  129. m_bits.set(i, val);
  130. }
  131. inline Bool test(Int i) const
  132. {
  133. return m_bits.test(i);
  134. }
  135. inline Int size() const
  136. {
  137. return m_bits.size();
  138. }
  139. inline Int count() const
  140. {
  141. return m_bits.count();
  142. }
  143. inline Bool any() const
  144. {
  145. return m_bits.any();
  146. }
  147. inline void flip()
  148. {
  149. m_bits.flip();
  150. }
  151. inline void clear()
  152. {
  153. m_bits.reset();
  154. }
  155. inline Int countIntersection(const BitFlags& that) const
  156. {
  157. BitFlags tmp = *this;
  158. tmp.m_bits &= that.m_bits;
  159. return tmp.m_bits.count();
  160. }
  161. inline Int countInverseIntersection(const BitFlags& that) const
  162. {
  163. BitFlags tmp = *this;
  164. tmp.m_bits.flip();
  165. tmp.m_bits &= that.m_bits;
  166. return tmp.m_bits.count();
  167. }
  168. inline Bool anyIntersectionWith(const BitFlags& that) const
  169. {
  170. /// @todo srj -- improve me.
  171. BitFlags tmp = that;
  172. tmp.m_bits &= m_bits;
  173. return tmp.m_bits.any();
  174. }
  175. inline void clear(const BitFlags& clr)
  176. {
  177. m_bits &= ~clr.m_bits;
  178. }
  179. inline void set(const BitFlags& set)
  180. {
  181. m_bits |= set.m_bits;
  182. }
  183. inline void clearAndSet(const BitFlags& clr, const BitFlags& set)
  184. {
  185. m_bits &= ~clr.m_bits;
  186. m_bits |= set.m_bits;
  187. }
  188. inline Bool testSetAndClear(const BitFlags& mustBeSet, const BitFlags& mustBeClear) const
  189. {
  190. /// @todo srj -- improve me.
  191. BitFlags tmp = *this;
  192. tmp.m_bits &= mustBeClear.m_bits;
  193. if (tmp.m_bits.any())
  194. return false;
  195. tmp = *this;
  196. tmp.m_bits.flip();
  197. tmp.m_bits &= mustBeSet.m_bits;
  198. if (tmp.m_bits.any())
  199. return false;
  200. return true;
  201. }
  202. static const char** getBitNames()
  203. {
  204. return s_bitNameList;
  205. }
  206. static const char* getNameFromSingleBit(Int i)
  207. {
  208. return (i >= 0 && i < NUMBITS) ? s_bitNameList[i] : NULL;
  209. }
  210. static Int getSingleBitFromName(const char* token)
  211. {
  212. Int i = 0;
  213. for(const char** name = s_bitNameList; *name; ++name, ++i )
  214. {
  215. if( stricmp( *name, token ) == 0 )
  216. {
  217. return i;
  218. }
  219. }
  220. return -1;
  221. }
  222. const char* getBitNameIfSet(Int i) const
  223. {
  224. return test(i) ? s_bitNameList[i] : NULL;
  225. }
  226. Bool setBitByName(const char* token)
  227. {
  228. Int i = getSingleBitFromName(token);
  229. if (i >= 0)
  230. {
  231. set(i);
  232. return true;
  233. }
  234. else
  235. {
  236. return false;
  237. }
  238. }
  239. void parse(INI* ini, AsciiString* str);
  240. void xfer(Xfer* xfer);
  241. static void parseFromINI(INI* ini, void* /*instance*/, void *store, const void* /*userData*/);
  242. void buildDescription( AsciiString* str ) const
  243. {
  244. if ( str == NULL )
  245. return;//sanity
  246. for( Int i = 0; i < size(); ++i )
  247. {
  248. const char* bitName = getBitNameIfSet(i);
  249. if (bitName != NULL)
  250. {
  251. str->concat( bitName );
  252. str->concat( ",\n");
  253. }
  254. }
  255. }
  256. };
  257. #endif // __BitFlags_H_