diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 3920dc28f..9820a1bd0 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,7 @@ +December 26, 2007 +- Enhanced TMap so that you can get at the iterator types by accessing them + like class members. + December 26, 2007 (Changes by Graf Zahl) - Fixed: The FSpecialFont constructor copied the untranslated colors directly from the source palette instead of the font's identity map. diff --git a/src/g_game.cpp b/src/g_game.cpp index 5f93e11c9..104abf94e 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1635,15 +1635,15 @@ static void WriteArrayVars (FILE *file, FWorldGlobalArray *vars, unsigned int co arc.WriteCount (j); for (; i <= j; ++i) { - const SDWORD *key; - SDWORD *val; - arc.WriteCount (vars[i].CountUsed()); - FWorldGlobalArrayIterator it(vars[i]); - while (it.NextPair (key, val)) + + FWorldGlobalArray::ConstIterator it(vars[i]); + const FWorldGlobalArray::Pair *pair; + + while (it.NextPair (pair)) { - arc.WriteCount (*key); - arc.WriteCount (*val); + arc.WriteCount (pair->Key); + arc.WriteCount (pair->Value); } } } diff --git a/src/g_level.h b/src/g_level.h index 3a1b0b1b9..2efb0fa07 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -313,7 +313,6 @@ struct InitIntToZero } }; typedef TMap, InitIntToZero> FWorldGlobalArray; -typedef TMapIterator FWorldGlobalArrayIterator; extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS]; extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS]; diff --git a/src/tarray.h b/src/tarray.h index 6dd97ee0e..2a9447ae4 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -361,10 +361,22 @@ template struct TValueTraits } }; +template class TMapIterator; +template class TMapConstIterator; + template, class ValueTraits=TValueTraits > class TMap { + template friend class TMapIterator; + template friend class TMapConstIterator; + public: + typedef class TMap MyType; + typedef class TMapIterator Iterator; + typedef class TMapConstIterator ConstIterator; + typedef struct { const KT Key; VT Value; } Pair; + typedef const Pair ConstPair; + TMap() { NumUsed = 0; SetNodeVector(1); } TMap(hash_t size) { NumUsed = 0; SetNodeVector(size); } ~TMap() { ClearNodeVector(); } @@ -435,12 +447,12 @@ public: VT &operator[] (const KT key) { - return GetNode(key)->Value; + return GetNode(key)->Pair.Value; } const VT &operator[] (const KT key) const { - return GetNode(key)->Value; + return GetNode(key)->Pair.Value; } //======================================================================= @@ -455,13 +467,13 @@ public: VT *CheckKey (const KT key) { Node *n = FindKey(key); - return n != NULL ? &n->Value : NULL; + return n != NULL ? &n->Pair.Value : NULL; } const VT *CheckKey (const KT key) const { - Node *n = FindKey(key); - return n != NULL ? &n->Value : NULL; + const Node *n = FindKey(key); + return n != NULL ? &n->Pair.Value : NULL; } //======================================================================= @@ -482,14 +494,14 @@ public: Node *n = FindKey(key); if (n != NULL) { - n->Value = value; + n->Pair.Value = value; } else { n = NewKey(key); - ::new(&n->Value) VT(value); + ::new(&n->Pair.Value) VT(value); } - return n->Value; + return n->Pair.Value; } //======================================================================= @@ -506,15 +518,15 @@ public: } protected: - template friend class TMapIterator; - template friend class TMapConstIterator; - + struct IPair // This must be the same as Pair above, but with a + { // non-const Key. + KT Key; + VT Value; + }; struct Node { Node *Next; - KT Key; - VT Value; - + IPair Pair; void SetNil() { Next = (Node *)1; @@ -588,8 +600,8 @@ protected: { if (!nold[i].IsNil()) { - Node *n = NewKey(nold[i].Key); - ::new(&n->Value) VT(nold[i].Value); + Node *n = NewKey(nold[i].Pair.Key); + ::new(&n->Pair.Value) VT(nold[i].Pair.Value); nold[i].~Node(); } } @@ -634,7 +646,7 @@ protected: Rehash(); /* grow table */ return NewKey(key); /* re-insert key into grown table */ } - othern = MainPosition(mp->Key); + othern = MainPosition(mp->Pair.Key); if (othern != mp) /* is colliding node out of its main position? */ { /* yes; move colliding node into free position */ while (othern->Next != mp) /* find previous */ @@ -657,7 +669,7 @@ protected: mp->Next = NULL; } ++NumUsed; - ::new(&mp->Key) KT(key); + ::new(&mp->Pair.Key) KT(key); return mp; } @@ -666,7 +678,7 @@ protected: Node *mp = MainPosition(key), **mpp; HashTraits Traits; - if (!mp->IsNil() && !Traits.Compare(mp->Key, key)) /* the key is in its main position */ + if (!mp->IsNil() && !Traits.Compare(mp->Pair.Key, key)) /* the key is in its main position */ { if (mp->Next != NULL) /* move next node to its main position */ { @@ -684,7 +696,7 @@ protected: } else /* the key is either not present or not in its main position */ { - for (mpp = &mp->Next, mp = *mpp; mp != NULL && Traits.Compare(mp->Key, key); mpp = &mp->Next, mp = *mpp) + for (mpp = &mp->Next, mp = *mpp; mp != NULL && Traits.Compare(mp->Pair.Key, key); mpp = &mp->Next, mp = *mpp) { } /* look for the key */ if (mp != NULL) /* found it */ { @@ -700,7 +712,18 @@ protected: { HashTraits Traits; Node *n = MainPosition(key); - while (n != NULL && !n->IsNil() && Traits.Compare(n->Key, key)) + while (n != NULL && !n->IsNil() && Traits.Compare(n->Pair.Key, key)) + { + n = n->Next; + } + return n == NULL || n->IsNil() ? NULL : n; + } + + const Node *FindKey(const KT key) const + { + HashTraits Traits; + const Node *n = MainPosition(key); + while (n != NULL && !n->IsNil() && Traits.Compare(n->Pair.Key, key)) { n = n->Next; } @@ -716,7 +739,7 @@ protected: } n = NewKey(key); ValueTraits traits; - traits.Init(n->Value); + traits.Init(n->Pair.Value); return n; } @@ -733,8 +756,8 @@ protected: { if (!nodes->IsNil()) { - Node *n = NewKey(nodes->Key); - ::new(&n->Value) VT(nodes->Value); + Node *n = NewKey(nodes->Pair.Key); + ::new(&n->Pair.Value) VT(nodes->Pair.Value); } } } @@ -762,7 +785,7 @@ public: // //======================================================================= - bool NextPair(const KT *&key, VT *&value) + bool NextPair(typename MapType::Pair *&pair) { if (Position >= Map.Size) { @@ -772,8 +795,7 @@ public: { if (!Map.Nodes[Position].IsNil()) { - key = &Map.Nodes[Position].Key; - value = &Map.Nodes[Position].Value; + pair = reinterpret_cast(&Map.Nodes[Position].Pair); Position += 1; return true; } @@ -811,7 +833,7 @@ public: { } - bool NextPair(const KT *&key, const VT *&value) + bool NextPair(typename MapType::ConstPair *&pair) { if (Position >= Map.Size) { @@ -821,8 +843,7 @@ public: { if (!Map.Nodes[Position].IsNil()) { - key = &Map.Nodes[Position].Key; - value = &Map.Nodes[Position].Value; + pair = reinterpret_cast(&Map.Nodes[Position].Pair); Position += 1; return true; }