#ifndef CoreFlagSet_included #define CoreFlagSet_included //============================================================================= // Includes //============================================================================= #include #include //============================================================================= // Typedefs //============================================================================= typedef unsigned long UInt32; #define CORE_FLAGS_FIFTH #if defined(CORE_FLAGS_FIRST) //============================================================================= // CoreFlagSet - enum dependent, fixed max size //============================================================================= template class CoreFlagSet { public: CoreFlagSet() : m_flagSet(0) { } CoreFlagSet(EnumT val) : m_flagSet(0x1 << val) { } CoreFlagSet& Raise(EnumT val) { assert(val < 32); m_flagSet |= (0x1 << val); return *this; } CoreFlagSet& Lower(EnumT val) { assert(val < 32); m_flagSet &= ~(0x1 << val); return *this; } bool Test(EnumT val) const { assert(val < 32); return (m_flagSet & (0x1 << val)) != 0; } CoreFlagSet& Merge(CoreFlagSet& rhs) { m_flagSet |= rhs.m_flagSet; return *this; } bool Any() const { return m_flagSet != 0; } bool None() const { return m_flagSet == 0; } private: UInt32 m_flagSet; }; #elif defined(CORE_FLAGS_SECOND) //============================================================================= // CoreFlagSet - class dependent, fixed max size - DOESN'T WORK! //============================================================================= template class CoreFlagSet { typedef typename DerivT::FlagEnum EnumT; public: CoreFlagSet() : m_flagSet(0) { } CoreFlagSet(EnumT val) : m_flagSet(0x1 << val) { } CoreFlagSet& Raise(EnumT val) { assert(val < 32); m_flagSet |= (0x1 << val); return *this; } CoreFlagSet& Lower(EnumT val) { assert(val < 32); m_flagSet &= ~(0x1 << val); return *this; } bool Test(EnumT val) const { assert(val < 32); return (m_flagSet & (0x1 << val)) != 0; } CoreFlagSet& Merge(CoreFlagSet& rhs) { m_flagSet |= rhs.m_flagSet; return *this; } bool Any() const { return m_flagSet != 0; } bool None() const { return m_flagSet == 0; } private: UInt32 m_flagSet; }; #elif defined(CORE_FLAGS_THIRD) //============================================================================= // CoreFlagSet - enum dependent, no fixed max size //============================================================================= template class CoreFlagSet { public: CoreFlagSet() { } CoreFlagSet(EnumT val) { m_flagSet.set(val, true); } CoreFlagSet& Raise(EnumT val) { m_flagSet.set(val, true); return *this; } CoreFlagSet& Lower(EnumT val) { m_flagSet.set(val, false); return *this; } bool Test(EnumT val) const { return m_flagSet.test(val); } CoreFlagSet& Merge(CoreFlagSet& rhs) { m_flagSet |= rhs.m_flagSet; return *this; } bool Any() const { return m_flagSet.any(); } bool None() const { return m_flagSet.none(); } private: std::bitset m_flagSet; }; #elif defined(CORE_FLAGS_FOURTH) //============================================================================= // CoreFlagSet - enum dependent, no fixed max size, partial template specialization - // Standard compliant, doesn't work under MSVC... //============================================================================= template class CoreFlagSetImpl { public: CoreFlagSetImpl() : m_flagSet(0) { } CoreFlagSetImpl(EnumT val) : m_flagSet(0x1 << val) { } CoreFlagSetImpl& Raise(EnumT val) { assert(val < 32); m_flagSet |= (0x1 << val); return *this; } CoreFlagSetImpl& Lower(EnumT val) { assert(val < 32); m_flagSet &= ~(0x1 << val); return *this; } bool Test(EnumT val) const { assert(val < 32); return (m_flagSet & (0x1 << val)) != 0; } CoreFlagSetImpl& Merge(CoreFlagSetImpl& rhs) { m_flagSet |= rhs.m_flagSet; return *this; } bool Any() const { return m_flagSet != 0; } bool None() const { return m_flagSet == 0; } private: UInt32 m_flagSet; }; template class CoreFlagSetImpl { public: CoreFlagSetImpl() { } CoreFlagSetImpl(EnumT val) { m_flagSet.set(val, true); } CoreFlagSetImpl& Raise(EnumT val) { m_flagSet.set(val, true); return *this; } CoreFlagSetImpl& Lower(EnumT val) { m_flagSet.set(val, false); return *this; } bool Test(EnumT val) const { return m_flagSet.test(val); } CoreFlagSetImpl& Merge(CoreFlagSetImpl& rhs) { m_flagSet |= rhs.m_flagSet; return *this; } bool Any() const { return m_flagSet.any(); } bool None() const { return m_flagSet.none(); } private: std::bitset m_flagSet; }; template class CoreFlagSet : public CoreFlagSetImpl 32)> { public: CoreFlagSet() { } CoreFlagSet(EnumT val) : CoreFlagSetImpl(val) { } }; #elif defined(CORE_FLAGS_FIFTH) //============================================================================= // CoreFlagSet - enum dependent, no fixed max size, partial template specialization workaround - // May or may not be standard compliant, works under MSVC, Codewarrior, Borland //============================================================================= template struct CoreFlagSetWrapper { template class Impl { public: Impl() : m_flagSet(0) { } Impl(EnumT val) : m_flagSet(0x1 << val) { } Impl& Raise(EnumT val) { assert(val < 32); m_flagSet |= (0x1 << val); return *this; } Impl& Lower(EnumT val) { assert(val < 32); m_flagSet &= ~(0x1 << val); return *this; } bool Test(EnumT val) const { assert(val < 32); return (m_flagSet & (0x1 << val)) != 0; } Impl& Merge(Impl& rhs) { m_flagSet |= rhs.m_flagSet; return *this; } bool Any() const { return m_flagSet != 0; } bool None() const { return m_flagSet == 0; } private: UInt32 m_flagSet; }; template <> class Impl { public: Impl() { } Impl(EnumT val) { m_flagSet.set(val, true); } Impl& Raise(EnumT val) { m_flagSet.set(val, true); return *this; } Impl& Lower(EnumT val) { m_flagSet.set(val, false); return *this; } bool Test(EnumT val) const { return m_flagSet.test(val); } Impl& Merge(Impl& rhs) { m_flagSet |= rhs.m_flagSet; return *this; } bool Any() const { return m_flagSet.any(); } bool None() const { return m_flagSet.none(); } private: std::bitset m_flagSet; }; }; template class CoreFlagSet : public CoreFlagSetWrapper::Impl<(MaxFlag > 32)> { public: CoreFlagSet() { } CoreFlagSet(EnumT val) : CoreFlagSetWrapper::Impl<(MaxFlag > 32)>(val) { } }; #elif defined(CORE_FLAGS_SIXTH) //============================================================================= // CoreFlagSet - enum dependent, no fixed max size, partial template specialization workaround - // Definitely not standard compliant, doesn't work under MSVC //============================================================================= template struct CoreFlagSetWrapper { template class Impl { public: Impl() : m_flagSet(0) { } Impl(EnumT val) : m_flagSet(0x1 << val) { } Impl& Raise(EnumT val) { assert(val < 32); m_flagSet |= (0x1 << val); return *this; } Impl& Lower(EnumT val) { assert(val < 32); m_flagSet &= ~(0x1 << val); return *this; } bool Test(EnumT val) const { assert(val < 32); return (m_flagSet & (0x1 << val)) != 0; } Impl& Merge(Impl& rhs) { m_flagSet |= rhs.m_flagSet; return *this; } bool Any() const { return m_flagSet != 0; } bool None() const { return m_flagSet == 0; } private: UInt32 m_flagSet; }; }; template template<> class CoreFlagSetWrapper::Impl { public: Impl() { } Impl(EnumT val) { m_flagSet.set(val, true); } Impl& Raise(EnumT val) { m_flagSet.set(val, true); return *this; } Impl& Lower(EnumT val) { m_flagSet.set(val, false); return *this; } bool Test(EnumT val) const { return m_flagSet.test(val); } Impl& Merge(Impl& rhs) { m_flagSet |= rhs.m_flagSet; return *this; } bool Any() const { return m_flagSet.any(); } bool None() const { return m_flagSet.none(); } private: std::bitset m_flagSet; }; template class CoreFlagSet : public CoreFlagSetWrapper::Impl<(MaxFlag > 32)> { public: CoreFlagSet() { } CoreFlagSet(EnumT val) : CoreFlagSetWrapper::Impl<(MaxFlag > 32)>(val) { } }; #endif #endif // CoreFlagSet_included