00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _array_h
00018 #define _array_h
00019
00020 #include <spl/types.h>
00021 #include <spl/Debug.h>
00022
00023 #ifdef _WINDOWS
00024 #include <spl/configwin32.h>
00025 #else
00026 #include <spl/autoconf/config.h>
00027 #endif
00028
00029 #include <spl/Exception.h>
00030 #include <spl/collection/IEnumerable.h>
00031 #include <spl/IIterator.h>
00032 #include <spl/Memory.h>
00033 #include <spl/RefCountPtr.h>
00034
00043 template<typename T>
00044 class Array : public IEnumerable<T>
00045 {
00046 private:
00047 T *m_data;
00048 int m_len;
00049
00050 public:
00051 class Iterator : public IIterator<T>
00052 {
00053 private:
00054 const Array<T> *m_ap;
00055 int m_pos;
00056
00057 public:
00058 Iterator()
00059 : m_ap(NULL), m_pos(-1)
00060 {
00061 }
00062
00063 Iterator(const Array<T> *ap)
00064 : m_ap(ap), m_pos(-1)
00065 {
00066 }
00067
00068 Iterator(const Iterator& ai)
00069 : m_ap(ai.m_ap), m_pos(ai.m_pos)
00070 {
00071 }
00072
00073 virtual bool Next()
00074 {
00075 if (NULL == m_ap || ++m_pos >= m_ap->Count())
00076 {
00077 return false;
00078 }
00079 return true;
00080 }
00081
00082 virtual bool Prev()
00083 {
00084 if (--m_pos < 0)
00085 {
00086 return false;
00087 }
00088 return true;
00089 }
00090
00091 virtual T Current()
00092 {
00093 return m_ap->ElementAt(m_pos);
00094 }
00095
00096 virtual T& CurrentRef()
00097 {
00098 return m_ap->ElementAtRef(m_pos);
00099 }
00100 };
00101
00102 protected:
00103 virtual RefCountPtr<IIterator<T> > IteratorPtr()
00104 {
00105 return RefCountPtr<IIterator<T> >(new Iterator(this));
00106 }
00107
00108 public:
00112 Array(int count)
00113 : m_len(count)
00114 {
00115 ASSERT(m_len > -1);
00116 if (0 == m_len)
00117 {
00118 m_data = NULL;
00119 return;
00120 }
00121 m_data = new T[m_len];
00122
00123 for ( int x = 0; x < m_len; x++ )
00124 {
00125 m_data[x] = T();
00126 }
00127 }
00128
00129 Array()
00130 : m_len(0), m_data(NULL)
00131 {
00132 }
00133
00134 Array(const Array& v)
00135 : m_len(v.m_len)
00136 {
00137 ASSERT(m_len > -1);
00138 if (0 == m_len)
00139 {
00140 m_data = NULL;
00141 return;
00142 }
00143
00144 m_data = new T[m_len];
00145
00146 for ( int x = 0; x < m_len; x++ )
00147 {
00148 m_data[x] = v.m_data[x];
00149 }
00150 }
00151
00152 Array(const T* v, int len)
00153 : m_len(len)
00154 {
00155 if (0 == m_len)
00156 {
00157 m_data = NULL;
00158 return;
00159 }
00160
00161 m_data = new T[m_len];
00162
00163 for ( int x = 0; x < m_len; x++ )
00164 {
00165 m_data[x] = v[x];
00166 }
00167 }
00168
00169 virtual ~Array()
00170 {
00171 if (NULL != m_data)
00172 {
00173 ASSERT_MEM( m_data, sizeof(T) * m_len );
00174 delete[] m_data;
00175 }
00176 }
00177
00178 Array& operator =(const Array& v)
00179 {
00180 Array<T>::ValidateMem();
00181
00182 if (m_len > 0)
00183 {
00184 delete[] m_data;
00185 }
00186 else
00187 {
00188 ASSERT(NULL == m_data);
00189 }
00190
00191 if (0 == (m_len = v.m_len))
00192 {
00193 m_data = NULL;
00194 }
00195 else
00196 {
00197 m_data = new T[m_len];
00198 }
00199
00200 for ( int x = 0; x < m_len; x++ )
00201 {
00202 m_data[x] = v.m_data[x];
00203 }
00204
00205 return *this;
00206 }
00207
00208 inline Iterator Begin() const
00209 {
00210 return Iterator(this);
00211 }
00212
00218 inline T ElementAt( const int pos ) const
00219 {
00220 if (pos >= m_len || 0 > pos)
00221 {
00222 throw new IndexOutOfBoundsException();
00223 }
00224 ASSERT_MEM( m_data, sizeof(T) * m_len);
00225
00226 return m_data[pos];
00227 }
00228
00234 inline T& ElementAtRef( const int pos ) const
00235 {
00236 ASSERT_MEM( m_data, sizeof(T) * m_len );
00237 if ( pos >= m_len || 0 > pos )
00238 {
00239 throw IndexOutOfBoundsException();
00240 }
00241 return m_data[pos];
00242 }
00243
00244 inline void SetElementAt( const int pos, T val )
00245 {
00246 if ( pos >= m_len || 0 > pos )
00247 {
00248 throw IndexOutOfBoundsException();
00249 }
00250 m_data[pos] = val;
00251 }
00252
00253 inline T& operator[] (const int idx)
00254 {
00255 return ElementAtRef(idx);
00256 }
00257
00258 inline const T& operator[] (const int idx) const
00259 {
00260 return ElementAtRef(idx);
00261 }
00262
00263 inline operator T*() const
00264 {
00265 return m_data;
00266 }
00267
00268 inline T* Data() const
00269 {
00270 return m_data;
00271 }
00272
00277 inline void Clear()
00278 {
00279 Clear(0, Length());
00280 }
00281
00282 void Clear(int start, int len)
00283 {
00284 ASSERT(len - start <= m_len);
00285 for ( int x = start; x < m_len && x < len; x++ )
00286 {
00287 m_data[x + start] = T();
00288 }
00289 }
00290
00291 inline void ClearBinary()
00292 {
00293 ClearBinary(0, Length());
00294 }
00295
00296 void ClearBinary(int start, int len)
00297 {
00298 ASSERT(len - start <= m_len);
00299 memset(m_data, 0, sizeof(T) * (len - start));
00300 for ( int x = start; x < m_len && x < len; x++ )
00301 {
00302 m_data[x + start] = T();
00303 }
00304 }
00305
00309 inline int Count() const
00310 {
00311 return m_len;
00312 }
00313
00314 inline int Length() const
00315 {
00316 return m_len;
00317 }
00318
00319 bool Equals(const Array<T>& a) const
00320 {
00321 if (m_len != a.m_len)
00322 {
00323 return false;
00324 }
00325 for (int x = 0; x < m_len; x++)
00326 {
00327 if (m_data[x] != a.m_data[x])
00328 {
00329 return false;
00330 }
00331 }
00332 return true;
00333 }
00334
00335 bool AreElementsEqualTo(const T& val) const
00336 {
00337 for (int x = 0; x < m_len; x++)
00338 {
00339 if (m_data[x] != val)
00340 {
00341 return false;
00342 }
00343 }
00344 return true;
00345 }
00346
00347 inline RefCountPtr<Array<T> > Clone() const
00348 {
00349 return RefCountPtr<Array<T> >(new Array<T>(*this));
00350 }
00351
00352 void CopyTo(Array<T>& to, int sourceStart) const
00353 {
00354 if (sourceStart >= m_len)
00355 {
00356 return;
00357 }
00358 int pos = 0;
00359 for (int x = sourceStart; x < m_len && pos < to.m_len; x++)
00360 {
00361 to.m_data[pos++] = m_data[x];
00362 }
00363 }
00364
00365 inline void CopyTo(Array<T>& to) const
00366 {
00367 CopyTo(to, 0);
00368 }
00369
00370 void CopyToBinary(Array<T>& to, int sourceStart) const
00371 {
00372 if (sourceStart >= m_len)
00373 {
00374 return;
00375 }
00376 int len = m_len - sourceStart;
00377 if (len >= to.Length())
00378 {
00379 len = to.Length();
00380 }
00381 memcpy(to.m_data, &m_data[sourceStart], sizeof(T) * len);
00382 }
00383
00384 inline void CopyToBinary(Array<T>& to) const
00385 {
00386 CopyToBinary(to, 0);
00387 }
00388
00389 inline static bool Equals(const Array<T>& a, const Array<T>& b)
00390 {
00391 return Equals(a, 0, b, 0, a.Length());
00392 }
00393
00394 static bool Equals(const Array<T>& a, int astart, const Array<T>& b, int bstart, int len)
00395 {
00396 int diff = (a.Length() - astart) - (b.Length() - bstart);
00397 if (0 != diff)
00398 {
00399 return false;
00400 }
00401
00402 int length = a.Length() - astart;
00403 if (length < len)
00404 {
00405 return false;
00406 }
00407 for ( int x = 0; x < length; x++)
00408 {
00409 if (!(a[x + astart] == b[x + bstart]))
00410 {
00411 return false;
00412 }
00413 }
00414 return true;
00415 }
00416
00417 static void Copy(const Array<T>& from, int fromStart, Array<T>& to, int toStart, int length)
00418 {
00419 for ( int x = 0; x < length; x++)
00420 {
00421 to[toStart + x] = from[fromStart + x];
00422 }
00423 }
00424
00425 inline static void CopyBinary(const Array<T>& from, int fromStart, Array<T>& to, int toStart, int length)
00426 {
00427 memmove(&to.m_data[toStart], &from.m_data[fromStart], sizeof(T) * length);
00428 }
00429
00430 #if defined(DEBUG) || defined(_DEBUG)
00431 void CheckMem() const
00432 {
00433 if (NULL != m_data)
00434 {
00435 DEBUG_NOTE_MEM_ALLOCATION( m_data );
00436 for ( int x = 0; x < m_len; x++ )
00437 {
00438 ValidateType( m_data[x] );
00439 }
00440 }
00441 }
00442
00443 void ValidateMem() const
00444 {
00445 if (NULL != m_data)
00446 {
00447 ASSERT_MEM(m_data, sizeof(T) * m_len);
00448 for ( int x = 0; x < m_len; x++ )
00449 {
00450 ValidateType( m_data[x] );
00451 }
00452 }
00453 }
00454 #endif
00455 };
00456
00457 REGISTER_TYPEOF( 151, Array<char> );
00458 REGISTER_TYPEOF( 152, Array<byte> );
00459 REGISTER_TYPEOF( 156, Array<int16> );
00460 REGISTER_TYPEOF( 157, Array<uint16> );
00461 REGISTER_TYPEOF( 160, Array<int32> );
00462 REGISTER_TYPEOF( 161, Array<uint32> );
00463 REGISTER_TYPEOF( 162, Array<int64> );
00464 REGISTER_TYPEOF( 163, Array<uint64> );
00465 REGISTER_TYPEOF( 164, Array<float32> );
00466 REGISTER_TYPEOF( 165, Array<float64> );
00467
00470 #endif