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 #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


Sun Mar 13 2011 Doxygen 1.7.1