| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- /*
- ** Command & Conquer Generals(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: BitFlags.h /////////////////////////////////////////////////////////////////////////
- // Author: Steven Johnson, March 2002
- // Desc:
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- #pragma once
- #ifndef __BitFlags_H_
- #define __BitFlags_H_
- // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
- #include "Common/STLTypedefs.h"
- class INI;
- class Xfer;
- class AsciiString;
- //-------------------------------------------------------------------------------------------------
- /*
- BitFlags is a wrapper class that exists primarily because of a flaw in std::bitset<>.
- Although quite useful, it has horribly non-useful constructor, which (1) don't let
- us initialize stuff in useful ways, and (2) provide a default constructor that implicitly
- converts ints into bitsets in a "wrong" way (ie, it treats the int as a mask, not an index).
- So we wrap to correct this, but leave the bitset "exposed" so that we can use all the non-ctor
- functions on it directly (since it doesn't overload operator= to do the "wrong" thing, strangley enough)
- */
- template <size_t NUMBITS>
- class BitFlags
- {
- private:
- std::bitset<NUMBITS> m_bits;
- static const char* s_bitNameList[];
- public:
-
- /*
- just a little syntactic sugar so that there is no "foo = 0" compatible constructor
- */
- enum BogusInitType
- {
- kInit = 0
- };
- inline BitFlags()
- {
- }
- inline BitFlags(BogusInitType k, Int idx1)
- {
- m_bits.set(idx1);
- }
- inline BitFlags(BogusInitType k, Int idx1, Int idx2)
- {
- m_bits.set(idx1);
- m_bits.set(idx2);
- }
- inline BitFlags(BogusInitType k, Int idx1, Int idx2, Int idx3)
- {
- m_bits.set(idx1);
- m_bits.set(idx2);
- m_bits.set(idx3);
- }
- inline BitFlags(BogusInitType k, Int idx1, Int idx2, Int idx3, Int idx4)
- {
- m_bits.set(idx1);
- m_bits.set(idx2);
- m_bits.set(idx3);
- m_bits.set(idx4);
- }
- inline BitFlags(BogusInitType k, Int idx1, Int idx2, Int idx3, Int idx4, Int idx5)
- {
- m_bits.set(idx1);
- m_bits.set(idx2);
- m_bits.set(idx3);
- m_bits.set(idx4);
- m_bits.set(idx5);
- }
- inline BitFlags(BogusInitType k,
- Int idx1,
- Int idx2,
- Int idx3,
- Int idx4,
- Int idx5,
- Int idx6,
- Int idx7,
- Int idx8,
- Int idx9,
- Int idx10,
- Int idx11,
- Int idx12
- )
- {
- m_bits.set(idx1);
- m_bits.set(idx2);
- m_bits.set(idx3);
- m_bits.set(idx4);
- m_bits.set(idx5);
- m_bits.set(idx6);
- m_bits.set(idx7);
- m_bits.set(idx8);
- m_bits.set(idx9);
- m_bits.set(idx10);
- m_bits.set(idx11);
- m_bits.set(idx12);
- }
- inline Bool operator==(const BitFlags& that) const
- {
- return this->m_bits == that.m_bits;
- }
- inline Bool operator!=(const BitFlags& that) const
- {
- return this->m_bits != that.m_bits;
- }
- inline void set(Int i, Int val = 1)
- {
- m_bits.set(i, val);
- }
- inline Bool test(Int i) const
- {
- return m_bits.test(i);
- }
- inline Int size() const
- {
- return m_bits.size();
- }
- inline Int count() const
- {
- return m_bits.count();
- }
- inline Bool any() const
- {
- return m_bits.any();
- }
- inline void flip()
- {
- m_bits.flip();
- }
- inline void clear()
- {
- m_bits.reset();
- }
- inline Int countIntersection(const BitFlags& that) const
- {
- BitFlags tmp = *this;
- tmp.m_bits &= that.m_bits;
- return tmp.m_bits.count();
- }
- inline Int countInverseIntersection(const BitFlags& that) const
- {
- BitFlags tmp = *this;
- tmp.m_bits.flip();
- tmp.m_bits &= that.m_bits;
- return tmp.m_bits.count();
- }
- inline Bool anyIntersectionWith(const BitFlags& that) const
- {
- /// @todo srj -- improve me.
- BitFlags tmp = that;
- tmp.m_bits &= m_bits;
- return tmp.m_bits.any();
- }
- inline void clear(const BitFlags& clr)
- {
- m_bits &= ~clr.m_bits;
- }
- inline void set(const BitFlags& set)
- {
- m_bits |= set.m_bits;
- }
- inline void clearAndSet(const BitFlags& clr, const BitFlags& set)
- {
- m_bits &= ~clr.m_bits;
- m_bits |= set.m_bits;
- }
- inline Bool testSetAndClear(const BitFlags& mustBeSet, const BitFlags& mustBeClear) const
- {
- /// @todo srj -- improve me.
- BitFlags tmp = *this;
- tmp.m_bits &= mustBeClear.m_bits;
- if (tmp.m_bits.any())
- return false;
- tmp = *this;
- tmp.m_bits.flip();
- tmp.m_bits &= mustBeSet.m_bits;
- if (tmp.m_bits.any())
- return false;
- return true;
- }
- static const char** getBitNames()
- {
- return s_bitNameList;
- }
- static const char* getNameFromSingleBit(Int i)
- {
- return (i >= 0 && i < NUMBITS) ? s_bitNameList[i] : NULL;
- }
- static Int getSingleBitFromName(const char* token)
- {
- Int i = 0;
- for(const char** name = s_bitNameList; *name; ++name, ++i )
- {
- if( stricmp( *name, token ) == 0 )
- {
- return i;
- }
- }
- return -1;
- }
- const char* getBitNameIfSet(Int i) const
- {
- return test(i) ? s_bitNameList[i] : NULL;
- }
- Bool setBitByName(const char* token)
- {
- Int i = getSingleBitFromName(token);
- if (i >= 0)
- {
- set(i);
- return true;
- }
- else
- {
- return false;
- }
- }
- void parse(INI* ini, AsciiString* str);
- void xfer(Xfer* xfer);
- static void parseFromINI(INI* ini, void* /*instance*/, void *store, const void* /*userData*/);
- void buildDescription( AsciiString* str ) const
- {
- if ( str == NULL )
- return;//sanity
- for( Int i = 0; i < size(); ++i )
- {
- const char* bitName = getBitNameIfSet(i);
- if (bitName != NULL)
- {
- str->concat( bitName );
- str->concat( ",\n");
- }
- }
- }
- };
- #endif // __BitFlags_H_
|