Created
July 6, 2012 05:56
-
-
Save PSyton/3058317 to your computer and use it in GitHub Desktop.
Constant string enums in C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include <string> | |
| #include <boost/unordered_map.hpp> | |
| namespace enum_base { | |
| template <class T> | |
| class BaseEnum | |
| { | |
| protected: | |
| typedef boost::unordered::unordered_map<std::string, size_t> TypesIndex; | |
| typedef boost::unordered::unordered_map<size_t, T*> TypesStorage; | |
| private: | |
| TypesIndex::iterator m_value; | |
| protected: | |
| BaseEnum(const std::string& val) | |
| { | |
| m_value = T::m_index.find( val ); | |
| if ( m_value == T::m_index.end() ) | |
| { | |
| m_value = T::m_index.insert( std::make_pair(val, T::m_index.size()) ).first; | |
| } | |
| T::m_map.insert( std::make_pair( m_value->second, (T*)this ) ); | |
| } | |
| public: | |
| BaseEnum() : m_value( T::m_index.end() ) | |
| { | |
| } | |
| bool operator==(const BaseEnum& other) const | |
| { | |
| return m_value == other.m_value; | |
| } | |
| bool operator!=(const BaseEnum& other) const | |
| { | |
| return m_value != other.m_value; | |
| } | |
| static const T& fromString(const std::string& type) | |
| { | |
| typename TypesIndex::iterator it = T::m_index.find( type ); | |
| if ( it != T::m_index.end() ) | |
| { | |
| return *(T::m_map[it->second]); | |
| } | |
| return T::BadType; | |
| } | |
| const std::string& toString() const | |
| { | |
| if ( m_value != T::m_index.end() ) | |
| return m_value->first; | |
| return T::m_empty; | |
| } | |
| operator std::string() const | |
| { | |
| return toString(); | |
| } | |
| virtual ~BaseEnum() {} | |
| }; | |
| } // namespace enum_base | |
| #define BASEENUM_DECL(SubClass) \ | |
| private: \ | |
| SubClass(const std::string& str) \ | |
| : enum_base::BaseEnum<SubClass>(str) {} \ | |
| SubClass() {} \ | |
| static TypesStorage m_map; \ | |
| static TypesIndex m_index; \ | |
| static std::string m_empty; \ | |
| friend class enum_base::BaseEnum<SubClass>; \ | |
| public: \ | |
| static const SubClass BadType; | |
| #define BASEENUM_IMPL(SubClass) \ | |
| enum_base::BaseEnum<SubClass>::TypesIndex SubClass::m_index; \ | |
| enum_base::BaseEnum<SubClass>::TypesStorage SubClass::m_map; \ | |
| std::string SubClass::m_empty; \ | |
| const SubClass SubClass::BadType( std::string("BadType") ); | |
| #define BASEENUM_CONST_IMPL(SubClass, constName) \ | |
| const SubClass SubClass::constName(#constName); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "enum_base.h" | |
| struct XEnum | |
| : public enum_base::BaseEnum<XEnum> | |
| { | |
| BASEENUM_DECL(XEnum) | |
| static const XEnum Value1; | |
| static const XEnum Value2; | |
| static const XEnum Value3; | |
| }; | |
| BASEENUM_IMPL(XEnum); | |
| BASEENUM_CONST_IMPL(XEnum, Value1); | |
| BASEENUM_CONST_IMPL(XEnum, Value2); | |
| BASEENUM_CONST_IMPL(XEnum, Value3); | |
| int main(int argc, char *argv[]) | |
| { | |
| std::cout << XEnum::Value1.toString() << std::endl; | |
| std::cout << XEnum::Value2.toString() << std::endl; | |
| std::cout << XEnum::Value3.toString() << std::endl; | |
| XEnum x = XEnum::Value3; | |
| std::cout << (x != XEnum::Value1); | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment