- [Main Page](index.md)
- [Classes](annotated.md)
- [Files](files.md)
- [Directories](dirs.md)
- [Related Pages](pages.md)
- [File List](files.md)
- [File Members](globals.md)
HashArra.h¶
Go to the documentation of this file.
00001 // BC 11/4/2004 \BobL115\Include\HashArra.h
00002
00003 #ifndef __HASHARRA_H
00004 #define __HASHARRA_H
00005
00006 #ifndef __ALLOCATE_H
00007 #include "Allocate.h"
00008 #endif
00009 #if defined(_MSC_VER) || defined(_OSX)
00010 #include <new.h>
00011 #else
00012 #ifndef __PLACEMENT_NEW_INLINE
00013 #define __PLACEMENT_NEW_INLINE
00014 inline void *__cdecl operator new(size_t, void *_P)
00015 {return (_P); }
00016 #if _MSC_VER >= 1200
00017 inline void __cdecl operator delete(void *, void *)
00018 {return; }
00019 #endif
00020 #endif
00021 #endif
00022
00023 template<class TYPE>
00024 inline void AFXAPI HashConstructElements(TYPE* pElements, int nCount)
00025 {
00026 ASSERT(nCount == 0 ||
00027 AfxIsValidAddress(pElements, nCount * sizeof(TYPE)));
00028
00029 // first do bit-wise zero initialization
00030 memset((void*)pElements, 0, nCount * sizeof(TYPE));
00031
00032 // then call the constructor(s)
00033 for (; nCount--; pElements++)
00034 ::new((void*)pElements) TYPE;
00035 }
00036
00037 template<class TYPE>
00038 inline void AFXAPI HashDestructElements(TYPE* pElements, int nCount)
00039 {
00040 ASSERT(nCount == 0 ||
00041 AfxIsValidAddress(pElements, nCount * sizeof(TYPE)));
00042
00043 // call the destructor(s)
00044 for (; nCount--; pElements++)
00045 pElements->~TYPE();
00046 }
00047
00048 template<class TYPE>
00049 inline void ConstructTheElements(TYPE* pElements, int count)
00050 {
00051 memset((void*)pElements, 0, count * sizeof(TYPE));
00052
00053 for (; count--; pElements++)
00054 ::new((void*)pElements) TYPE;
00055 }
00056
00057 template<class TYPE>
00058 inline void DestructTheElements(TYPE* pElements, int count)
00059 {
00060 for (; count--; pElements++)
00061 pElements->~TYPE();
00062 }
00063
00064 template<class TYPE, class ARG_TYPE>
00065 class HashArray
00066 {
00067 public:
00068 HashArray();
00069
00070 int GetSize() const;
00071 int GetUpperBound() const;
00072 void SetSize(int newsize, int growby = -1);
00073
00074 void FreeExtra();
00075 void RemoveAll();
00076
00077 TYPE GetAt(int index) const;
00078 TYPE& ElementAt(int index);
00079 void SetAt(int index, ARG_TYPE newElement);
00080 void InsertAt(int nIndex, ARG_TYPE newElement, int nCount=1 );
00081 void RemoveAt(int index, int count=1);
00082
00083 TYPE operator [] ( int index ) const { return m_data[index]; }
00084 TYPE &operator [] (int index) { return m_data[index]; }
00085
00086 TYPE* GetArray();
00087
00088 void SetAtGrow(int index, ARG_TYPE newElement);
00089 int Add(ARG_TYPE newElement);
00090 void Push(ARG_TYPE newElement);
00091 TYPE Pop();
00092 TYPE GetPushed() const;
00093 void SetGranularity(int granularity) { m_growby = granularity; }
00094
00095 protected:
00096 TYPE* m_data;
00097 int m_size;
00098 int m_maxsize;
00099 int m_growby;
00100
00101 public:
00102 ~HashArray();
00103 };
00104
00105 template<class TYPE, class ARG_TYPE>
00106 inline int HashArray<TYPE, ARG_TYPE>::GetSize() const { return m_size; }
00107
00108 template<class TYPE, class ARG_TYPE>
00109 inline int HashArray<TYPE, ARG_TYPE>::GetUpperBound() const { return m_size-1; }
00110
00111 template<class TYPE, class ARG_TYPE>
00112 inline void HashArray<TYPE, ARG_TYPE>::RemoveAll() { SetSize(0, -1); }
00113
00114 template<class TYPE, class ARG_TYPE>
00115 inline TYPE HashArray<TYPE, ARG_TYPE>::GetAt(int index) const { return m_data[index]; }
00116
00117 template<class TYPE, class ARG_TYPE>
00118 inline TYPE& HashArray<TYPE, ARG_TYPE>::ElementAt(int index) { return m_data[index]; }
00119
00120 template<class TYPE, class ARG_TYPE>
00121 inline void HashArray<TYPE, ARG_TYPE>::SetAt(int index, ARG_TYPE newElement) { m_data[index] = newElement; }
00122
00123 template<class TYPE, class ARG_TYPE>
00124 inline TYPE* HashArray<TYPE, ARG_TYPE>::GetArray() { return (TYPE*)m_data; }
00125
00126 template<class TYPE, class ARG_TYPE>
00127 inline int HashArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement)
00128 {
00129 int index = m_size;
00130 SetAtGrow(index, newElement);
00131 return index;
00132 }
00133
00134 template<class TYPE, class ARG_TYPE>
00135 HashArray<TYPE, ARG_TYPE>::HashArray()
00136 {
00137 m_data = NULL;
00138 m_size = m_maxsize = m_growby = 0;
00139 }
00140
00141 template<class TYPE, class ARG_TYPE>
00142 HashArray<TYPE, ARG_TYPE>::~HashArray()
00143 {
00144 if (m_data != NULL) {
00145 DestructTheElements(m_data, m_size);
00146 FreeExt( m_data );
00147 }
00148 }
00149
00150 template<class TYPE, class ARG_TYPE>
00151 void HashArray<TYPE, ARG_TYPE>::SetSize(int newsize, int growby)
00152 {
00153 if (growby != -1)
00154 m_growby = growby;
00155
00156 if (newsize == 0) {
00157 if (m_data != NULL) {
00158 DestructTheElements(m_data, m_size);
00159 FreeExt( m_data );
00160 m_data = NULL;
00161 }
00162 m_size = m_maxsize = 0;
00163 }
00164 else if (m_data == NULL) {
00165 m_data = (TYPE*) AllocExt( newsize * sizeof(TYPE));
00166 ConstructTheElements(m_data, newsize);
00167 m_size = m_maxsize = newsize;
00168 }
00169 else if (newsize <= m_maxsize) {
00170 if (newsize > m_size) {
00171 ConstructTheElements(&m_data[m_size], newsize-m_size);
00172 }
00173 else if (m_size > newsize) {
00174 DestructTheElements(&m_data[newsize], m_size-newsize);
00175 }
00176 m_size = newsize;
00177 }
00178 else {
00179 int growby = m_growby;
00180 if (growby == 0) {
00181 growby = m_size / 8;
00182 growby = (growby < 4) ? 4 : ((growby > 1024) ? 1024 : growby);
00183 }
00184 int newmax;
00185 if (newsize < m_maxsize + growby)
00186 newmax = m_maxsize + growby;
00187 else
00188 newmax = newsize;
00189
00190 TYPE* newdata = (TYPE*) AllocExt( newmax * sizeof(TYPE));
00191
00192 memcpy(newdata, m_data, m_size * sizeof(TYPE));
00193
00194 ConstructTheElements(&newdata[m_size], newsize-m_size);
00195
00196 FreeExt( m_data );
00197 m_data = newdata;
00198 m_size = newsize;
00199 m_maxsize = newmax;
00200 }
00201 }
00202
00203 template<class TYPE, class ARG_TYPE>
00204 void HashArray<TYPE, ARG_TYPE>::FreeExtra()
00205 {
00206 if (m_size != m_maxsize) {
00207 TYPE* newdata = NULL;
00208 if (m_size != 0) {
00209 newdata = (TYPE*) AllocExt( m_size * sizeof(TYPE));
00210 memcpy(newdata, m_data, m_size * sizeof(TYPE));
00211 }
00212
00213 FreeExt( m_data );
00214 m_data = newdata;
00215 m_maxsize = m_size;
00216 }
00217 }
00218
00219 template<class TYPE, class ARG_TYPE>
00220 void HashArray<TYPE, ARG_TYPE>::SetAtGrow(int index, ARG_TYPE newElement)
00221 {
00222 if (index >= m_size)
00223 SetSize(index+1, -1);
00224 m_data[index] = newElement;
00225 }
00226
00227 template<class TYPE, class ARG_TYPE>
00228 void HashArray<TYPE, ARG_TYPE>::InsertAt(int nIndex, ARG_TYPE newElement, int nCount /*=1*/)
00229 {
00230 // YP Comeback: "this" is not a CObject so can not be used with ASSERT_VALID
00231 // ASSERT_VALID(this);
00232 ASSERT(nIndex >= 0); // will expand to meet need
00233 ASSERT(nCount > 0); // zero or negative size not allowed
00234
00235 if (nIndex >= m_size)
00236 {
00237 // adding after the end of the array
00238 SetSize(nIndex + nCount, -1); // grow so nIndex is valid
00239 }
00240 else
00241 {
00242 // inserting in the middle of the array
00243 int nOldSize = m_size;
00244 SetSize(m_size + nCount, -1); // grow it to new size
00245 // destroy intial data before copying over it
00246 #if (_MFC_VER > 0x0420)
00247 HashDestructElements<TYPE>(&m_data[nOldSize], nCount);
00248 #else
00249 HashDestructElements(&m_data[nOldSize], nCount);
00250 #endif
00251 // shift old data up to fill gap
00252 memmove(&m_data[nIndex+nCount], &m_data[nIndex],
00253 (nOldSize-nIndex) * sizeof(TYPE));
00254
00255 // re-init slots we copied from
00256 #if (_MFC_VER > 0x0420)
00257 HashConstructElements<TYPE>(&m_data[nIndex], nCount);
00258 #else
00259 HashConstructElements(&m_data[nIndex], nCount);
00260 #endif
00261 }
00262
00263 // insert new value in the gap
00264 ASSERT(nIndex + nCount <= m_size);
00265 while (nCount--)
00266 m_data[nIndex++] = newElement;
00267 }
00268
00269 template<class TYPE, class ARG_TYPE>
00270 void HashArray<TYPE, ARG_TYPE>::RemoveAt(int index, int count)
00271 {
00272 // just remove a range
00273 int movecount = m_size - (index + count);
00274
00275 #if (_MFC_VER > 0x0420)
00276 HashDestructElements<TYPE>(&m_data[index], count);
00277 #else
00278 HashDestructElements(&m_data[index], count);
00279 #endif
00280
00281 if (movecount)
00282 memmove(&m_data[index], &m_data[index + count],
00283 movecount * sizeof(TYPE));
00284 m_size -= count;
00285 }
00286
00287 template<class TYPE, class ARG_TYPE>
00288 inline void HashArray<TYPE, ARG_TYPE>::Push(ARG_TYPE newElement)
00289 {
00290 SetAtGrow(m_size, newElement);
00291 }
00292
00293 template<class TYPE, class ARG_TYPE>
00294 TYPE HashArray<TYPE, ARG_TYPE>::Pop()
00295 {
00296 if (m_size < 1) {
00297 ASSERT(FALSE);
00298 return (TYPE)NULL;
00299 }
00300 TYPE rvalue = m_data[m_size-1];
00301 #if (_MFC_VER > 0x0420)
00302 HashDestructElements<TYPE>(&m_data[m_size-1], 1);
00303 #else
00304 HashDestructElements(&m_data[m_size-1], 1);
00305 #endif
00306
00307 --m_size;
00308 return rvalue;
00309 }
00310
00311 template<class TYPE, class ARG_TYPE>
00312 inline TYPE HashArray<TYPE, ARG_TYPE>::GetPushed() const { return m_data[m_size-1]; }
00313
00314 #endif __HASHARRA_H
This A:M SDK v12.0 documentation is maintained by Hash Inc. Please address any comments concerning this documentation to AMReports. If you have any information, knowledge, or documentation to share with the A:M developer community, please post them on the Hash SDK forum.
Generated on Thu Oct 27 11:46:44 2005 with doxygen 1.4.5 written by Dimitri van Heesch, © 1997-2001