Skip to content

Instantly share code, notes, and snippets.

@haleyjd
Created May 21, 2018 20:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haleyjd/adb2d4e9bfb8c4e831d84f14bf131333 to your computer and use it in GitHub Desktop.
Save haleyjd/adb2d4e9bfb8c4e831d84f14bf131333 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <initializer_list>
#include <type_traits>
using namespace std;
template<typename EnumType>
class FlagSet
{
public:
using underlyingType_t = typename underlying_type<EnumType>::type;
FlagSet() : m_dwValue(0) {}
FlagSet(EnumType eLitValue) : m_dwValue(eLitValue) {}
FlagSet(initializer_list<EnumType> cInitList)
{
for(EnumType eVal : cInitList)
{
m_dwValue |= eVal;
}
}
FlagSet &operator = (const FlagSet &other) { m_dwValue = other.m_dwValue; return *this; }
FlagSet &operator |= (const FlagSet &other) { m_dwValue |= other.m_dwValue; return *this; }
FlagSet &operator &= (const FlagSet &other) { m_dwValue &= other.m_dwValue; return *this; }
FlagSet &operator ^= (const FlagSet &other) { m_dwValue ^= other.m_dwValue; return *this; }
FlagSet &operator = (initializer_list<EnumType> cInitList)
{
m_dwValue = 0;
for(EnumType eVal : cInitList)
{
m_dwValue |= eVal;
}
return *this;
}
FlagSet &operator |= (initializer_list<EnumType> cInitList)
{
for(EnumType eVal : cInitList)
{
m_dwValue |= eVal;
}
return *this;
}
FlagSet &operator &= (initializer_list<EnumType> cInitList)
{
for(EnumType eVal : cInitList)
{
m_dwValue &= eVal;
}
return *this;
}
FlagSet &operator ^= (initializer_list<EnumType> cInitList)
{
underlyingType_t dwTemp = 0;
for(EnumType eVal : cInitList)
{
dwTemp |= eVal;
}
m_dwValue ^= dwTemp;
return *this;
}
FlagSet &operator = (EnumType eLitValue) { m_dwValue = eLitValue; return *this; }
FlagSet &operator |= (EnumType eLitValue) { m_dwValue |= eLitValue; return *this; }
FlagSet &operator &= (EnumType eLitValue) { m_dwValue &= eLitValue; return *this; }
FlagSet &operator ^= (EnumType eLitValue) { m_dwValue ^= eLitValue; return *this; }
FlagSet operator & (const FlagSet &other) const { FlagSet f; f.m_dwValue = other.m_dwValue & m_dwValue; return f; }
FlagSet operator | (const FlagSet &other) const { FlagSet f; f.m_dwValue = other.m_dwValue | m_dwValue; return f; }
FlagSet operator ^ (const FlagSet &other) const { FlagSet f; f.m_dwValue = other.m_dwValue ^ m_dwValue; return f; }
FlagSet operator & (EnumType eLitValue) const { FlagSet f; f.m_dwValue = eLitValue & m_dwValue; return f; }
FlagSet operator | (EnumType eLitValue) const { FlagSet f; f.m_dwValue = eLitValue | m_dwValue; return f; }
FlagSet operator ^ (EnumType eLitValue) const { FlagSet f; f.m_dwValue = eLitValue ^ m_dwValue; return f; }
FlagSet operator ~ () const { FlagSet f; f.m_dwValue = ~m_dwValue; return f; }
underlyingType_t GetUnderlyingValue() const { return m_dwValue; }
protected:
underlyingType_t m_dwValue;
};
enum plainOldEnum_e
{
RED = 1,
GREEN = 2,
BLUE = 4
};
enum typedEnum_e : unsigned int
{
CYAN = 1,
MAGENTA = 2,
YELLOW = 4
};
enum class classEnum_e : unsigned int
{
ORANGE = 1,
PURPLE = 2
};
int main()
{
FlagSet<plainOldEnum_e> a{ RED, GREEN };
FlagSet<typedEnum_e> b;
FlagSet<classEnum_e> c;
cout << "1. a = " << a.GetUnderlyingValue() << endl;
a |= BLUE;
cout << "2. a = " << a.GetUnderlyingValue() << endl;
FlagSet<plainOldEnum_e> d;
d |= { RED, BLUE };
a &= ~d;
cout << "3. a = " << a.GetUnderlyingValue() << endl;
FlagSet<plainOldEnum_e> e = a | RED | BLUE;
cout << "4. e = " << e.GetUnderlyingValue() << endl;
// Should cause errors:
//a = CYAN;
//b |= BLUE;
//c &= ~a;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment