Skip to content

Instantly share code, notes, and snippets.

@PSyton
Created July 6, 2012 05:56
Show Gist options
  • Select an option

  • Save PSyton/3058317 to your computer and use it in GitHub Desktop.

Select an option

Save PSyton/3058317 to your computer and use it in GitHub Desktop.
Constant string enums in C++
#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);
#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