00001 #ifndef SYMBOLMAP_HH
00002 #define SYMBOLMAP_HH
00003
00004 #include <map>
00005 #include <string>
00006 #include <vector>
00007 #include "str/str.hh"
00008
00009 namespace bit {
00010
00012 template <typename S, typename I>
00013 class SymbolMap {
00014 public:
00015 SymbolMap()
00016 {
00017 }
00018
00020 void write(FILE *file) const
00021 {
00022 fprintf(file, "SYM:%zd:", m_symbols.size());
00023 for (size_t i = 0; i < m_symbols.size(); i++)
00024 fprintf(file, "%s\n", m_symbols[i].c_str());
00025 }
00026
00030 void read(FILE *file)
00031 {
00032 m_symbols.clear();
00033 m_indices.clear();
00034
00035 size_t size;
00036 int ret = fscanf(file, "SYM:%zd:", &size);
00037 if (ret != 1)
00038 throw std::string("bit::SymbolMap::read() failed reading header");
00039 std::string line;
00040 for (size_t i = 0; i < size; i++) {
00041 bool ok = str::read_line(line, file, true);
00042 if (!ok)
00043 throw std::string("bit::SymbolMap::read() failed reading symbol");
00044 insert_new(line);
00045 }
00046 }
00047
00050 I insert_dummy(const S &symbol = S())
00051 {
00052 m_symbols.push_back(symbol);
00053 return m_symbols.size() - 1;
00054 }
00055
00062 I insert(const S &symbol)
00063 {
00064 std::pair<typename Map::iterator, bool> ret =
00065 m_indices.insert(typename Map::value_type(symbol, m_symbols.size()));
00066 if (ret.second)
00067 m_symbols.push_back(symbol);
00068 return ret.first->second;
00069 }
00070
00077 I insert_new(const S &symbol)
00078 {
00079 std::pair<typename std::map<S, I>::iterator, bool> ret =
00080 m_indices.insert(
00081 typename std::map<S, I>::value_type(symbol, m_symbols.size()));
00082 if (!ret.second)
00083 throw std::string("tried to reinsert symbol");
00084 m_symbols.push_back(symbol);
00085 return ret.first->second;
00086 }
00087
00090 I index(const S &symbol) const
00091 {
00092 typename Map::const_iterator it = m_indices.find(symbol);
00093 if (it == m_indices.end())
00094 throw std::string("symbol not in the symbol map");
00095 return it->second;
00096 }
00097
00100 I index_nothrow(const S &symbol) const
00101 {
00102 typename Map::const_iterator it = m_indices.find(symbol);
00103 if (it == m_indices.end())
00104 return -1;
00105 return it->second;
00106 }
00107
00109 const S &at(I index) const
00110 {
00111 return m_symbols.at(index);
00112 }
00113
00115 S &at(I index)
00116 {
00117 return m_symbols.at(index);
00118 }
00119
00121 I size() const { return m_symbols.size(); }
00122
00123 private:
00124 typedef std::map<S, I> Map;
00125 std::vector<S> m_symbols;
00126 Map m_indices;
00127 };
00128
00129 };
00130
00131 #endif