share/Allocator.cxx

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     void* memory_block = malloc(sizeof(int) + num * sizeof(T));
00117     memcpy(memory_block, &num, sizeof(int));
00118     char* data = static_cast<char*>(memory_block) + sizeof(int);
00119     return static_cast<pointer>(new(data) T[num]);
00120   }
00121 
00122 
00123   template <class T>
00124   inline void MallocObject<T>::deallocate(pointer data, int num, void* h)
00125   {
00126     char* memory_block = reinterpret_cast<char*>(data) - sizeof(int);
00127     for (int i = 0; i < num; i++)
00128       data[i].~T();
00129     free(memory_block);
00130   }
00131 
00132 
00133   template <class T>
00134   inline void* MallocObject<T>::reallocate(pointer data, int num, void* h)
00135   {
00136     if (data == NULL)
00137       return allocate(num, h);
00138 
00139     void* memory_block = static_cast<void*>(reinterpret_cast<char*>(data)
00140                                             - sizeof(int));
00141     int initial_num = *reinterpret_cast<int*>(memory_block);
00142     if (initial_num < num)
00143       {
00144         memory_block = realloc(memory_block,
00145                                sizeof(int) + num * sizeof(T));
00146         new(static_cast<char*>(memory_block) + sizeof(int) +
00147             initial_num * sizeof(T)) T[num - initial_num];
00148       }
00149     else if (initial_num > num)
00150       {
00151         for (int i = num; i < initial_num; i++)
00152           data[i].~T();
00153         memory_block = realloc(memory_block,
00154                                sizeof(int) + num * sizeof(T));
00155       }
00156     else
00157       return data;
00158 
00159     memcpy(memory_block, &num, sizeof(int));
00160     return reinterpret_cast<pointer>(static_cast<char*>(memory_block) +
00161                                      sizeof(int));
00162   }
00163 
00164 
00165   template <class T>
00166   inline void MallocObject<T>::memoryset(pointer data, char c, size_t num)
00167   {
00168     memset(reinterpret_cast<void*>(data), c, num);
00169   }
00170 
00171 
00172   template <class T>
00173   inline void
00174   MallocObject<T>::memorycpy(pointer datat, pointer datas, size_t num)
00175   {
00176     for (size_t i = 0; i < num; i++)
00177       datat[i] = datas[i];
00178   }
00179 
00180 
00182   // NEWALLOC //
00184 
00185 
00186   template <class T>
00187   inline typename NewAlloc<T>::pointer
00188   NewAlloc<T>::allocate(int num, void* h)
00189   {
00190     return static_cast<pointer>(new T[num]);
00191   }
00192 
00193   template <class T>
00194   inline void NewAlloc<T>::deallocate(pointer data, int num, void* h)
00195   {
00196     delete [] data;
00197   }
00198 
00199   template <class T>
00200   inline void* NewAlloc<T>::reallocate(pointer data, int num, void* h)
00201   {
00202     if (data != NULL)
00203       delete [] data;
00204     return (new T[num]);
00205   }
00206 
00207   template <class T>
00208   inline void NewAlloc<T>::memoryset(pointer data, char c, size_t num)
00209   {
00210     memset(reinterpret_cast<void*>(data), c, num);
00211   }
00212 
00213   template <class T>
00214   inline void
00215   NewAlloc<T>::memorycpy(pointer datat, pointer datas, size_t num)
00216   {
00217     for (size_t i = 0; i < num; i++)
00218       datat[i] = datas[i];
00219   }
00220 
00221 
00223   // NANALLOC //
00225 
00226 
00227   template <class T>
00228   inline typename NaNAlloc<T>::pointer
00229   NaNAlloc<T>::allocate(int num, void* h)
00230   {
00231     pointer data = static_cast<pointer>( malloc(num * sizeof(T)) );
00232     if (numeric_limits<value_type>::has_signaling_NaN)
00233       for (int i = 0; i < num; i++)
00234         data[i] = numeric_limits<value_type>::signaling_NaN();
00235     else if (numeric_limits<value_type>::has_quiet_NaN)
00236       for (int i = 0; i < num; i++)
00237         data[i] = numeric_limits<value_type>::quiet_NaN();
00238     else if  (numeric_limits<value_type>::has_infinity)
00239       for (int i = 0; i < num; i++)
00240         data[i] = numeric_limits<value_type>::infinity();
00241     return data;
00242   }
00243 
00244   template <class T>
00245   inline void NaNAlloc<T>::deallocate(pointer data, int num, void* h)
00246   {
00247     free(data);
00248   }
00249 
00250   template <class T>
00251   inline void* NaNAlloc<T>::reallocate(pointer data, int num, void* h)
00252   {
00253     void* datav = realloc(reinterpret_cast<void*>(data), num * sizeof(T));
00254     pointer datap = reinterpret_cast<pointer>(datav);
00255     if (numeric_limits<value_type>::has_signaling_NaN)
00256       for (int i = 0; i < num; i++)
00257         datap[i] = numeric_limits<value_type>::signaling_NaN();
00258     else if (numeric_limits<value_type>::has_quiet_NaN)
00259       for (int i = 0; i < num; i++)
00260         datap[i] = numeric_limits<value_type>::quiet_NaN();
00261     else if  (numeric_limits<value_type>::has_infinity)
00262       for (int i = 0; i < num; i++)
00263         datap[i] = numeric_limits<value_type>::infinity();
00264     return datav;
00265   }
00266 
00267   template <class T>
00268   inline void NaNAlloc<T>::memoryset(pointer data, char c, size_t num)
00269   {
00270     memset(reinterpret_cast<void*>(data), c, num);
00271   }
00272 
00273   template <class T>
00274   inline void
00275   NaNAlloc<T>::memorycpy(pointer datat, pointer datas, size_t num)
00276   {
00277     memcpy(reinterpret_cast<void*>(datat), reinterpret_cast<void*>(datas),
00278            num * sizeof(T));
00279   }
00280 
00281 
00282 } // namespace Seldon.
00283 
00284 #define SELDON_FILE_ALLOCATOR_CXX
00285 #endif