ps_allocator.h
Go to the documentation of this file.00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef NL_PS_ALLOCATOR_H
00024 #define NL_PS_ALLOCATOR_H
00025
00026 #include "nel/misc/time_nl.h"
00027 #include "nel/misc/contiguous_block_allocator.h"
00028
00029 #include <map>
00030
00031 namespace NL3D
00032 {
00033
00034 #ifdef NL_OS_WINDOWS
00035 # if (__SGI_STL_PORT > 0x449) && (__SGI_STL_PORT < 0x460) || !defined(NL_DONT_USE_EXTERNAL_CODE)
00036
00037
00038
00039
00040
00041 # endif
00042 #endif // NL_OS_WINDOWS
00043
00044
00045 #ifndef PS_FAST_ALLOC
00046
00047
00048
00049
00050 # define PS_FAST_OBJ_ALLOC
00051
00052
00053 template <class T> struct CPSVector
00054 {
00055 typedef std::vector<T, std::allocator<T> > V;
00056 };
00057
00058 template <class T, class U, class Pr = std::less<T> > struct CPSMultiMap
00059 {
00060 #ifdef NL_OS_MAC
00061 typedef std::multimap<T, U, Pr > M;
00062 #else
00063 typedef std::multimap<T, U, Pr, std::allocator<T> > M;
00064 #endif
00065 };
00066
00067 #else
00068
00069
00070 extern NLMISC::CContiguousBlockAllocator *PSBlockAllocator;
00071
00072
00073
00074
00075 #if(__SGI_STL_PORT > 0x449) && (__SGI_STL_PORT < 0x460)
00076 template<class T> class CPSAllocator
00077 {
00078 public:
00079 typedef size_t size_type;
00080 typedef ptrdiff_t difference_type;
00081 typedef T *pointer;
00082 typedef const T *const_pointer;
00083 typedef T& reference;
00084 typedef const T& const_reference;
00085 typedef T value_type;
00086 pointer address(reference x) const { return &x; }
00087 const_pointer address(const_reference x) const { return &x; }
00088 CPSAllocator() {}
00089 CPSAllocator<T>& operator=(const CPSAllocator<T> &other) { return *this; }
00090 private:
00091 typedef NLMISC::CContiguousBlockAllocator *TBlocAllocPtr;
00092 public:
00093 pointer allocate(size_type n, const void *hint)
00094 {
00095 ++NumPSAlloc;
00096 TBlocAllocPtr *result;
00097
00098 if (PSBlockAllocator)
00099 {
00100 result = (TBlocAllocPtr *) PSBlockAllocator->alloc(n * sizeof(T) + sizeof(TBlocAllocPtr *));
00101 *result = PSBlockAllocator;
00102 }
00103 else
00104 {
00105 result = (TBlocAllocPtr *) _Alloc.allocate(n * sizeof(T) + sizeof(TBlocAllocPtr *));
00106 *result = NULL;
00107 }
00108 return (pointer) (result + 1);
00109 }
00110 void deallocate(pointer p, size_type n)
00111 {
00112 ++NumDealloc;
00113 --NumPSAlloc;
00114 if (!p) return;
00115 pointer realAddress = (pointer) ((uint8 *) p - sizeof(TBlocAllocPtr *));
00116 if (* (TBlocAllocPtr *) realAddress)
00117 {
00118
00119 (*(TBlocAllocPtr *) realAddress)->free((void *) realAddress, n * sizeof(T) + sizeof(TBlocAllocPtr *));
00120 }
00121 else
00122 {
00123
00124 _Alloc.deallocate((uint8 *) realAddress, n * sizeof(T) + sizeof(TBlocAllocPtr *));
00125 }
00126 }
00127 void construct(pointer p, const T& val) { new (p) T(val); }
00128 void destroy(pointer p) { p->~T(); }
00129
00130 template <class _Tp, class U>
00131 CPSAllocator<U>& __stl_alloc_rebind(CPSAllocator<_Tp>& __a, const U*)
00132 {
00133 return (CPSAllocator<U>&)(__a);
00134 }
00135
00136 template <class _Tp, class U>
00137 CPSAllocator<U> __stl_alloc_create(const CPSAllocator<_Tp>&, const U*)
00138 {
00139 return CPSAllocator<U>();
00140 }
00141
00142 private:
00143 std::allocator<uint8> _Alloc;
00144 };
00145
00146
00147 #elif(__SGI_STL_PORT > 0x459)
00148
00149 template<class T> class CPSAllocator
00150 {
00151 public:
00152
00153 typedef T value_type;
00154 typedef value_type *pointer;
00155 typedef const T *const_pointer;
00156 typedef T& reference;
00157 typedef const T& const_reference;
00158 typedef size_t size_type;
00159 typedef ptrdiff_t difference_type;
00160
00161 #ifdef _STLP_MEMBER_TEMPLATE_CLASSES
00162 template <class U> struct rebind {
00163 typedef CPSAllocator<U> other;
00164 };
00165 #endif
00166
00167 CPSAllocator() _STLP_NOTHROW {}
00168
00169 #ifdef _STLP_MEMBER_TEMPLATES
00170 template <class U> CPSAllocator(const CPSAllocator<U>&) _STLP_NOTHROW {}
00171 #endif
00172
00173 CPSAllocator(const CPSAllocator<T>&) _STLP_NOTHROW {}
00174
00175 CPSAllocator<T>& operator=(const CPSAllocator<T> &other) { return *this; }
00176 ~CPSAllocator() _STLP_NOTHROW {}
00177
00178 pointer address(reference x) const { return &x; }
00179 const_pointer address(const_reference x) const { return &x; }
00180
00181 private:
00182
00183 typedef NLMISC::CContiguousBlockAllocator *TBlocAllocPtr;
00184
00185 public:
00186
00187 pointer allocate(size_type n, const void* = 0)
00188 {
00189 ++NumPSAlloc;
00190 TBlocAllocPtr *result;
00191
00192 if (PSBlockAllocator)
00193 {
00194 result = (TBlocAllocPtr *) PSBlockAllocator->alloc(n * sizeof(T) + sizeof(TBlocAllocPtr *));
00195 *result = PSBlockAllocator;
00196 }
00197 else
00198 {
00199 result = (TBlocAllocPtr *) _Alloc.allocate(n * sizeof(T) + sizeof(TBlocAllocPtr *));
00200 *result = NULL;
00201 }
00202 return (pointer) (result + 1);
00203 }
00204
00205 void deallocate(pointer p, size_type n)
00206 {
00207 ++NumDealloc;
00208 --NumPSAlloc;
00209 if (!p) return;
00210 pointer realAddress = (pointer) ((uint8 *) p - sizeof(TBlocAllocPtr *));
00211 if (* (TBlocAllocPtr *) realAddress)
00212 {
00213
00214 (*(TBlocAllocPtr *) realAddress)->free((void *) realAddress, n * sizeof(T) + sizeof(TBlocAllocPtr *));
00215 }
00216 else
00217 {
00218
00219 _Alloc.deallocate((uint8 *) realAddress, n * sizeof(T) + sizeof(TBlocAllocPtr *));
00220 }
00221 }
00222
00223 void construct(pointer p, const T& val) { new (p) T(val); }
00224 void destroy(pointer p) { p->~T(); }
00225
00226 size_type max_size() const _STLP_NOTHROW { return size_t(-1) / sizeof(value_type); }
00227
00228
00229 template <class _Tp, class U> CPSAllocator<U>& __stl_alloc_rebind(CPSAllocator<_Tp>& __a, const U*)
00230 {
00231 return (CPSAllocator<U>&)(__a);
00232 }
00233
00234
00235 template <class _Tp, class U> CPSAllocator<U> __stl_alloc_create(const CPSAllocator<_Tp>&, const U*)
00236 {
00237 return CPSAllocator<U>();
00238 }
00239
00240 private:
00241 std::allocator<uint8> _Alloc;
00242 };
00243
00244 #endif
00245
00246
00247 # define PS_FAST_OBJ_ALLOC \
00248 void *operator new(size_t size) { return PSFastMemAlloc((uint) size); }\
00249 void operator delete(void *block) { PSFastMemFree(block); }
00250
00251
00252
00253
00254 template <class T> struct CPSVector
00255 {
00256 typedef std::vector<T, CPSAllocator<T> > V;
00257 };
00258
00259 template <class T, class U, class Pr = std::less<T> > struct CPSMultiMap
00260 {
00261 typedef std::multimap<T, U, Pr, CPSAllocator<T> > M;
00262 };
00263
00264 extern uint NumPSAlloc;
00265 extern uint NumDealloc;
00266
00267
00268 void *PSFastMemAlloc(uint numBytes);
00269 void PSFastMemFree(void *block);
00270
00271 #endif // PS_FAST_ALLOC
00272
00273 }
00274
00275 #endif // NL_PS_ALLOCATOR_H