unsigned NumTombstones;
unsigned ItemSize;
protected:
+ StringMapImpl(unsigned itemSize) : ItemSize(itemSize) {
+ // Initialize the map with zero buckets to allocation.
+ TheTable = 0;
+ NumBuckets = 0;
+ NumItems = 0;
+ NumTombstones = 0;
+ }
StringMapImpl(unsigned InitSize, unsigned ItemSize);
void RehashTable();
/// RemoveKey - Remove the StringMapEntry for the specified key from the
/// table, returning it. If the key is not in the table, this returns null.
StringMapEntryBase *RemoveKey(const char *KeyStart, const char *KeyEnd);
-
+private:
+ void init(unsigned Size);
public:
static StringMapEntryBase *getTombstoneVal() {
return (StringMapEntryBase*)-1;
// Okay, the item doesn't already exist, and 'Bucket' is the bucket to fill
// in. Allocate a new item with space for the string at the end and a null
// terminator.
+
unsigned AllocSize = sizeof(StringMapEntry)+KeyLength+1;
+ unsigned Alignment = alignof<StringMapEntry>();
-#ifdef __GNUC__
- unsigned Alignment = __alignof__(StringMapEntry);
-#else
- // FIXME: ugly.
- unsigned Alignment = 8;
-#endif
- StringMapEntry *NewItem =
- static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize, Alignment));
+ StringMapEntry *NewItem =
+ static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
// Default construct the value.
new (NewItem) StringMapEntry(KeyLength);
MallocAllocator A;
return Create(KeyStart, KeyEnd, A);
}
-
+
+
+ /// GetStringMapEntryFromValue - Given a value that is known to be embedded
+ /// into a StringMapEntry, return the StringMapEntry itself.
+ static StringMapEntry &GetStringMapEntryFromValue(ValueTy &V) {
+ StringMapEntry *EPtr = 0;
+ char *Ptr = reinterpret_cast<char*>(&V) -
+ (reinterpret_cast<char*>(&EPtr->Val) -
+ reinterpret_cast<char*>(EPtr));
+ return *reinterpret_cast<StringMapEntry*>(Ptr);
+ }
+ static const StringMapEntry &GetStringMapEntryFromValue(const ValueTy &V) {
+ return GetStringMapEntryFromValue(const_cast<ValueTy&>(V));
+ }
+
/// Destroy - Destroy this StringMapEntry, releasing memory back to the
/// specified allocator.
template<typename AllocatorTy>
AllocatorTy Allocator;
typedef StringMapEntry<ValueTy> MapEntryTy;
public:
- StringMap(unsigned InitialSize = 0)
+ StringMap() : StringMapImpl(sizeof(MapEntryTy)) {}
+ StringMap(unsigned InitialSize)
: StringMapImpl(InitialSize, sizeof(MapEntryTy)) {}
AllocatorTy &getAllocator() { return Allocator; }
typedef StringMapConstIterator<ValueTy> const_iterator;
typedef StringMapIterator<ValueTy> iterator;
- iterator begin() { return iterator(TheTable); }
- iterator end() { return iterator(TheTable+NumBuckets); }
- const_iterator begin() const { return const_iterator(TheTable); }
- const_iterator end() const { return const_iterator(TheTable+NumBuckets); }
-
+ iterator begin() {
+ return iterator(TheTable, NumBuckets == 0);
+ }
+ iterator end() {
+ return iterator(TheTable+NumBuckets, true);
+ }
+ const_iterator begin() const {
+ return const_iterator(TheTable, NumBuckets == 0);
+ }
+ const_iterator end() const {
+ return const_iterator(TheTable+NumBuckets, true);
+ }
iterator find(const char *KeyStart, const char *KeyEnd) {
int Bucket = FindKey(KeyStart, KeyEnd);
RemoveKey(KeyValue);
}
+ void erase(iterator I) {
+ MapEntryTy &V = *I;
+ remove(&V);
+ V.Destroy(Allocator);
+ }
+
~StringMap() {
for (ItemBucket *I = TheTable, *E = TheTable+NumBuckets; I != E; ++I) {
if (I->Item && I->Item != getTombstoneVal())
static_cast<MapEntryTy*>(I->Item)->Destroy(Allocator);
}
- delete [] TheTable;
+ free(TheTable);
}
+private:
+ StringMap(const StringMap &); // FIXME: Implement.
+ void operator=(const StringMap &); // FIXME: Implement.
};
protected:
StringMapImpl::ItemBucket *Ptr;
public:
- StringMapConstIterator(StringMapImpl::ItemBucket *Bucket) : Ptr(Bucket) {
- AdvancePastEmptyBuckets();
+ StringMapConstIterator(StringMapImpl::ItemBucket *Bucket,
+ bool NoAdvance = false)
+ : Ptr(Bucket) {
+ if (!NoAdvance) AdvancePastEmptyBuckets();
}
const StringMapEntry<ValueTy> &operator*() const {
template<typename ValueTy>
class StringMapIterator : public StringMapConstIterator<ValueTy> {
public:
- StringMapIterator(StringMapImpl::ItemBucket *Bucket)
- : StringMapConstIterator<ValueTy>(Bucket) {
+ StringMapIterator(StringMapImpl::ItemBucket *Bucket,
+ bool NoAdvance = false)
+ : StringMapConstIterator<ValueTy>(Bucket, NoAdvance) {
}
StringMapEntry<ValueTy> &operator*() const {
return *static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item);