00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef LABELED_ENUM_HPP
00021 #define LABELED_ENUM_HPP
00022
00023 #include <StringEquality.hpp>
00024 #include <IdentifierSet.hpp>
00025
00026 #include <ErrorHandler.hpp>
00027
00028 #include <sstream>
00029
00030 template <typename GivenEnumType>
00031 class LabeledEnum
00032 {
00033 public:
00034 typedef GivenEnumType EnumType;
00035
00036 private:
00037
00038 typedef std::map<EnumType,
00039 const char*,
00040 std::less<EnumType> > EnumSet;
00041
00042 typedef std::map<const char*,
00043 EnumType,
00044 StringEquality> LabelSet;
00045
00046 EnumSet __enumSet;
00047 LabelSet __labelSet;
00048
00049 public:
00050 void get(IdentifierSet& I)
00051 {
00052 for (typename LabelSet::iterator i = __labelSet.begin();
00053 i != __labelSet.end(); ++i) {
00054 I.insert((*i).first);
00055 }
00056 }
00057
00058 void add(const char* c, const EnumType t)
00059 {
00060 typename LabelSet::iterator name = __labelSet.find(c);
00061 typename EnumSet::iterator value = __enumSet.find(t);
00062
00063 if (name != __labelSet.end()) {
00064 std::stringstream errorMsg;
00065 errorMsg << "the label '" << c << "' has already been associated to '"
00066 << t << "'\n";
00067 errorMsg << "found: " <<(*name).first << '\n';
00068 errorMsg << "list:\n";
00069 for (typename LabelSet::iterator i = __labelSet.begin();
00070 i != __labelSet.end(); ++i) {
00071 errorMsg << '\t' <<(*i).first << '\n';
00072 }
00073 errorMsg << std::ends;
00074
00075 throw ErrorHandler(__FILE__,__LINE__,
00076 errorMsg.str(),
00077 ErrorHandler::unexpected);
00078
00079 } else if (value != __enumSet.end()) {
00080 std::stringstream errorMsg;
00081 errorMsg << "the enum '" << t << "' has already been associated to '"
00082 << (*value).second << "'" << std::ends;
00083
00084 throw ErrorHandler(__FILE__,__LINE__,
00085 errorMsg.str(),
00086 ErrorHandler::unexpected);
00087 } else {
00088 __labelSet[c] = t;
00089 __enumSet [t] = c;
00090 }
00091 }
00092
00093 const EnumType operator()(const char* c) const
00094 {
00095 typename LabelSet::const_iterator i = __labelSet.find(c);
00096 if (i != __labelSet.end()) {
00097 return (*i).second;
00098 } else {
00099 std::stringstream errorMsg;
00100 errorMsg << "'" << c << "' is not associated to any enum\n";
00101 errorMsg << "Possible cases are:\n";
00102 errorMsg << *this << std::ends;
00103 throw ErrorHandler(__FILE__,__LINE__,
00104 errorMsg.str(),
00105 ErrorHandler::unexpected);
00106 return (*i).second;
00107 }
00108 }
00109
00110 friend std::ostream& operator << (std::ostream& os,
00111 const LabeledEnum<EnumType>& l)
00112 {
00113 for (typename LabeledEnum<EnumType>::LabelSet::const_iterator i
00114 = l.__labelSet.begin();
00115 i != l.__labelSet.end(); ++i) {
00116 os << (*i).second << '\t' << (*i).first << '\n';
00117 }
00118 return os;
00119 }
00120
00121 LabeledEnum()
00122 {
00123 ;
00124 }
00125
00126 ~LabeledEnum()
00127 {
00128 ;
00129 }
00130 };
00131
00132 #endif // LABELED_ENUM_HPP