| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #ifndef _ISS_H |
| #define _ISS_H |
|
|
| #include <limits> |
| #include <vector> |
| #include <string.h> |
|
|
| |
| #ifdef USE_HASHSET |
| #include <ext/hash_set> |
| #else |
| #include <set> |
| #endif |
|
|
| #include <boost/pool/pool.hpp> |
|
|
| #ifdef USE_HASHSET |
| |
| template<class IndType> |
| class StringsEqualComparator; |
|
|
| template<class IndType> |
| class Hasher; |
| #else |
| |
| template<class IndType> |
| class StringsLessComparator; |
| #endif |
|
|
| |
| |
| template<class IndType> |
| class IndexedStringsStorage { |
|
|
| public: |
|
|
| typedef IndType index_type; |
|
|
| #ifdef USE_HASHSET |
| typedef StringsEqualComparator<IndType> equality_comparator_t; |
|
|
| typedef Hasher<IndType> hasher_t; |
|
|
| |
| typedef __gnu_cxx::hash_set<IndType, hasher_t, equality_comparator_t> index_t; |
| #else |
| typedef StringsLessComparator<IndType> less_comparator_t; |
|
|
| |
| typedef std::set<IndType, less_comparator_t> index_t; |
| #endif |
| |
| |
| |
| typedef std::vector<const char*> table_t; |
|
|
| private: |
|
|
| |
| boost::pool<> _storage; |
|
|
| |
| table_t _table; |
|
|
| |
| index_t _index; |
|
|
| public: |
| |
| |
| IndexedStringsStorage(void); |
|
|
| |
| |
| inline bool is_full(void) const { return _table.size() == std::numeric_limits<IndType>::max(); } |
|
|
| |
| |
| |
| |
| |
| inline const char* get(IndType index) const { return _table[index]; } |
|
|
| |
| |
| |
| |
| |
| |
| IndType put(const char* str); |
|
|
| |
| |
| inline table_t::size_type size(void) const { return _table.size(); } |
| }; |
|
|
|
|
| |
| |
| |
| #ifdef USE_HASHSET |
| template<class IndType> |
| class StringsEqualComparator: public std::binary_function<IndType, IndType, bool> { |
| #else |
| template<class IndType> |
| class StringsLessComparator: public std::binary_function<IndType, IndType, bool> { |
| #endif |
| |
| const typename IndexedStringsStorage<IndType>::table_t& _table; |
| public: |
| #ifdef USE_HASHSET |
| StringsEqualComparator<IndType>(const typename IndexedStringsStorage<IndType>::table_t& table): _table(table) {} |
| #else |
| StringsLessComparator<IndType>(const typename IndexedStringsStorage<IndType>::table_t& table): _table(table) {} |
| #endif |
|
|
| |
| |
| |
| |
| |
| inline bool operator()(IndType lhs, IndType rhs) const { |
| #ifdef USE_HASHSET |
| return strcmp(_table[lhs], _table[rhs]) == 0; |
| #else |
| return strcmp(_table[lhs], _table[rhs]) < 0; |
| #endif |
| } |
| }; |
|
|
| #ifdef USE_HASHSET |
| |
| |
| template<class IndType> |
| class Hasher: public std::unary_function<IndType, size_t> { |
|
|
| __gnu_cxx::hash<const char*> _hash; |
|
|
| |
| const typename IndexedStringsStorage<IndType>::table_t& _table; |
|
|
| public: |
| |
| Hasher<IndType>(const typename IndexedStringsStorage<IndType>::table_t& table): _hash(), _table(table) {} |
|
|
| |
| |
| |
| |
| inline size_t operator()(const IndType index) const { |
| return _hash(_table[index]); |
| } |
| }; |
| #endif |
|
|
| template <class IndType> |
| #ifdef USE_HASHSET |
| IndexedStringsStorage<IndType>::IndexedStringsStorage(void): _storage(sizeof(char)), _table(), _index(100, hasher_t(_table), equality_comparator_t(_table)) {} |
| #else |
| IndexedStringsStorage<IndType>::IndexedStringsStorage(void): _storage(sizeof(char)), _table(), _index(less_comparator_t(_table)) {} |
| #endif |
|
|
| template <class IndType> |
| IndType IndexedStringsStorage<IndType>::put(const char* str) { |
|
|
| if ( this->is_full() ) { |
| |
| throw std::bad_alloc(); |
| } |
|
|
| |
| |
| |
| |
| IndType index = static_cast<IndType>(_table.size()); |
| _table.push_back(str); |
|
|
| #ifdef USE_HASHSET |
| |
| typename index_t::iterator iIndex = _index.find(index); |
| #else |
| |
| |
| typename index_t::iterator iIndex = _index.lower_bound(index); |
| #endif |
|
|
| if ( (iIndex != _index.end()) |
| #ifndef USE_HASHSET |
| |
| |
| && (strcmp(_table[*iIndex], str) == 0) |
| #endif |
| ) { |
| |
| |
| _table.pop_back(); |
| |
| return static_cast<IndType>(*iIndex); |
| } |
|
|
| |
|
|
| |
| char* mem = static_cast<char*>(_storage.ordered_malloc(strlen(str) + 1)); |
| |
| strcpy(mem, str); |
|
|
| |
| |
| _table[index] = mem; |
|
|
| #ifdef USE_HASHSET |
| |
| _index.insert(index); |
| #else |
| |
| |
| _index.insert(iIndex, index); |
| #endif |
|
|
| |
| return index; |
| } |
|
|
| #endif |
|
|