vectorsp.h

Go to the documentation of this file.
00001 /* Vector SP.
00002  *
00003  * Containers collection (c) 2005 PegSoft
00004  * Contact us at pegsoft@pegsoft.net
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program (see the file COPYING); if not, write to the
00018  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00024 #ifndef CONTAINERS_VECTORSP_H
00025 #define CONTAINERS_VECTORSP_H
00026 
00027 /*************************************************************************/
00028 
00029 #include <iterator>
00030 
00031 /*************************************************************************/
00032 
00033 namespace containers
00034 {
00035 
00036 /*************************************************************************/
00037 
00039 
00048 template <class T, class SizeT>
00049 class VectorSP
00050 {
00051     public:
00053         typedef T value_type;
00055         typedef T & reference;
00057         typedef T const & const_reference;
00059         typedef T * pointer;
00061         typedef T const * const_pointer;
00063         typedef SizeT size_type;
00065         typedef ptrdiff_t difference_type;
00066     
00068         typedef pointer iterator;
00070         typedef const_pointer const_iterator;
00072         typedef std::reverse_iterator<iterator> reverse_iterator;
00074         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00075         
00077         VectorSP() : m_array(0), m_size(0), m_capacity(0) { }
00079         VectorSP(VectorSP const &v);
00081         VectorSP &operator=(VectorSP const &right);
00083         ~VectorSP();
00084         
00086 
00090         void clear(bool free = false);
00091         
00093 
00098         void erase(iterator it, bool free = false);
00099         
00101 
00107         void erase(iterator first, iterator last, bool free = false);
00108         
00110 
00117         iterator insert(iterator pos, value_type const &val);
00118         
00120         void pop_back(bool free = false) { erase(end() - 1, free); }
00122         void push_back(value_type const &val) { insert(end(), val); }
00123         
00125 
00132         void reserve(size_type capacity);
00134 
00146         void resize(size_type size, value_type const &val = NULL,
00147                 bool free = false);
00148         
00150         iterator begin() { return m_array; }
00152         iterator end() { return &m_array[m_size]; }
00154         const_iterator begin() const 
00155                 { return m_array; }
00157         const_iterator end() const 
00158                 { return &m_array[m_size]; }
00159         
00161         reverse_iterator rbegin() { return reverse_iterator(end()); }
00163         reverse_iterator rend() { return reverse_iterator(begin()); }
00165         const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
00167         const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00168         
00170         reference operator[](size_type idx) { return m_array[idx]; }
00172         const_reference operator[](size_type idx) const { return m_array[idx]; }
00173         
00175         reference front() { return m_array[0]; }
00177         const_reference front() const { return m_array[0]; }
00179         reference back() { return m_array[m_size - 1]; }
00181         const_reference back() const { return m_array[m_size - 1]; }
00182         
00184         const_pointer data() const { return m_array; }
00185         
00187         size_type size() const { return m_size; }
00189         bool empty() const { return (m_size == 0); }
00191         size_type capacity() const { return m_capacity; }
00193         size_type max_size() const;
00194     private:
00195         T *m_array;
00196         
00197         size_type m_size;
00198         size_type m_capacity;
00199         
00200         void copy_array(T const *array, size_type size, size_type capacity);
00201         void free_array();
00202 };
00203 
00204 /*************************************************************************/
00205 
00206 template <class T, class SizeT>
00207 VectorSP<T, SizeT>::VectorSP(VectorSP const &v) : m_array(0), m_size(0),
00208         m_capacity(0)
00209 {
00210     copy_array(v.m_array, v.m_size, v.m_size /* Don't use the same capacity. */);
00211 }
00212 
00213 /*************************************************************************/
00214 
00215 template <class T, class SizeT>
00216 VectorSP<T, SizeT> &VectorSP<T, SizeT>::operator=(VectorSP const &right)
00217 {
00218     if (this != &right)
00219     {
00220         free_array();
00221         copy_array(right.m_array, right.m_size, right.m_size);
00222     }
00223     
00224     return *this;
00225 }
00226 
00227 /*************************************************************************/
00228 
00229 template <class T, class SizeT>
00230 VectorSP<T, SizeT>::~VectorSP()
00231 {
00232     free_array();
00233 }
00234 
00235 /*************************************************************************/
00236 
00237 template <class T, class SizeT>
00238 void VectorSP<T, SizeT>::clear(bool free)
00239 {
00240     if (free)
00241     {
00242         iterator it, iend;
00243         
00244         for (it = begin(), iend = end(); it != iend; ++it)
00245             if (*it)
00246                 delete (*it);
00247     }
00248     
00249     free_array();
00250 }
00251 
00252 /*************************************************************************/
00253 
00254 template <class T, class SizeT>
00255 void VectorSP<T, SizeT>::copy_array(T const *array, size_type size,
00256         size_type capacity)
00257 {
00258     if (!capacity)
00259         return; /* Nothing to do. */
00260     
00261     m_capacity = capacity;
00262     m_array = new value_type[m_capacity];
00263     
00264     if (!array || !size)
00265         return;
00266     
00267     m_size = size;
00268     memcpy(m_array, array, (m_size * sizeof(value_type)));
00269 }
00270 
00271 /*************************************************************************/
00272 
00273 template <class T, class SizeT>
00274 void VectorSP<T, SizeT>::erase(iterator it, bool free)
00275 {
00276     /* Sanity check -- I know there shouldn't be any in
00277      * containers, but well -- I'm a bit worried on this one. :P */
00278     if (!m_size)
00279         return;
00280     
00281     if (free && (*it))
00282         delete (*it);
00283     
00284     if (it != (end() - 1))
00285         memmove(it, it + 1, (sizeof(value_type) * (end() - it - 1)));
00286     --m_size;
00287 }
00288 
00289 /*************************************************************************/
00290 
00291 template <class T, class SizeT>
00292 void VectorSP<T, SizeT>::erase(iterator first, iterator last, bool free)
00293 {
00294     /* Sanity check -- I know there shouldn't be any in
00295      * containers, but well -- I'm a bit worried on this one (too). :P */
00296     if ((last - first) > m_size)
00297         return;
00298     
00299     if (free)
00300     {
00301         for (iterator it = first; it != last; ++it)
00302             if (*it)
00303                 delete (*it);
00304     }
00305     
00306     if (last != end())
00307         memmove(first, last, (sizeof(value_type) * (end() - last)));
00308     m_size -= (last - first);
00309 }
00310 
00311 /*************************************************************************/
00312 
00313 template <class T, class SizeT>
00314 void VectorSP<T, SizeT>::free_array()
00315 {
00316     if (m_array)
00317         delete [] m_array;
00318     m_array = 0;
00319     m_capacity = m_size = 0;
00320 }
00321 
00322 /*************************************************************************/
00323 
00324 template <class T, class SizeT>
00325 typename VectorSP<T, SizeT>::iterator VectorSP<T, SizeT>::insert(iterator pos,
00326         value_type const &val)
00327 {
00328     if (m_size == max_size())
00329         return end();
00330     
00331     size_type idx = (m_size - (end() - pos));
00332     
00333     reserve(++m_size);
00334     
00335     iterator newpos = &m_array[idx];
00336     
00337     if (newpos != end())
00338         memmove(newpos + 1, newpos, (sizeof(value_type) * (end() - newpos - 1)));
00339     *newpos = val;
00340     return newpos;
00341 }
00342 
00343 /*************************************************************************/
00344 
00345 template <class T, class SizeT>
00346 typename VectorSP<T, SizeT>::size_type VectorSP<T, SizeT>::max_size() const
00347 {
00348     size_type result = 0;
00349     
00350     if (sizeof(T *) <= sizeof(size_type))
00351     {
00352         for (unsigned int i = 0; i < (sizeof(T *) * 8); ++i)
00353         {
00354             result <<= 1;
00355             result |= 1;
00356         }
00357         
00358         result /= sizeof(T *);
00359     } else {
00360         for (unsigned int i = 0; i < (sizeof(size_type) * 8); ++i)
00361         {
00362             result <<= 1;
00363             result |= 1;
00364         }
00365     }
00366     
00367     return result;
00368 }
00369 
00370 /*************************************************************************/
00371 
00372 template <class T, class SizeT>
00373 void VectorSP<T, SizeT>::reserve(size_type capacity)
00374 {
00375     if (capacity > max_size())
00376         capacity = max_size();
00377     
00378     if (capacity <= m_capacity)
00379         return;
00380     
00381     T *array = m_array;
00382     
00383     copy_array(array, m_size, capacity);
00384     delete [] array;
00385 }
00386 
00387 /*************************************************************************/
00388 
00389 template <class T, class SizeT>
00390 void VectorSP<T, SizeT>::resize(size_type size,
00391         value_type const &val, bool free)
00392 {
00393     if (size > max_size())
00394         size = max_size();
00395     
00396     if (size == m_size)
00397         return; /* No-op */
00398     
00399     if (size < m_size)
00400     {
00401         if (free)
00402         {
00403             for (size_type i = size; i < m_size; ++i)
00404                 if (m_array[i])
00405                     delete m_array[i];
00406         }
00407         
00408         m_size = size;
00409         /* No need to reallocate anything! */
00410     } else {
00411         if (size > m_capacity)
00412             reserve(size);
00413         for (size_type i = m_size; i < size; ++i)
00414             m_array[i] = val;
00415         m_size = size;
00416     }
00417 }
00418 
00419 /*************************************************************************/
00420 
00421 } /* namespace containers */
00422 
00423 /*************************************************************************/
00424 
00425 #endif /* CONTAINERS_VECTORSP_H */

Generated on Fri Apr 18 22:03:27 2008 for Epona API by  doxygen 1.5.3