00001
00002
00003
00004
00005
00006 #ifndef SG_ARRAYLIST_H
00007 #define SG_ARRAYLIST_H
00008
00009 #include <algorithm>
00010
00011
00012
00013
00014
00015
00016
00017 template<typename T, int SIZE>
00018 class SgArrayList
00019 {
00020 public:
00021
00022 class Iterator
00023 {
00024 public:
00025 Iterator(const SgArrayList& list);
00026
00027 const T& operator*() const;
00028
00029 void operator++();
00030
00031 operator bool() const;
00032
00033 private:
00034 const T* m_end;
00035
00036 const T* m_current;
00037 };
00038
00039
00040 class NonConstIterator
00041 {
00042 public:
00043 NonConstIterator(SgArrayList& list);
00044
00045 T& operator*() const;
00046
00047 void operator++();
00048
00049 operator bool() const;
00050
00051 private:
00052 const T* m_end;
00053
00054 T* m_current;
00055 };
00056
00057 SgArrayList();
00058
00059
00060 explicit SgArrayList(const T& val);
00061
00062 SgArrayList(const SgArrayList<T,SIZE>& list);
00063
00064 SgArrayList& operator=(const SgArrayList& list);
00065
00066 bool operator==(const SgArrayList& list) const;
00067
00068 bool operator!=(const SgArrayList& list) const;
00069
00070 T& operator[](int index);
00071
00072 const T& operator[](int index) const;
00073
00074 void Clear();
00075
00076 bool Contains(const T& val) const;
00077
00078
00079
00080
00081
00082
00083 bool Exclude(const T& val);
00084
00085
00086
00087 void Include(const T& val);
00088
00089
00090
00091 SgArrayList Intersect(const SgArrayList<T,SIZE>& list) const;
00092
00093 bool IsEmpty() const;
00094
00095 T& Last();
00096
00097 const T& Last() const;
00098
00099 int Length() const;
00100
00101
00102
00103
00104 void PopBack();
00105
00106 void PushBack(const T& val);
00107
00108
00109
00110
00111
00112 template<int SIZE2>
00113 void PushBackList(const SgArrayList<T,SIZE2>& list);
00114
00115
00116
00117
00118 void RemoveFirst(const T& val);
00119
00120
00121
00122
00123
00124
00125
00126 void Resize(int length);
00127
00128 bool SameElements(const SgArrayList& list) const;
00129
00130 void SetTo(const T& val);
00131
00132 void Sort();
00133
00134 private:
00135 friend class Iterator;
00136 friend class NonConstIterator;
00137
00138 int m_len;
00139
00140 T m_array[SIZE];
00141 };
00142
00143
00144
00145 template<typename T, int SIZE>
00146 inline SgArrayList<T,SIZE>::Iterator::Iterator(const SgArrayList& list)
00147 : m_end(list.m_array + list.Length()),
00148 m_current(list.m_array)
00149 {
00150 }
00151
00152 template<typename T, int SIZE>
00153 inline const T& SgArrayList<T,SIZE>::Iterator::operator*() const
00154 {
00155 SG_ASSERT(*this);
00156 return *m_current;
00157 }
00158
00159 template<typename T, int SIZE>
00160 inline void SgArrayList<T,SIZE>::Iterator::operator++()
00161 {
00162 ++m_current;
00163 }
00164
00165 template<typename T, int SIZE>
00166 inline SgArrayList<T,SIZE>::Iterator::operator bool() const
00167 {
00168 return m_current < m_end;
00169 }
00170
00171 template<typename T, int SIZE>
00172 inline
00173 SgArrayList<T,SIZE>::NonConstIterator::NonConstIterator(SgArrayList& list)
00174 : m_end(list.m_array + list.Length()),
00175 m_current(list.m_array)
00176 {
00177 }
00178
00179 template<typename T, int SIZE>
00180 inline T& SgArrayList<T,SIZE>::NonConstIterator::operator*() const
00181 {
00182 SG_ASSERT(*this);
00183 return *m_current;
00184 }
00185
00186 template<typename T, int SIZE>
00187 inline void SgArrayList<T,SIZE>::NonConstIterator::operator++()
00188 {
00189 ++m_current;
00190 }
00191
00192 template<typename T, int SIZE>
00193 inline SgArrayList<T,SIZE>::NonConstIterator::operator bool() const
00194 {
00195 return m_current < m_end;
00196 }
00197
00198 template<typename T, int SIZE>
00199 inline SgArrayList<T,SIZE>::SgArrayList()
00200 : m_len(0)
00201 {
00202 }
00203
00204 template<typename T, int SIZE>
00205 inline SgArrayList<T,SIZE>::SgArrayList(const T& val)
00206 {
00207 SetTo(val);
00208 m_len = 1;
00209 m_array[0] = val;
00210 }
00211
00212 template<typename T, int SIZE>
00213 inline SgArrayList<T,SIZE>::SgArrayList(const SgArrayList<T,SIZE>& list)
00214 {
00215 *this = list;
00216 }
00217
00218 template<typename T, int SIZE>
00219 SgArrayList<T,SIZE>& SgArrayList<T,SIZE>::operator=(const SgArrayList& list)
00220 {
00221 m_len = list.m_len;
00222 T* p = m_array;
00223 const T* pp = list.m_array;
00224 for (int i = m_len; i--; ++p, ++pp)
00225 *p = *pp;
00226 return *this;
00227 }
00228
00229 template<typename T, int SIZE>
00230 bool SgArrayList<T,SIZE>::operator==(const SgArrayList& list) const
00231 {
00232 if (m_len != list.m_len)
00233 return false;
00234 const T* p = m_array;
00235 const T* pp = list.m_array;
00236 for (int i = m_len; i--; ++p, ++pp)
00237 if (*p != *pp)
00238 return false;
00239 return true;
00240 }
00241
00242 template<typename T, int SIZE>
00243 inline bool SgArrayList<T,SIZE>::operator!=(const SgArrayList& list) const
00244 {
00245 return ! this->operator==(list);
00246 }
00247
00248 template<typename T, int SIZE>
00249 inline T& SgArrayList<T,SIZE>::operator[](int index)
00250 {
00251 SG_ASSERT(index >= 0);
00252 SG_ASSERT(index < m_len);
00253 return m_array[index];
00254 }
00255
00256 template<typename T, int SIZE>
00257 inline const T& SgArrayList<T,SIZE>::operator[](int index) const
00258 {
00259 SG_ASSERT(index >= 0);
00260 SG_ASSERT(index < m_len);
00261 return m_array[index];
00262 }
00263
00264 template<typename T, int SIZE>
00265 inline void SgArrayList<T,SIZE>::Clear()
00266 {
00267 m_len = 0;
00268 }
00269
00270 template<typename T, int SIZE>
00271 bool SgArrayList<T,SIZE>::Contains(const T& val) const
00272 {
00273 int i;
00274 const T* t = m_array;
00275 for (i = m_len; i--; ++t)
00276 if (*t == val)
00277 return true;
00278 return false;
00279 }
00280
00281 template<typename T, int SIZE>
00282 bool SgArrayList<T,SIZE>::Exclude(const T& val)
00283 {
00284
00285
00286 T* t = m_array + m_len - 1;
00287 for (int i = m_len; i--; --t)
00288 if (*t == val)
00289 {
00290 --m_len;
00291 if (m_len > 0)
00292 *t = *(m_array + m_len);
00293 return true;
00294 }
00295 return false;
00296 }
00297
00298 template<typename T, int SIZE>
00299 void SgArrayList<T,SIZE>::Include(const T& val)
00300 {
00301 if (! Contains(val))
00302 PushBack(val);
00303 }
00304
00305 template<typename T, int SIZE>
00306 SgArrayList<T,SIZE>
00307 SgArrayList<T,SIZE>::Intersect(const SgArrayList<T,SIZE>& list) const
00308 {
00309 SgArrayList<T, SIZE> result;
00310 const T* t = m_array;
00311 for (int i = m_len; i--; ++t)
00312 if (list.Contains(*t))
00313 {
00314 SG_ASSERT(! result.Contains(*t));
00315 result.PushBack(*t);
00316 }
00317 return result;
00318 }
00319
00320 template<typename T, int SIZE>
00321 inline bool SgArrayList<T,SIZE>::IsEmpty() const
00322 {
00323 return m_len == 0;
00324 }
00325
00326 template<typename T, int SIZE>
00327 inline T& SgArrayList<T,SIZE>::Last()
00328 {
00329 SG_ASSERT(m_len > 0);
00330 return m_array[m_len - 1];
00331 }
00332
00333 template<typename T, int SIZE>
00334 inline const T& SgArrayList<T,SIZE>::Last() const
00335 {
00336 SG_ASSERT(m_len > 0);
00337 return m_array[m_len - 1];
00338 }
00339
00340 template<typename T, int SIZE>
00341 inline int SgArrayList<T,SIZE>::Length() const
00342 {
00343 return m_len;
00344 }
00345
00346 template<typename T, int SIZE>
00347 inline void SgArrayList<T,SIZE>::PopBack()
00348 {
00349 SG_ASSERT(m_len > 0);
00350 --m_len;
00351 }
00352
00353 template<typename T, int SIZE>
00354 inline void SgArrayList<T,SIZE>::PushBack(const T& val)
00355 {
00356 SG_ASSERT(m_len < SIZE);
00357 m_array[m_len++] = val;
00358 }
00359
00360 template<typename T, int SIZE>
00361 template<int SIZE2>
00362 inline void SgArrayList<T,SIZE>::PushBackList(const SgArrayList<T,SIZE2>& list)
00363 {
00364 for (typename SgArrayList<T,SIZE2>::Iterator it(list); it; ++it)
00365 PushBack(*it);
00366 }
00367
00368 template<typename T, int SIZE>
00369 void SgArrayList<T,SIZE>::RemoveFirst(const T& val)
00370 {
00371 int i;
00372 T* t = m_array;
00373 for (i = m_len; i--; ++t)
00374 if (*t == val)
00375 {
00376 for ( ; i--; ++t)
00377 *t = *(t + 1);
00378 --m_len;
00379 break;
00380 }
00381 }
00382
00383 template<typename T, int SIZE>
00384 inline void SgArrayList<T,SIZE>::Resize(int length)
00385 {
00386 SG_ASSERT(length >= 0);
00387 SG_ASSERT(length <= SIZE);
00388 m_len = length;
00389 }
00390
00391 template<typename T, int SIZE>
00392 bool SgArrayList<T,SIZE>::SameElements(const SgArrayList& list) const
00393 {
00394 if (m_len != list.m_len)
00395 return false;
00396 const T* p = m_array;
00397 for (int i = m_len; i--; ++p)
00398 if (! list.Contains(*p))
00399 return false;
00400 return true;
00401 }
00402
00403 template<typename T, int SIZE>
00404 inline void SgArrayList<T,SIZE>::SetTo(const T& val)
00405 {
00406 m_len = 1;
00407 m_array[0] = val;
00408 }
00409
00410 template<typename T, int SIZE>
00411 inline void SgArrayList<T,SIZE>::Sort()
00412 {
00413 std::sort(m_array, m_array + m_len);
00414 }
00415
00416
00417
00418 #endif // SG_ARRAYLIST_H