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