Blender V2.61 - r43446

gim_array.h

Go to the documentation of this file.
00001 #ifndef GIM_ARRAY_H_INCLUDED
00002 #define GIM_ARRAY_H_INCLUDED
00003 
00006 /*
00007 -----------------------------------------------------------------------------
00008 This source file is part of GIMPACT Library.
00009 
00010 For the latest info, see http://gimpact.sourceforge.net/
00011 
00012 Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
00013 email: projectileman@yahoo.com
00014 
00015  This library is free software; you can redistribute it and/or
00016  modify it under the terms of EITHER:
00017    (1) The GNU Lesser General Public License as published by the Free
00018        Software Foundation; either version 2.1 of the License, or (at
00019        your option) any later version. The text of the GNU Lesser
00020        General Public License is included with this library in the
00021        file GIMPACT-LICENSE-LGPL.TXT.
00022    (2) The BSD-style license that is included with this library in
00023        the file GIMPACT-LICENSE-BSD.TXT.
00024    (3) The zlib/libpng license that is included with this library in
00025        the file GIMPACT-LICENSE-ZLIB.TXT.
00026 
00027  This library is distributed in the hope that it will be useful,
00028  but WITHOUT ANY WARRANTY; without even the implied warranty of
00029  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
00030  GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
00031 
00032 -----------------------------------------------------------------------------
00033 */
00034 
00035 #include "gim_memory.h"
00036 
00037 
00038 #define GIM_ARRAY_GROW_INCREMENT 2
00039 #define GIM_ARRAY_GROW_FACTOR 2
00040 
00042 template<typename T>
00043 class gim_array
00044 {
00045 public:
00048     T *m_data;
00049     GUINT m_size;
00050     GUINT m_allocated_size;
00054 
00055     inline void destroyData()
00056     {
00057         m_allocated_size = 0;
00058         if(m_data==NULL) return;
00059         gim_free(m_data);
00060         m_data = NULL;
00061     }
00062 
00063     inline bool resizeData(GUINT newsize)
00064     {
00065         if(newsize==0)
00066         {
00067             destroyData();
00068             return true;
00069         }
00070 
00071         if(m_size>0)
00072         {
00073             m_data = (T*)gim_realloc(m_data,m_size*sizeof(T),newsize*sizeof(T));
00074         }
00075         else
00076         {
00077             m_data = (T*)gim_alloc(newsize*sizeof(T));
00078         }
00079         m_allocated_size = newsize;
00080         return true;
00081     }
00082 
00083     inline bool growingCheck()
00084     {
00085         if(m_allocated_size<=m_size)
00086         {
00087             GUINT requestsize = m_size;
00088             m_size = m_allocated_size;
00089             if(resizeData((requestsize+GIM_ARRAY_GROW_INCREMENT)*GIM_ARRAY_GROW_FACTOR)==false) return false;
00090         }
00091         return true;
00092     }
00093 
00097     inline  bool reserve(GUINT size)
00098     {
00099         if(m_allocated_size>=size) return false;
00100         return resizeData(size);
00101     }
00102 
00103     inline void clear_range(GUINT start_range)
00104     {
00105         while(m_size>start_range)
00106         {
00107             m_data[--m_size].~T();
00108         }
00109     }
00110 
00111     inline void clear()
00112     {
00113         if(m_size==0)return;
00114         clear_range(0);
00115     }
00116 
00117     inline void clear_memory()
00118     {
00119         clear();
00120         destroyData();
00121     }
00122 
00123     gim_array()
00124     {
00125         m_data = 0;
00126         m_size = 0;
00127         m_allocated_size = 0;
00128     }
00129 
00130     gim_array(GUINT reservesize)
00131     {
00132         m_data = 0;
00133         m_size = 0;
00134 
00135         m_allocated_size = 0;
00136         reserve(reservesize);
00137     }
00138 
00139     ~gim_array()
00140     {
00141         clear_memory();
00142     }
00143 
00144     inline GUINT size() const
00145     {
00146         return m_size;
00147     }
00148 
00149     inline GUINT max_size() const
00150     {
00151         return m_allocated_size;
00152     }
00153 
00154     inline T & operator[](size_t i)
00155     {
00156         return m_data[i];
00157     }
00158     inline  const T & operator[](size_t i) const
00159     {
00160         return m_data[i];
00161     }
00162 
00163     inline T * pointer(){ return m_data;}
00164     inline const T * pointer() const
00165     { return m_data;}
00166 
00167 
00168     inline T * get_pointer_at(GUINT i)
00169     {
00170         return m_data + i;
00171     }
00172 
00173     inline const T * get_pointer_at(GUINT i) const
00174     {
00175         return m_data + i;
00176     }
00177 
00178     inline T & at(GUINT i)
00179     {
00180         return m_data[i];
00181     }
00182 
00183     inline const T & at(GUINT i) const
00184     {
00185         return m_data[i];
00186     }
00187 
00188     inline T & front()
00189     {
00190         return *m_data;
00191     }
00192 
00193     inline const T & front() const
00194     {
00195         return *m_data;
00196     }
00197 
00198     inline T & back()
00199     {
00200         return m_data[m_size-1];
00201     }
00202 
00203     inline const T & back() const
00204     {
00205         return m_data[m_size-1];
00206     }
00207 
00208 
00209     inline void swap(GUINT i, GUINT j)
00210     {
00211         gim_swap_elements(m_data,i,j);
00212     }
00213 
00214     inline void push_back(const T & obj)
00215     {
00216         this->growingCheck();
00217         m_data[m_size] = obj;
00218         m_size++;
00219     }
00220 
00222     inline void push_back_mem()
00223     {
00224         this->growingCheck();
00225         m_size++;
00226     }
00227 
00228     inline void push_back_memcpy(const T & obj)
00229     {
00230         this->growingCheck();
00231         irr_simd_memcpy(&m_data[m_size],&obj,sizeof(T));
00232         m_size++;
00233     }
00234 
00235     inline void pop_back()
00236     {
00237         m_size--;
00238         m_data[m_size].~T();
00239     }
00240 
00242     inline void pop_back_mem()
00243     {
00244         m_size--;
00245     }
00246 
00248     inline void erase(GUINT index)
00249     {
00250         if(index<m_size-1)
00251         {
00252             swap(index,m_size-1);
00253         }
00254         pop_back();
00255     }
00256 
00257     inline void erase_sorted_mem(GUINT index)
00258     {
00259         m_size--;
00260         for(GUINT i = index;i<m_size;i++)
00261         {
00262             gim_simd_memcpy(m_data+i,m_data+i+1,sizeof(T));
00263         }
00264     }
00265 
00266     inline void erase_sorted(GUINT index)
00267     {
00268         m_data[index].~T();
00269         erase_sorted_mem(index);
00270     }
00271 
00272     inline void insert_mem(GUINT index)
00273     {
00274         this->growingCheck();
00275         for(GUINT i = m_size;i>index;i--)
00276         {
00277             gim_simd_memcpy(m_data+i,m_data+i-1,sizeof(T));
00278         }
00279         m_size++;
00280     }
00281 
00282     inline void insert(const T & obj,GUINT index)
00283     {
00284         insert_mem(index);
00285         m_data[index] = obj;
00286     }
00287 
00288     inline void resize(GUINT size, bool call_constructor = true)
00289     {
00290 
00291         if(size>m_size)
00292         {
00293             reserve(size);
00294             if(call_constructor)
00295             {
00296                 T obj;
00297                 while(m_size<size)
00298                 {
00299                     m_data[m_size] = obj;
00300                     m_size++;
00301                 }
00302             }
00303             else
00304             {
00305                 m_size = size;
00306             }
00307         }
00308         else if(size<m_size)
00309         {
00310             if(call_constructor) clear_range(size);
00311             m_size = size;
00312         }
00313     }
00314 
00315     inline void refit()
00316     {
00317         resizeData(m_size);
00318     }
00319 
00320 };
00321 
00322 
00323 
00324 
00325 
00326 #endif // GIM_CONTAINERS_H_INCLUDED