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