00001 //---------------------------------------------------------------------------- 00002 /** @file SgArray.h 00003 Static array. */ 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 /** Helper class to allow partial specialization of SgArray::operator=. 00016 Partial member function specialization is not yet supported by standard 00017 C++. */ 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); // self-assignment not supported for efficiency 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); // self-assignment not supported for efficiency 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); // self-assignment not supported for efficiency 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); // self-assignment not supported for efficiency 00074 std::memcpy(dest, src, SIZE * sizeof(T*)); 00075 } 00076 00077 //---------------------------------------------------------------------------- 00078 00079 /** Static array. 00080 Wrapper class around a C style array. 00081 Uses assertions for indices in range in debug mode. 00082 @deprecated Use boost::array instead */ 00083 template<typename T, int SIZE> 00084 class SgArray 00085 { 00086 public: 00087 /** Local const iterator */ 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 /** Local non-const iterator */ 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); // self-assignment not supported for efficiency 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); // self-assignment not supported for efficiency 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