00001
00002
00003
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
00017
00018
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);
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);
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);
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);
00076 std::memcpy(dest, src, SIZE * sizeof(T*));
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086 template<typename T, int SIZE>
00087 class SgArray
00088 {
00089 public:
00090
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
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);
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);
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