00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00030 #ifndef _GG_Enum_h_
00031 #define _GG_Enum_h_
00032
00033 #include <map>
00034 #include <string>
00035
00036
00037 namespace GG {
00038
00040 struct EnumMapBase
00041 {
00042 enum {BAD_VALUE = -5000000};
00043
00044 virtual ~EnumMapBase() {}
00045
00048 virtual const std::string& FromEnum(int i) const = 0;
00049
00052 virtual int FromString (const std::string& str) const = 0;
00053 };
00054
00057 template <class E> struct EnumMap : EnumMapBase
00058 {
00059 virtual ~EnumMap() {}
00060 virtual const std::string& FromEnum(int) const
00061 { static std::string empty; return empty; }
00062 virtual int FromString (const std::string&) const {return 0;}
00063 };
00064
00066 template <class E> EnumMap<E> GetEnumMap()
00067 {
00068 static EnumMap<E> enum_map;
00069 return enum_map;
00070 }
00071
00081 #define GG_ENUM_MAP_BEGIN( name ) \
00082 template <> struct EnumMap< name > : EnumMapBase \
00083 { \
00084 typedef name EnumType; \
00085 typedef std::map<EnumType, std::string> MapType; \
00086 EnumMap () \
00087 {
00088
00090 #define GG_ENUM_MAP_INSERT( value ) m_map[ value ] = #value ;
00091
00093 #define GG_ENUM_MAP_END \
00094 } \
00095 virtual const std::string& FromEnum(int i) const \
00096 { \
00097 static const std::string ERROR_STR; \
00098 std::map<EnumType, std::string>::const_iterator it = \
00099 m_map.find(EnumType(i)); \
00100 return it == m_map.end() ? ERROR_STR : it->second; \
00101 } \
00102 int FromString (const std::string &str) const \
00103 { \
00104 for (MapType::const_iterator it = m_map.begin(); \
00105 it != m_map.end(); \
00106 ++it) { \
00107 if (it->second == str) \
00108 return it->first; \
00109 } \
00110 return BAD_VALUE; \
00111 } \
00112 MapType m_map; \
00113 };
00114
00116 #define GG_ENUM_STREAM_IN( name ) \
00117 inline std::istream& operator>>(std::istream& is, name& v) \
00118 { \
00119 std::string str; \
00120 is >> str; \
00121 v = name (GG::GetEnumMap< name >().FromString(str)); \
00122 return is; \
00123 }
00124
00126 #define GG_ENUM_STREAM_OUT( name ) \
00127 inline std::ostream& operator<<(std::ostream& os, name v) \
00128 { \
00129 os << GG::GetEnumMap< name >().FromEnum(v); \
00130 return os; \
00131 }
00132
00133 }
00134
00135 #endif // _GG_Enum_h_