Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

SgArray.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file SgArray.h
00003     Static array.
00004 */
00005 //----------------------------------------------------------------------------
00006 
00007 #ifndef SG_ARRAY_H
00008 #define SG_ARRAY_H
00009 
00010 #include <cstring>
00011 
00012 //----------------------------------------------------------------------------
00013 
00014 template<typename T, int SIZE> class SgArray;
00015 
00016 /** Helper class to allow partial specialization of SgArray::operator=.
00017     Partial member function specialization is not yet supported by standard
00018     C++.
00019 */
00020 template<typename T, int SIZE>
00021 class SgArrayAssign
00022 {
00023 public:
00024     static void Assign(T* dest, const T* src);
00025 };
00026 
00027 template<int SIZE>
00028 class SgArrayAssign<int,SIZE>
00029 {
00030 public:
00031     static void Assign(int* dest, const int* src);
00032 };
00033 
00034 template<int SIZE>
00035 class SgArrayAssign<bool,SIZE>
00036 {
00037 public:
00038     static void Assign(bool* dest, const bool* src);
00039 };
00040 
00041 template<typename T,int SIZE>
00042 class SgArrayAssign<T*,SIZE>
00043 {
00044 public:
00045     static void Assign(T** dest, T* const * src);
00046 };
00047 
00048 template<typename T, int SIZE>
00049 void SgArrayAssign<T,SIZE>::Assign(T* dest, const T* src)
00050 {
00051     SG_ASSERT(dest != src); // self-assignment not supported for efficiency
00052     T* p = dest;
00053     const T* pp = src;
00054     for (int i = SIZE; i--; ++p, ++pp)
00055         *p = *pp;
00056 }
00057 
00058 template<int SIZE>
00059 void SgArrayAssign<int,SIZE>::Assign(int* dest, const int* src)
00060 {
00061     SG_ASSERT(dest != src); // self-assignment not supported for efficiency
00062     std::memcpy(dest, src, SIZE * sizeof(int));
00063 }
00064 
00065 template<int SIZE>
00066 void SgArrayAssign<bool,SIZE>::Assign(bool* dest, const bool* src)
00067 {
00068     SG_ASSERT(dest != src); // self-assignment not supported for efficiency
00069     std::memcpy(dest, src, SIZE * sizeof(bool));
00070 }
00071 
00072 template<typename T, int SIZE>
00073 void SgArrayAssign<T*,SIZE>::Assign(T** dest, T* const * src)
00074 {
00075     SG_ASSERT(dest != src); // self-assignment not supported for efficiency
00076     std::memcpy(dest, src, SIZE * sizeof(T*));
00077 }
00078 
00079 //----------------------------------------------------------------------------
00080 
00081 /** Static array.
00082     Wrapper class around a C style array.
00083     Uses assertions for indices in range in debug mode.
00084     @deprecated Use boost::array instead
00085 */
00086 template<typename T, int SIZE>
00087 class SgArray
00088 {
00089 public:
00090     /** Local const iterator */
00091     class Iterator
00092     {
00093     public:
00094         Iterator(const SgArray& array);
00095 
00096         const T& operator*() const;
00097 
00098         void operator++();
00099 
00100         operator bool() const;
00101 
00102     private:
00103         const T* m_end;
00104 
00105         const T* m_current;
00106     };
00107 
00108     /** Local non-const iterator */
00109     class NonConstIterator
00110     {
00111     public:
00112         NonConstIterator(SgArray& array);
00113 
00114         T& operator*() const;
00115 
00116         void operator++();
00117 
00118         operator bool() const;
00119 
00120     private:
00121         const T* m_end;
00122 
00123         T* m_current;
00124     };
00125 
00126     SgArray();
00127 
00128     SgArray(const SgArray& array);
00129 
00130     explicit SgArray(const T& val);
00131 
00132     SgArray& operator=(const SgArray& array);
00133 
00134     T& operator[](int index);
00135 
00136     const T& operator[](int index) const;
00137 
00138     SgArray& operator*=(T val);
00139 
00140     void Fill(const T& val);
00141 
00142 private:
00143     friend class Iterator;
00144     friend class NonConstIterator;
00145 
00146     T m_array[SIZE];
00147 };
00148 
00149 template<typename T, int SIZE>
00150 SgArray<T,SIZE>::Iterator::Iterator(const SgArray& array)
00151     : m_end(array.m_array + SIZE),
00152       m_current(array.m_array)
00153 {
00154 }
00155 
00156 template<typename T, int SIZE>
00157 const T& SgArray<T,SIZE>::Iterator::operator*() const
00158 {
00159     SG_ASSERT(*this);
00160     return *m_current;
00161 }
00162 
00163 template<typename T, int SIZE>
00164 void SgArray<T,SIZE>::Iterator::operator++()
00165 {
00166     ++m_current;
00167 }
00168 
00169 template<typename T, int SIZE>
00170 SgArray<T,SIZE>::Iterator::operator bool() const
00171 {
00172     return m_current < m_end;
00173 }
00174 
00175 template<typename T, int SIZE>
00176 SgArray<T,SIZE>::NonConstIterator::NonConstIterator(SgArray& array)
00177     : m_end(array.m_array + SIZE),
00178       m_current(array.m_array)
00179 { }
00180 
00181 template<typename T, int SIZE>
00182 T& SgArray<T,SIZE>::NonConstIterator::operator*() const
00183 {
00184     SG_ASSERT(*this);
00185     return *m_current;
00186 }
00187 
00188 template<typename T, int SIZE>
00189 void SgArray<T,SIZE>::NonConstIterator::operator++()
00190 {
00191     ++m_current;
00192 }
00193 
00194 template<typename T, int SIZE>
00195 SgArray<T,SIZE>::NonConstIterator::operator bool() const
00196 {
00197     return m_current < m_end;
00198 }
00199 
00200 template<typename T, int SIZE>
00201 SgArray<T,SIZE>::SgArray()
00202 {
00203 }
00204 
00205 template<typename T, int SIZE>
00206 SgArray<T,SIZE>::SgArray(const SgArray& array)
00207 {
00208     SG_ASSERT(&array != this); // self-assignment not supported for efficiency
00209     *this = array;
00210 }
00211 
00212 template<typename T, int SIZE>
00213 SgArray<T,SIZE>::SgArray(const T& val)
00214 {
00215     Fill(val);
00216 }
00217 
00218 template<typename T, int SIZE>
00219 SgArray<T,SIZE>& SgArray<T,SIZE>::operator=(const SgArray& array)
00220 {
00221     SG_ASSERT(&array != this); // self-assignment not supported for efficiency
00222     SgArrayAssign<T,SIZE>::Assign(m_array, array.m_array);
00223     return *this;
00224 }
00225 
00226 template<typename T, int SIZE>
00227 T& SgArray<T,SIZE>::operator[](int index)
00228 {
00229     SG_ASSERT(index >= 0);
00230     SG_ASSERT(index < SIZE);
00231     return m_array[index];
00232 }
00233 
00234 template<typename T, int SIZE>
00235 const T& SgArray<T,SIZE>::operator[](int index) const
00236 {
00237     SG_ASSERT(index >= 0);
00238     SG_ASSERT(index < SIZE);
00239     return m_array[index];
00240 }
00241 
00242 template<typename T, int SIZE>
00243 SgArray<T,SIZE>& SgArray<T,SIZE>::operator*=(T val)
00244 {
00245     T* p = m_array;
00246     for (int i = SIZE; i--; ++p)
00247         *p *= val;
00248     return *this;
00249 }
00250 
00251 template<typename T, int SIZE>
00252 void SgArray<T,SIZE>::Fill(const T& val)
00253 {
00254     T* v = m_array;
00255     for (int i = SIZE; i--; ++v)
00256         *v = val;
00257 }
00258 
00259 //----------------------------------------------------------------------------
00260 
00261 #endif // SG_ARRAY_H


17 Jun 2010 Doxygen 1.4.7