Blender V2.61 - r43446
|
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