Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

SgArrayList.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file SgArrayList.h
00003     Static list. */
00004 //----------------------------------------------------------------------------
00005 
00006 #ifndef SG_ARRAYLIST_H
00007 #define SG_ARRAYLIST_H
00008 
00009 #include <algorithm>
00010 
00011 //----------------------------------------------------------------------------
00012 
00013 /** Static list not using dynamic memory allocation.
00014     Elements need to have a default constructor.
00015     They should be value-types, not entity-types, because operations like
00016     Clear() do not call the destructor of the old elements immediately. */
00017 template<typename T, int SIZE>
00018 class SgArrayList
00019 {
00020 public:
00021     /** Const iterator */
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     /** Non-const iterator */
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     /** Construct list with one element. */
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     /** Remove first occurrence of a value.
00079         Like RemoveFirst, but more efficient and does not preserve
00080         order of remaining elements. The first occurrence of the value is
00081         replaced by the last element.
00082         @return false, if element was not found */
00083     bool Exclude(const T& val);
00084 
00085     /** PushBack value at the end of the list if it's not already in the
00086         list. */
00087     void Include(const T& val);
00088 
00089     /** Build intersection with other list.
00090         List may not contain duplicate entries. */
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     /** Remove the last element of the list.
00102         Does not return the last element for efficiency. To get the last
00103         element, use Last() before calling PopBack(). */
00104     void PopBack();
00105 
00106     void PushBack(const T& val);
00107 
00108     /** Push back all elements of another list.
00109         Works with lists of different maximum sizes.
00110         Requires: Total resulting number of elements will fit into the target
00111         list. */
00112     template<int SIZE2>
00113     void PushBackList(const SgArrayList<T,SIZE2>& list);
00114 
00115     /** Remove first occurence of a value.
00116         Preserves order of remaining elements.
00117         @see Exclude */
00118     void RemoveFirst(const T& val);
00119 
00120     /** Resize list.
00121         If new length is greater than current length, then the elements
00122         at a place greater than the old length are not initialized, they are
00123         just the old elements at this place.
00124         This is necessary if elements are re-used for efficiency and will be
00125         initialized later. */
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     // Go backwards through list, because with game playing programs
00285     // it is more likely that a recently added element is removed first
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


Sun Mar 13 2011 Doxygen 1.7.1