Warning: this documentation for the development version is under construction.
00001 // Copyright (C) 2001-2010 Vivien Mallet, INRIA 00002 // Author(s): Vivien Mallet, Marc Fragu 00003 // 00004 // This file is part of the linear-algebra library Seldon, 00005 // http://seldon.sourceforge.net/. 00006 // 00007 // Seldon is free software; you can redistribute it and/or modify it under the 00008 // terms of the GNU Lesser General Public License as published by the Free 00009 // Software Foundation; either version 2.1 of the License, or (at your option) 00010 // any later version. 00011 // 00012 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY 00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00014 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 00015 // more details. 00016 // 00017 // You should have received a copy of the GNU Lesser General Public License 00018 // along with Seldon. If not, see http://www.gnu.org/licenses/. 00019 00020 00021 #ifndef SELDON_FILE_ALLOCATOR_CXX 00022 00023 #include "Allocator.hxx" 00024 00025 namespace Seldon 00026 { 00027 00028 00030 // MALLOCALLOC // 00032 00033 00034 template <class T> 00035 inline typename MallocAlloc<T>::pointer 00036 MallocAlloc<T>::allocate(int num, void* h) 00037 { 00038 return static_cast<pointer>( malloc(num * sizeof(T)) ); 00039 } 00040 00041 template <class T> 00042 inline void MallocAlloc<T>::deallocate(pointer data, int num, void* h) 00043 { 00044 free(data); 00045 } 00046 00047 template <class T> 00048 inline void* MallocAlloc<T>::reallocate(pointer data, int num, void* h) 00049 { 00050 return realloc(reinterpret_cast<void*>(data), num * sizeof(T)); 00051 } 00052 00053 template <class T> 00054 inline void MallocAlloc<T>::memoryset(pointer data, char c, size_t num) 00055 { 00056 memset(reinterpret_cast<void*>(data), c, num); 00057 } 00058 00059 template <class T> 00060 inline void 00061 MallocAlloc<T>::memorycpy(pointer datat, pointer datas, size_t num) 00062 { 00063 memcpy(reinterpret_cast<void*>(datat), reinterpret_cast<void*>(datas), 00064 num * sizeof(T)); 00065 } 00066 00067 00069 // CALLOCALLOC // 00071 00072 00073 template <class T> 00074 inline typename CallocAlloc<T>::pointer 00075 CallocAlloc<T>::allocate(int num, void* h) 00076 { 00077 return static_cast<pointer>( calloc(num, sizeof(T)) ); 00078 } 00079 00080 template <class T> 00081 inline void CallocAlloc<T>::deallocate(pointer data, int num, void* h) 00082 { 00083 free(data); 00084 } 00085 00086 template <class T> 00087 inline void* CallocAlloc<T>::reallocate(pointer data, int num, void* h) 00088 { 00089 return realloc(reinterpret_cast<void*>(data), num * sizeof(T)); 00090 } 00091 00092 template <class T> 00093 inline void CallocAlloc<T>::memoryset(pointer data, char c, size_t num) 00094 { 00095 memset(reinterpret_cast<void*>(data), c, num); 00096 } 00097 00098 template <class T> 00099 inline void 00100 CallocAlloc<T>::memorycpy(pointer datat, pointer datas, size_t num) 00101 { 00102 memcpy(reinterpret_cast<void*>(datat), reinterpret_cast<void*>(datas), 00103 num * sizeof(T)); 00104 } 00105 00106 00108 // MALLOCOBJECT // 00110 00111 00112 template <class T> 00113 inline typename MallocObject<T>::pointer 00114 MallocObject<T>::allocate(int num, void* h) 00115 { 00116 // The cast from char* to T* may lead to a memory shift (because of 00117 // alignment issues) under MS Windows. It requires that one allocates more 00118 // memory than necessary for memory_block. 00119 00120 void* memory_block = malloc(sizeof(int) + sizeof(char*) + 00121 (num + 2) * sizeof(T)); 00122 memcpy(memory_block, &num, sizeof(int)); 00123 char* data = static_cast<char*>(memory_block) 00124 + sizeof(int) + sizeof(char*) + sizeof(T); 00125 00126 // The memory shift can occur here. 00127 pointer data_P = reinterpret_cast<pointer>(new(data) T[num]); 00128 00129 memcpy(reinterpret_cast<char *>(data_P) - sizeof(char*), 00130 &memory_block, sizeof(char*)); 00131 00132 return data_P; 00133 } 00134 00135 00136 template <class T> 00137 inline void MallocObject<T>::deallocate(pointer data, int num, void* h) 00138 { 00139 void * memory_block; 00140 memcpy(&memory_block, 00141 reinterpret_cast<char *>(data) - sizeof(char*), sizeof(char*)); 00142 for (int i = 0; i < num; i++) 00143 data[i].~T(); 00144 free(memory_block); 00145 } 00146 00147 00148 template <class T> 00149 inline void* MallocObject<T>::reallocate(pointer data, int num, void* h) 00150 { 00151 if (data == NULL) 00152 return allocate(num, h); 00153 00154 void * memory_block; 00155 memcpy(&memory_block, 00156 reinterpret_cast<char *>(data) - sizeof(char*), sizeof(char*)); 00157 int initial_num = *reinterpret_cast<int*>(memory_block); 00158 00159 if (initial_num < num) 00160 { 00161 memory_block = realloc(memory_block, sizeof(int) + sizeof(char*) + 00162 (num + 2) * sizeof(T)); 00163 00164 new(static_cast<char *>(memory_block) + sizeof(int) + sizeof(T) + 00165 sizeof(char*) + initial_num * sizeof(T)) T[num - initial_num]; 00166 } 00167 else if (initial_num > num) 00168 { 00169 for (int i = num; i < initial_num; i++) 00170 data[i].~T(); 00171 00172 memory_block = realloc(memory_block, sizeof(int) + sizeof(char*) + 00173 (num + 2) * sizeof(T)); 00174 00175 } 00176 else 00177 return data; 00178 00179 memcpy(memory_block, &num, sizeof(int)); 00180 00181 pointer data_P = 00182 reinterpret_cast<pointer>(static_cast<char*>(memory_block) + 00183 sizeof(int) + sizeof(char*) + sizeof(T)); 00184 memcpy(reinterpret_cast<char *>(data_P) - sizeof(char*), 00185 &memory_block, sizeof(char*)); 00186 00187 return data_P; 00188 } 00189 00190 00191 template <class T> 00192 inline void MallocObject<T>::memoryset(pointer data, char c, size_t num) 00193 { 00194 memset(reinterpret_cast<void*>(data), c, num); 00195 } 00196 00197 00198 template <class T> 00199 inline void 00200 MallocObject<T>::memorycpy(pointer datat, pointer datas, size_t num) 00201 { 00202 for (size_t i = 0; i < num; i++) 00203 datat[i] = datas[i]; 00204 } 00205 00206 00208 // NEWALLOC // 00210 00211 00212 template <class T> 00213 inline typename NewAlloc<T>::pointer 00214 NewAlloc<T>::allocate(int num, void* h) 00215 { 00216 return static_cast<pointer>(new T[num]); 00217 } 00218 00219 template <class T> 00220 inline void NewAlloc<T>::deallocate(pointer data, int num, void* h) 00221 { 00222 delete [] data; 00223 } 00224 00225 template <class T> 00226 inline void* NewAlloc<T>::reallocate(pointer data, int num, void* h) 00227 { 00228 if (data != NULL) 00229 delete [] data; 00230 return (new T[num]); 00231 } 00232 00233 template <class T> 00234 inline void NewAlloc<T>::memoryset(pointer data, char c, size_t num) 00235 { 00236 memset(reinterpret_cast<void*>(data), c, num); 00237 } 00238 00239 template <class T> 00240 inline void 00241 NewAlloc<T>::memorycpy(pointer datat, pointer datas, size_t num) 00242 { 00243 for (size_t i = 0; i < num; i++) 00244 datat[i] = datas[i]; 00245 } 00246 00247 00249 // NANALLOC // 00251 00252 00253 template <class T> 00254 inline typename NaNAlloc<T>::pointer 00255 NaNAlloc<T>::allocate(int num, void* h) 00256 { 00257 pointer data = static_cast<pointer>( malloc(num * sizeof(T)) ); 00258 if (numeric_limits<value_type>::has_signaling_NaN) 00259 for (int i = 0; i < num; i++) 00260 data[i] = numeric_limits<value_type>::signaling_NaN(); 00261 else if (numeric_limits<value_type>::has_quiet_NaN) 00262 for (int i = 0; i < num; i++) 00263 data[i] = numeric_limits<value_type>::quiet_NaN(); 00264 else if (numeric_limits<value_type>::has_infinity) 00265 for (int i = 0; i < num; i++) 00266 data[i] = numeric_limits<value_type>::infinity(); 00267 return data; 00268 } 00269 00270 template <class T> 00271 inline void NaNAlloc<T>::deallocate(pointer data, int num, void* h) 00272 { 00273 free(data); 00274 } 00275 00276 template <class T> 00277 inline void* NaNAlloc<T>::reallocate(pointer data, int num, void* h) 00278 { 00279 void* datav = realloc(reinterpret_cast<void*>(data), num * sizeof(T)); 00280 pointer datap = reinterpret_cast<pointer>(datav); 00281 if (numeric_limits<value_type>::has_signaling_NaN) 00282 for (int i = 0; i < num; i++) 00283 datap[i] = numeric_limits<value_type>::signaling_NaN(); 00284 else if (numeric_limits<value_type>::has_quiet_NaN) 00285 for (int i = 0; i < num; i++) 00286 datap[i] = numeric_limits<value_type>::quiet_NaN(); 00287 else if (numeric_limits<value_type>::has_infinity) 00288 for (int i = 0; i < num; i++) 00289 datap[i] = numeric_limits<value_type>::infinity(); 00290 return datav; 00291 } 00292 00293 template <class T> 00294 inline void NaNAlloc<T>::memoryset(pointer data, char c, size_t num) 00295 { 00296 memset(reinterpret_cast<void*>(data), c, num); 00297 } 00298 00299 template <class T> 00300 inline void 00301 NaNAlloc<T>::memorycpy(pointer datat, pointer datas, size_t num) 00302 { 00303 memcpy(reinterpret_cast<void*>(datat), reinterpret_cast<void*>(datas), 00304 num * sizeof(T)); 00305 } 00306 00307 00308 } // namespace Seldon. 00309 00310 #define SELDON_FILE_ALLOCATOR_CXX 00311 #endif