From: <sil...@li...> - 2003-04-17 22:04:05
|
Update of /cvsroot/silgraphite/silgraphite/include In directory sc8-pr-cvs1:/tmp/cvs-serv17051/include Modified Files: GrCommon.h GrPlatform.h Added Files: UtilHashMap.h UtilInt.h UtilSet.h Log Message: Added/modified utility files for GrCompiler --- NEW FILE: UtilHashMap.h --- /*--------------------------------------------------------------------*//*:Ignore this sentence. Copyright (C) 2001 SIL International. All rights reserved. Distributable under the terms of either the Common Public License or the GNU Lesser General Public License, as specified in the LICENSING.txt file. File: HashMap.h Responsibility: Steve McConnel Last reviewed: Not yet. Description: This provides a set of template collection classes to replace std::map. Their primary reason to exist is to allow explicit checking for internal memory allocation failures. ----------------------------------------------------------------------------------------------*/ #pragma once #ifndef HASHMAP_H_INCLUDED #define HASHMAP_H_INCLUDED //:End Ignore /*---------------------------------------------------------------------------------------------- Functor class for computing a hash value from an arbitrary object. Hungarian: hsho ----------------------------------------------------------------------------------------------*/ class HashObj { public: int operator () (void * pKey, int cbKey); }; /*---------------------------------------------------------------------------------------------- Functor class for comparing two arbitrary objects (of the same class) for equality. Hungarian: eqlo ----------------------------------------------------------------------------------------------*/ class EqlObj { public: bool operator () (void * pKey1, void * pKey2, int cbKey); }; /*---------------------------------------------------------------------------------------------- Hash map template collection class whose keys are objects of an arbitrary class. Hungarian: hm[K][T] ----------------------------------------------------------------------------------------------*/ template<class K, class T, class H = HashObj, class Eq = EqlObj> class HashMap { public: //:> Member classes /*------------------------------------------------------------------------------------------ This is the basic data structure for storing one key-value pair in a hash map. In order to handle hash collisions, this structure is a member of a linked list. Hungarian: hsnd ------------------------------------------------------------------------------------------*/ class HashNode { public: //:> Constructors/destructors/etc. HashNode(void) : m_key(K()), m_value(T()), m_nHash(0), m_ihsndNext(0) { } HashNode(K & key, T & value, int nHash, int ihsndNext = -1) : m_key(key), m_value(value), m_nHash(nHash), m_ihsndNext(ihsndNext) { } ~HashNode() { } //:> Member variable access void PutKey(K & key) { m_key = key; } K & GetKey() { return m_key; } void PutValue(T & value) { m_value = value; } T & GetValue() { return m_value; } void PutHash(int nHash) { m_nHash = nHash; } int GetHash() { return m_nHash; } void PutNext(int ihsndNext) { m_ihsndNext = ihsndNext; } int GetNext() { return m_ihsndNext; } /*-------------------------------------------------------------------------------------- Check whether the given HashNode is being used. --------------------------------------------------------------------------------------*/ bool InUse() { return m_ihsndNext >= -1; } protected: //:> Member variables K m_key; T m_value; int m_nHash; int m_ihsndNext; // -1 means end of list, -(ihsnd + 3) for free list members }; /*------------------------------------------------------------------------------------------ This provides an iterator for stepping through all HashNodes stored in the hash map. This is useful primarily for saving the contents of a hash map to a file. Hungarian: ithm[K][T] ------------------------------------------------------------------------------------------*/ class iterator { public: // Constructors/destructors/etc. iterator() : m_phmParent(NULL), m_ihsnd(0) { } iterator(HashMap<K,T,H,Eq> * phm, int ihsnd) : m_phmParent(phm), m_ihsnd(ihsnd) { } iterator(const iterator & v) : m_phmParent(v.m_phmParent), m_ihsnd(v.m_ihsnd) { } ~iterator() { } // Other public methods iterator & operator = (const iterator & ithm) { m_phmParent = ithm.m_phmParent; m_ihsnd = ithm.m_ihsnd; return *this; } T & operator * (void) { Assert(m_phmParent); Assert(m_phmParent->m_prghsnd); Assert(m_ihsnd < m_phmParent->m_ihsndLim); return m_phmParent->m_prghsnd[m_ihsnd].GetValue(); } HashNode * operator -> (void) { Assert(m_phmParent); Assert(m_phmParent->m_prghsnd); Assert(m_ihsnd < m_phmParent->m_ihsndLim); return &m_phmParent->m_prghsnd[m_ihsnd]; } iterator & operator ++ (void) { Assert(m_phmParent); ++m_ihsnd; // make sure that this new HashNode is actually in use while (m_ihsnd < m_phmParent->m_ihsndLim) { if (m_phmParent->m_prghsnd[m_ihsnd].InUse()) return *this; // skip to the next one and check it ++m_ihsnd; } if (m_ihsnd > m_phmParent->m_ihsndLim) m_ihsnd = m_phmParent->m_ihsndLim; return *this; } bool operator == (const iterator & ithm) { return (m_phmParent == ithm.m_phmParent) && (m_ihsnd == ithm.m_ihsnd); } bool operator != (const iterator & ithm) { return (m_phmParent != ithm.m_phmParent) || (m_ihsnd != ithm.m_ihsnd); } T & GetValue(void) { Assert(m_phmParent); Assert(m_phmParent->m_prghsnd); Assert(m_ihsnd < m_phmParent->m_ihsndLim); Assert(m_phmParent->m_prghsnd[m_ihsnd].InUse()); return m_phmParent->m_prghsnd[m_ihsnd].GetValue(); } K & GetKey(void) { Assert(m_phmParent); Assert(m_phmParent->m_prghsnd); Assert(m_ihsnd < m_phmParent->m_ihsndLim); Assert(m_phmParent->m_prghsnd[m_ihsnd].InUse()); return m_phmParent->m_prghsnd[m_ihsnd].GetKey(); } int GetHash() { Assert(m_phmParent); Assert(m_phmParent->m_prghsnd); Assert(m_ihsnd < m_phmParent->m_ihsndLim); Assert(m_phmParent->m_prghsnd[m_ihsnd].InUse()); return m_phmParent->m_prghsnd[m_ihsnd].GetHash(); } int GetIndex() { Assert(m_phmParent); Assert(m_phmParent->m_prghsnd); Assert(m_ihsnd < m_phmParent->m_ihsndLim); Assert(m_phmParent->m_prghsnd[m_ihsnd].InUse()); return m_ihsnd; } protected: //:> Member variables HashMap<K,T,H,Eq> * m_phmParent; int m_ihsnd; }; friend class iterator; //:> Constructors/destructors/etc. HashMap(); ~HashMap(); HashMap(HashMap<K,T,H,Eq> & hm); //:> Other public methods iterator Begin(); iterator End(); void Insert(K & key, T & value, bool fOverwrite = false, int * pihsndOut = NULL); bool Retrieve(K & key, T * pvalueRet); bool Delete(K & key); void Clear(); void CopyTo(HashMap<K,T,H,Eq> & hmKT); void CopyTo(HashMap<K,T,H,Eq> * phmKT); bool GetIndex(K & key, int * pihsndRet); bool IndexKey(int ihsnd, K * pkeyRet); bool IndexValue(int ihsnd, T * pvalueRet); int Size(); /*------------------------------------------------------------------------------------------ The assignment operator allows an entire hashmap to be assigned as the value of another hashmap. It throws an error if it runs out of memory. @return a reference to this hashmap. (That is how the assignment operator is defined!) @param hm is a reference to the other hashmap. ------------------------------------------------------------------------------------------*/ HashMap<K,T,H,Eq> & operator = (HashMap<K,T,H,Eq> & hm) { hm.CopyTo(this); return *this; } //:Ignore #ifdef DEBUG int _BucketCount(); int _EmptyBuckets(); int _BucketsUsed(); int _FullestBucket(); bool AssertValid() { AssertPtrN(m_prgihsndBuckets); Assert(m_prgihsndBuckets || !m_cBuckets); Assert(!m_prgihsndBuckets || m_cBuckets); AssertArray(m_prgihsndBuckets, m_cBuckets); AssertPtrN(m_prghsnd); Assert(m_prghsnd || !m_ihsndMax); Assert(!m_prghsnd || m_ihsndMax); AssertArray(m_prghsnd, m_ihsndMax); Assert(0 <= m_ihsndLim && m_ihsndLim <= m_ihsndMax); Assert(-1 <= FreeListIdx(m_ihsndFirstFree)); Assert(FreeListIdx(m_ihsndFirstFree) < m_ihsndLim); return true; } #endif //:End Ignore protected: //:> Member variables int * m_prgihsndBuckets; int m_cBuckets; HashNode * m_prghsnd; int m_ihsndLim; int m_ihsndMax; int m_ihsndFirstFree; // stores -(ihsnd + 3) //:> Protected methods //:Ignore /*------------------------------------------------------------------------------------------ Map between real index and "free list" index. Note that this mapping is bidirectional. ------------------------------------------------------------------------------------------*/ int FreeListIdx(int ihsnd) { return -(ihsnd + 3); } //:End Ignore }; // Local Variables: // mode:C++ // c-file-style:"cellar" // tab-width:4 // End: #endif /*HASHMAP_H_INCLUDED*/ --- NEW FILE: UtilInt.h --- /*--------------------------------------------------------------------*//*:Ignore this sentence. Copyright (C) 1999, 2001 SIL International. All rights reserved. Distributable under the terms of either the Common Public License or the GNU Lesser General Public License, as specified in the LICENSING.txt file. File: UtilInt.h Responsibility: Steve McConnel (was Shon Katzenberger) Last reviewed: Integer utilities. ----------------------------------------------------------------------------------------------*/ #pragma once #ifndef UtilInt_H #define UtilInt_H 1 const int knMax = 0x7FFFFFFF; /*********************************************************************************************** Intel 80386 routines. ***********************************************************************************************/ #define MulDiv MulDivImp inline int MulDiv(int n, int nMul, int nDiv) { Assert(nDiv != 0); __asm { mov eax,n imul nMul idiv nDiv mov n,eax } return n; } inline int MulDivMod(int n, int nMul, int nDiv, int *pnRem) { Assert(nDiv != 0); AssertPtr(pnRem); __asm { mov eax,n imul nMul idiv nDiv mov ecx,pnRem mov DWORD PTR[ecx],edx mov n,eax } return n; } /*********************************************************************************************** These arithmetic functions assert that the result doesn't overflow. ***********************************************************************************************/ /*---------------------------------------------------------------------------------------------- Multiply two integers and assert on overflow. ----------------------------------------------------------------------------------------------*/ template<typename T> inline int Mul(T t1, T t2) { Assert(!t1 || (t1 * t2) / t1 == t2); return t1 * t2; } /*---------------------------------------------------------------------------------------------- Add two integers and assert on overflow. ----------------------------------------------------------------------------------------------*/ template<typename T> inline int Add(T t1, T t2) { Assert((t1 + t2 < t2) == (t1 < 0)); return t1 + t2; } /*********************************************************************************************** Arithmetic functions. ***********************************************************************************************/ /*---------------------------------------------------------------------------------------------- Return the floor(tNum / tDen) where floor(x) is defined as the the greatest integer that is less than or equal to the number. This only works for signed integer types. ----------------------------------------------------------------------------------------------*/ template<typename T> inline T FloorDiv(T tNum, T tDen) { Assert(tDen != 0); return tNum / tDen - ((tNum ^ tDen) < 0 && (tNum % tDen)); } /*---------------------------------------------------------------------------------------------- Return the absolute value of the given integer. ----------------------------------------------------------------------------------------------*/ inline uint Abs(int n) { return n < 0 ? -n : n; } /*********************************************************************************************** Hash functions. ***********************************************************************************************/ /* uint ComputeHashRgb(const byte * prgb, int cb, uint uHash = 0); uint CaseSensitiveComputeHash(LPCOLESTR psz, uint uHash = 0); uint CaseSensitiveComputeHashCch(const OLECHAR * prgch, int cch, uint uHash = 0); uint CaseInsensitiveComputeHash(LPCOLESTR psz, uint uHash = 0); uint CaseInsensitiveComputeHashCch(const OLECHAR * prgch, int cch, uint uHash = 0); */ /*********************************************************************************************** Getting primes. ***********************************************************************************************/ // Looks for a prime near u. The primes are gotten from a table in Util.cpp. uint GetPrimeNear(uint u); // Looks for a prime larger than u. If u is larger than the largest prime in the table, we // just return that largest prime. uint GetLargerPrime(uint u); // Looks for a prime smaller than u. If u is smaller than the smallest prime in the table, // we just return that smallest prime. uint GetSmallerPrime(uint u); /*********************************************************************************************** Max and Min. ***********************************************************************************************/ template<typename T> T Max(T t1, T t2) { return (t1 >= t2) ? t1 : t2; } template<typename T> T Min(T t1, T t2) { return (t1 <= t2) ? t1 : t2; } inline int NMax(int n1, int n2) { return (n1 >= n2) ? n1 : n2; } inline int NMin(int n1, int n2) { return (n1 <= n2) ? n1 : n2; } /*---------------------------------------------------------------------------------------------- If t < tMin, this returns tMin. Otherwise if t > tMax, it returns tMax. Otherwise it returns t. ----------------------------------------------------------------------------------------------*/ template<typename T> T Bound(T t, T tMin, T tMax) { return t < tMin ? tMin : t > tMax ? tMax : t; } inline int NBound(int n, int nMin, int nMax) { return n < nMin ? nMin : n > nMax ? nMax : n; } /*---------------------------------------------------------------------------------------------- This returns true iff tMin <= t && t < tLim. ----------------------------------------------------------------------------------------------*/ template<typename T> bool InInterval(T t, T tMin, T tLim) { return tMin <= t && t < tLim; } inline int SignedInt(OLECHAR ch) { if (ch & 0x00008000) { // Negative number. int nRet = (ch | 0xFFFF0000); return nRet; } else return (int)ch; } #endif // !UtilInt_H --- NEW FILE: UtilSet.h --- /*--------------------------------------------------------------------*//*:Ignore this sentence. Copyright (C) 2001 SIL International. All rights reserved. Distributable under the terms of either the Common Public License or the GNU Lesser General Public License, as specified in the LICENSING.txt file. File: Set.h Responsibility: Steve McConnel Last reviewed: Not yet. Description: This provides a template collection class to replace std::set. Its primary reason to exist is to allow explicit checking for internal memory allocation failures. ----------------------------------------------------------------------------------------------*/ #pragma once #ifndef SET_H_INCLUDED #define SET_H_INCLUDED //:End Ignore /*---------------------------------------------------------------------------------------------- Set template collection class for storing unique objects of an arbitrary class. Hungarian: set[T] ----------------------------------------------------------------------------------------------*/ template<class T, class H = HashObj, class Eq = EqlObj> class Set { public: //:> Internal helper classes. /*------------------------------------------------------------------------------------------ This is the basic data structure for storing a value in a set. In order to handle hash collisions, this structure is a member of a linked list. It should not be used outside the implementation of Set<T, H, Eq> itself. Hungarian: hsnd ------------------------------------------------------------------------------------------*/ class HashNode { public: // Default Constructor. HashNode(void) : m_value(T()), m_nHash(0), m_ihsndNext(0) { } // Constructor. HashNode(T & value, int nHash, int ihsndNext = -1) : m_value(value), m_nHash(nHash), m_ihsndNext(ihsndNext) { } // Destructor. ~HashNode() { } //:> Member variable access. void PutValue(T & value) { m_value = value; } T & GetValue() { return m_value; } void PutHash(int nHash) { m_nHash = nHash; } int GetHash() { return m_nHash; } void PutNext(int ihsndNext) { m_ihsndNext = ihsndNext; } int GetNext() { return m_ihsndNext; } /*-------------------------------------------------------------------------------------- Check whether the given HashNode is being used. --------------------------------------------------------------------------------------*/ bool InUse() { return m_ihsndNext >= -1; } protected: //:> Member variables. T m_value; int m_nHash; int m_ihsndNext; // -1 means end of list, -(ihsnd + 3) for free list members. }; /*------------------------------------------------------------------------------------------ This provides an iterator for stepping through all HashNodes stored in the set. This is useful primarily for saving the contents of a set to a file. Hungarian: itset[T] ------------------------------------------------------------------------------------------*/ class iterator { public: //:> Constructors/destructors/etc. iterator() : m_psetParent(NULL), m_irghsnd(0) { } iterator(Set<T,H,Eq> * pset, int irghsnd) : m_psetParent(pset), m_irghsnd(irghsnd) { } iterator(const iterator & v) : m_psetParent(v.m_psetParent), m_irghsnd(v.m_irghsnd) { } ~iterator() { } //:> Other public methods. iterator & operator = (const iterator & itseto) { m_psetParent = itseto.m_psetParent; m_irghsnd = itseto.m_irghsnd; return *this; } T & operator * (void) { AssertPtr(m_psetParent); AssertObj(m_psetParent); AssertPtr(m_psetParent->m_prghsnd); Assert(0 <= m_irghsnd && m_irghsnd < m_psetParent->m_ihsndLim); return m_psetParent->m_prghsnd[m_irghsnd].GetValue(); } HashNode * operator -> (void) { AssertPtr(m_psetParent); AssertObj(m_psetParent); AssertPtr(m_psetParent->m_prghsnd); Assert(0 <= m_irghsnd && m_irghsnd < m_psetParent->m_ihsndLim); return &m_psetParent->m_prghsnd[m_irghsnd]; } iterator & operator ++ (void) { AssertPtr(m_psetParent); AssertObj(m_psetParent); AssertPtr(m_psetParent->m_prghsnd); Assert(0 <= m_irghsnd && m_irghsnd <= m_psetParent->m_ihsndLim); ++m_irghsnd; // // Make sure that this new HashNode is actually in use. // while (m_irghsnd < m_psetParent->m_ihsndLim) { if (m_psetParent->m_prghsnd[m_irghsnd].InUse()) return *this; // Skip to the next one and check it. ++m_irghsnd; } if (m_irghsnd > m_psetParent->m_ihsndLim) m_irghsnd = m_psetParent->m_ihsndLim; return *this; } bool operator == (const iterator & itseto) { return (m_psetParent == itseto.m_psetParent) && (m_irghsnd == itseto.m_irghsnd); } bool operator != (const iterator & itseto) { return (m_psetParent != itseto.m_psetParent) || (m_irghsnd != itseto.m_irghsnd); } T & GetValue(void) { AssertPtr(m_psetParent); AssertObj(m_psetParent); AssertPtr(m_psetParent->m_prghsnd); Assert(0 <= m_irghsnd && m_irghsnd < m_psetParent->m_ihsndLim); Assert(m_psetParent->m_prghsnd[m_irghsnd].InUse()); return m_psetParent->m_prghsnd[m_irghsnd].GetValue(); } int GetHash() { AssertPtr(m_psetParent); AssertObj(m_psetParent); AssertPtr(m_psetParent->m_prghsnd); Assert(0 <= m_irghsnd && m_irghsnd < m_psetParent->m_ihsndLim); Assert(m_psetParent->m_prghsnd[m_irghsnd].InUse()); return m_psetParent->m_prghsnd[m_irghsnd].GetHash(); } int GetIndex() { AssertPtr(m_psetParent); AssertObj(m_psetParent); AssertPtr(m_psetParent->m_prghsnd); Assert(0 <= m_irghsnd && m_irghsnd < m_psetParent->m_ihsndLim); Assert(m_psetParent->m_prghsnd[m_irghsnd].InUse()); return m_irghsnd; } protected: // Member variables. Set<T,H,Eq> * m_psetParent; int m_irghsnd; }; friend class iterator; //:> Constructors/destructors/etc. Set(); ~Set(); //:> Other public methods. iterator Begin(); iterator End(); void Insert(T & value, int * pihsndOut = NULL); bool IsMember(T & value); bool Delete(T & value); void Clear(); bool GetIndex(T & value, int * pihsndRet); bool IndexValue(int ihsnd, T * pvalueRet); int Size(); bool Equals(Set<T, H, Eq> & itset); //:Ignore #ifdef DEBUG // For debugging. int _BucketCount(); int _EmptyBuckets(); int _BucketsUsed(); int _FullestBucket(); bool AssertValid() { AssertPtrN(m_prgihsndBuckets); Assert(m_prgihsndBuckets || !m_cBuckets); Assert(!m_prgihsndBuckets || m_cBuckets); AssertArray(m_prgihsndBuckets, m_cBuckets); AssertPtrN(m_prghsnd); Assert(m_prghsnd || !m_ihsndMax); Assert(!m_prghsnd || m_ihsndMax); AssertArray(m_prghsnd, m_ihsndMax); Assert(0 <= m_ihsndLim && m_ihsndLim <= m_ihsndMax); Assert(-1 <= FreeListIdx(m_ihsndFirstFree)); Assert(FreeListIdx(m_ihsndFirstFree) < m_ihsndLim); return true; } #endif //:End Ignore protected: //:> Member variables. int * m_prgihsndBuckets; int m_cBuckets; HashNode * m_prghsnd; int m_ihsndLim; int m_ihsndMax; int m_ihsndFirstFree; //:> Protected methods. /*------------------------------------------------------------------------------------------ Map between real index and "free list" index. Note that this mapping is bidirectional. @param ihsnd ------------------------------------------------------------------------------------------*/ int FreeListIdx(int ihsnd) { return -(ihsnd + 3); } }; // Local Variables: // mode:C++ // c-file-style:"cellar" // tab-width:4 // End: #endif /*SET_H_INCLUDED*/ Index: GrCommon.h =================================================================== RCS file: /cvsroot/silgraphite/silgraphite/include/GrCommon.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- GrCommon.h 17 Apr 2003 16:31:22 -0000 1.4 +++ GrCommon.h 17 Apr 2003 22:04:01 -0000 1.5 @@ -259,6 +259,7 @@ /************************************************************************************* Utility headers. *************************************************************************************/ +#include "UtilInt.h" #include "UtilRect.h" #include "GenericResource.h" #include "UtilString.h" Index: GrPlatform.h =================================================================== RCS file: /cvsroot/silgraphite/silgraphite/include/GrPlatform.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- GrPlatform.h 1 Apr 2003 08:55:09 -0000 1.1 +++ GrPlatform.h 17 Apr 2003 22:04:01 -0000 1.2 @@ -8,7 +8,6 @@ typedef unsigned short wchar_t; #endif - typedef unsigned char BYTE; #ifndef NULL @@ -34,6 +33,10 @@ { return false; } + + +// This should probably be moved here, if we keep it: +/////typedef wchar_t grwchar; // Can probably remove this stuff: |