// // Atomic string class (AString): // The size of each object is the same as int. Quick to handle. // // usage) // AString a("abc"); // AString b("def"); // b = a; // cout << b.str() << endl; // #ifndef __ATOMICSTRING_H__ #define __ATOMICSTRING_H__ #include #include #include struct hash { size_t operator()(const string& s) const { assert(sizeof(int) == 4 && sizeof(char) == 1); const int* p = reinterpret_cast(s.c_str()); size_t v = 0; int n = s.size() / 4; for (int i = 0; i < n; i++, p++) { // v ^= *p; v ^= *p << (4 * (i % 2)); // note) 0 <= char < 128 } int m = s.size() % 4; for (int i = 0; i < m; i++) { v ^= s[4 * n + i] << (i * 8); } return v; } }; class AString { int _id; public: AString(const int i = -1) : _id(i) {} AString(const char* c) { init(string(c)); } AString(const string& s) { init(s); } std::string str() const { assert(_id >= 0 && _id < _id2str.size()); // return _id2str[_id]->first; return _id2str[_id]; } bool is_valid() const { return _id >= 0; } operator int() const { return _id; } private: typedef std::hash_map map_type; void init(const string& s) { map_type::const_iterator pos = _str2id.find(s); if (pos != _str2id.end()) { _id = pos->second; return; } _id = _id2str.size(); pair p = _str2id.insert(make_pair(s, _id)); // _id2str.push_back(p.first); _id2str.push_back(s); } static map_type _str2id; // string -> id // static std::vector _id2str; // id -> string static std::vector _id2str; // id -> string // note) inefficient implementation: strings are duplicated. }; struct hash { size_t operator()(const AString & a) const { return int(a); } }; #endif