#pragma once // // ###### To create an enum call MyType with string support: ###### // //// MyType.h //struct MyType //{ // enum _Enum // { // Unknown, // Foo, // Bar // }; // // struct _Definition : public EnumerationDefinition< _Enum, _Definition > { static StringValue Strings[]; }; // typedef EnumerationValue< _Enum, _Definition, Unknown > _Value; //}; // //typedef MyType::_Value MyTypeEnum; // // //// MyType.cpp //#include "MyType.h" // //MyType::_Definition::StringValue MyType::_Definition::Strings[] = //{ // { MyType::Foo, _T( "Foo" ) }, // { MyType::Bar, _T( "Bar" ) }, // { MyType::Unknown, NULL } //}; // // // ###### To create an enum call MyType without string support: ###### // //// MyType.h //struct MyType //{ // enum _Enum // { // Unknown, // Foo, // Bar // }; // // typedef EnumerationDefinitionNoStrings _Definition; // typedef EnumerationValue< _Enum, _Definition, Unknown > _Value; //}; // //typedef MyType::_Value MyTypeEnum; // namespace SevenZip { namespace intl { template < typename TEnum, class DerivedDef > struct EnumerationDefinition { struct StringValue { TEnum value; const TCHAR* string; }; static TEnum Parse( const TString& string, const TEnum defaultValue ) { const StringValue* it = DerivedDef::Strings; for (; it->string != NULL; ++it ) { if ( string.Compare( it->string ) == 0 ) { return it->value; } } return defaultValue; } static TString Format( const TEnum& value ) { const StringValue* it = DerivedDef::Strings; for (; it->string != NULL; ++it ) { if ( value == it->value ) { return it->string; } } return TString(); } }; struct EnumerationDefinitionNoStrings {}; template < typename TEnum, class TEnumClass, TEnum DefaultValue > class EnumerationValue { private: typedef typename EnumerationValue< TEnum, TEnumClass, DefaultValue > ThisClass; TEnum m_value; public: typedef typename TEnum Enum; EnumerationValue(): m_value( DefaultValue ) {} EnumerationValue( const TEnum& value ): m_value( value ) {} static ThisClass Parse( const TString& string ) { return ThisClass( TEnumClass::Parse( string, DefaultValue ) ); } const TEnum& GetValue() const { return m_value; } TString GetString() const { return TEnumClass::Format( m_value ); } operator TEnum() const { return m_value; } ThisClass& operator=( const TEnum& value ) { m_value = value; return *this; } bool operator==( const ThisClass& that ) const { return that.m_value == m_value; } bool operator!=( const ThisClass& that ) const { return !operator==( that ); } bool operator==( const TEnum& value ) const { return value == m_value; } bool operator!=( const TEnum& value ) const { return !operator==( value ); } bool operator< ( const ThisClass& that ) const { return m_value < that.m_value; } // Bit field members void AddFlag( const TEnum& value ) { *reinterpret_cast< int* >( &m_value ) |= static_cast< int >( value ); } void RemoveFlag( const TEnum& value ) { *reinterpret_cast< int* >( &m_value ) &= ~static_cast< int >( value ); } bool HasFlag( const TEnum& value ) const { return ( m_value & value ) == value; } bool HasAnyFlag( const TEnum& valueCombo ) const { return ( m_value & valueCombo ) != 0; } }; } }