Go to the documentation of this file.00001 #ifndef GIM_ARRAY_H_INCLUDED
00002 #define GIM_ARRAY_H_INCLUDED
00003
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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