00001
00002
00003
00004
00005
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
00041 #ifndef BASE_CCMEM_H
00042 #define BASE_CCMEM_H
00043
00044 #include "fastlib/base/common.h"
00045 #include "fastlib/base/debug.h"
00046 #include "fastlib/base/cc.h"
00047
00048 #include <new>
00049
00050 #define MEM__DEBUG_MEMORY(ptr) \
00051 DEBUG_ASSERT_MSG((ptr) != NULL, "out of memory")
00052
00053 namespace mem__private {
00054 const size_t BIG_BAD_BUF_SIZE = 64;
00055
00056 extern const int32 BIG_BAD_BUF[];
00057
00058 void PoisonBytes(char *array_cp, size_t bytes);
00059
00060 const size_t SWAP_BUF_SIZE = 64;
00061
00062 void SwapBytes(char *a_cp, char *b_cp, size_t bytes);
00063 };
00064
00081 namespace mem {
00083 template<typename T>
00084 T *PoisonBytes(T *array, size_t bytes) {
00085 char *array_cp = reinterpret_cast<char *>(array);
00086 mem__private::PoisonBytes(array_cp, bytes);
00087 return array;
00088 }
00090 template<typename T>
00091 inline T *Poison(T *array, size_t elems) {
00092 return PoisonBytes(array, elems * sizeof(T));
00093 }
00095 template<typename T>
00096 inline T *Poison(T *ptr) {
00097 if (sizeof(T) <= mem__private::BIG_BAD_BUF_SIZE) {
00098 return reinterpret_cast<T *>(
00099 ::memcpy(ptr, mem__private::BIG_BAD_BUF, sizeof(T)));
00100 } else {
00101 return PoisonBytes(ptr, sizeof(T));
00102 }
00103 }
00104
00106 template<typename T>
00107 inline T *DebugPoisonBytes(T *array, size_t bytes) {
00108 DEBUG_ONLY(PoisonBytes(array, bytes));
00109 return array;
00110 }
00112 template<typename T>
00113 inline T *DebugPoison(T *array, size_t elems) {
00114 DEBUG_ONLY(Poison(array, elems));
00115 return array;
00116 }
00118 template<typename T>
00119 inline T *DebugPoison(T *ptr) {
00120 DEBUG_ONLY(Poison(ptr));
00121 return ptr;
00122 }
00123
00125 template<typename T>
00126 inline T *AllocBytes(size_t bytes) {
00127 #ifdef SCALE_NORMAL
00128
00129 DEBUG_BOUNDS(bytes, BIG_BAD_NUMBER);
00130 #endif
00131 T *array = reinterpret_cast<T *>(::malloc(bytes));
00132 MEM__DEBUG_MEMORY(array);
00133 return DebugPoisonBytes(array, bytes);
00134 }
00136 template<typename T>
00137 inline T *Alloc(size_t elems) {
00138 #ifdef SCALE_NORMAL
00139
00140 DEBUG_BOUNDS(elems, BIG_BAD_NUMBER);
00141 #endif
00142 return AllocBytes<T>(elems * sizeof(T));
00143 }
00145 template<typename T>
00146 inline T *Alloc() {
00147 T *array = reinterpret_cast<T *>(::malloc(sizeof(T)));
00148 MEM__DEBUG_MEMORY(array);
00149 return DebugPoisonBytes(array);
00150 }
00151
00153 template<typename T>
00154 inline T *ZeroBytes(T *array, size_t bytes) {
00155 return reinterpret_cast<T *>(::memset(array, 0, bytes));
00156 }
00158 template<typename T>
00159 inline T *Zero(T *array, size_t elems = 1) {
00160 return ZeroBytes(array, elems * sizeof(T));
00161 }
00163 template<typename T>
00164 inline T *AllocZeroBytes(size_t bytes) {
00165 T *array = reinterpret_cast<T *>(::calloc(bytes, 1));
00166 MEM__DEBUG_MEMORY(array);
00167 return array;
00168 }
00170 template<typename T>
00171 inline T *AllocZero(size_t elems = 1) {
00172 T *array = reinterpret_cast<T *>(::calloc(elems, sizeof(T)));
00173 MEM__DEBUG_MEMORY(array);
00174 return array;
00175 }
00176
00178 template<typename T, typename U>
00179 inline T *CopyBytes(T *dest, const U *src, size_t bytes) {
00180 return reinterpret_cast<T *>(::memcpy(dest, src, bytes));
00181 }
00183 template<typename V, typename T, typename U>
00184 inline T *Copy(T *dest, const U *src, size_t elems = 1) {
00185 return CopyBytes(dest, src, elems * sizeof(V));
00186 }
00187 template<typename T, typename U>
00188 inline T* CopyValues(T *dest, const U *src, size_t elems=1) {
00189 for(index_t i=0; i<elems; i++) {
00190 dest[i]=T(src[i]);
00191 }
00192 return dest;
00193 }
00194 template<typename T>
00195 inline T *Copy(T *dest, const T *src, size_t elems = 1) {
00196 return Copy<T, T, T>(dest, src, elems);
00197 }
00199 template<typename T, typename U>
00200 inline T *AllocCopyBytes(const U *src, size_t bytes) {
00201 T *array = reinterpret_cast<T *>(::malloc(bytes));
00202 MEM__DEBUG_MEMORY(array);
00203 return CopyBytes(array, src, bytes);
00204 }
00206 template<typename T, typename U>
00207 inline T *AllocCopy(const U *src, size_t elems = 1) {
00208 return AllocCopyBytes<T>(src, elems * sizeof(T));
00209 }
00210
00211 template<typename T, typename U>
00212 inline T *AllocCopyValues(const U *src, size_t elems = 1) {
00213
00214 T *dest = reinterpret_cast<T *>(::malloc(elems*sizeof(T)));
00215 MEM__DEBUG_MEMORY(dest);
00216 return CopyValues<T, U>(dest, src, elems);
00217 }
00218
00219 template<typename T>
00220 inline T *AllocCopy(const T *src, size_t elems = 1) {
00221 return AllocCopy<T, T>(src, elems);
00222 }
00223
00231 template<typename T>
00232 inline T *ReallocBytes(T *array, size_t bytes) {
00233 array = reinterpret_cast<T *>(::realloc(array, bytes));
00234 MEM__DEBUG_MEMORY(array);
00235 return array;
00236 }
00244 template<typename T>
00245 inline T *Realloc(T *array, size_t elems) {
00246 return ReallocBytes<T>(array, elems * sizeof(T));
00247 }
00248
00250 template<typename T>
00251 inline void Free(T* ptr) {
00252 ::free(ptr);
00253 }
00254
00255
00256
00267 template<typename T, typename U>
00268 void SwapBytes(T *a, U *b, size_t bytes) {
00269 char *a_cp = reinterpret_cast<char *>(a);
00270 char *b_cp = reinterpret_cast<char *>(b);
00271 mem__private::SwapBytes(a_cp, b_cp, bytes);
00272 }
00283 template<typename V, typename T, typename U>
00284 inline void Swap(T *a, U *b, size_t elems) {
00285 SwapBytes(a, b, elems * sizeof(V));
00286 }
00287 template<typename T>
00288 inline void Swap(T *a, T *b, size_t elems) {
00289 Swap<T, T, T>(a, b, elems);
00290 }
00291 template<typename V, typename T, typename U>
00292 inline void Swap(T *a, U *b) {
00293 if (sizeof(V) <= mem__private::SWAP_BUF_SIZE * 2) {
00294 char buf[sizeof(V)];
00295
00296 ::memcpy(buf, a, sizeof(V));
00297 ::memcpy(a, b, sizeof(V));
00298 ::memcpy(b, buf, sizeof(V));
00299 } else {
00300 SwapBytes(a, b, sizeof(V));
00301 }
00302 }
00303 template<typename T>
00304 inline void Swap(T *a, T *b) {
00305 Swap<T, T, T>(a, b);
00306 }
00307
00309 template<typename T, typename U>
00310 inline T *MoveBytes(T *dest, const U *src, size_t bytes) {
00311 return reinterpret_cast<T *>(::memmove(dest, src, bytes));
00312 }
00314 template<typename V, typename T, typename U>
00315 inline T *Move(T *dest, const U *src, size_t elems = 1) {
00316 return MoveBytes(dest, src, elems * sizeof(V));
00317 }
00318 template<typename T>
00319 inline T *Move(T *dest, const T *src, size_t elems = 1) {
00320 return Move<T, T, T>(dest, src, elems);
00321 }
00322
00323
00324
00326 template<typename T>
00327 inline T *Construct(T *ptr) {
00328 new(ptr) T;
00329 return ptr;
00330 }
00332 template<typename T>
00333 inline T *Construct(T *array, size_t elems) {
00334 new(array) T[elems];
00335 return array;
00336 }
00338 template<typename T>
00339 inline T *Destruct(T *ptr) {
00340 ptr->~T();
00341 return DebugPoison(ptr);
00342 }
00344 template<typename T>
00345 inline T *Destruct(T *array, size_t elems) {
00346 for (size_t i = 0; i < elems; ++i) {
00347 array[i].~T();
00348 }
00349 return DebugPoison(array, elems);
00350 }
00352 template<typename T, typename U>
00353 inline T *CopyConstruct(T *dest, const U *src) {
00354 new(dest) T(*src);
00355 return dest;
00356 }
00358 template<typename T, typename U>
00359 inline T *CopyConstruct(T *dest, const U *src, size_t elems) {
00360 for (size_t i = 0; i < elems; ++i) {
00361 new(dest + i) T(src[i]);
00362 }
00363 return dest;
00364 }
00365
00367 #define BASE_CCMEM__SIMPLE_CONSTRUCTORS(T, TF) \
00368 template<> \
00369 inline T *Construct< T >(T *ptr) { \
00370 return DebugPoison(ptr); \
00371 } \
00372 template<> \
00373 inline T *Construct< T >(T *array, size_t elems) { \
00374 return DebugPoison(array, elems); \
00375 } \
00376 template<> \
00377 inline T *Destruct< T >(T *ptr) { \
00378 return DebugPoison(ptr); \
00379 } \
00380 template<> \
00381 inline T *Destruct< T >(T *array, size_t elems) { \
00382 return DebugPoison(array, elems); \
00383 } \
00384 template<> \
00385 inline T *CopyConstruct< T >(T *dest, const T *src) { \
00386 return Copy(dest, src, 1); \
00387 } \
00388 template<> \
00389 inline T *CopyConstruct< T >(T *dest, const T *src, size_t elems) { \
00390 return Copy(dest, src, elems); \
00391 }
00392
00393 FOR_ALL_PRIMITIVES_DO(BASE_CCMEM__SIMPLE_CONSTRUCTORS)
00394 BASE_CCMEM__SIMPLE_CONSTRUCTORS(bool, "%d")
00395
00397 template<typename T>
00398 inline T **Construct(T **array, size_t elems = 1) {
00399 return DebugPoison(array, elems);
00400 }
00402 template<typename T>
00403 inline T **Destruct(T **array, size_t elems = 1) {
00404 return DebugPoison(array, elems);
00405 }
00407 template<typename T>
00408 inline T **CopyConstruct(T **dest, const T **src, size_t elems = 1) {
00409 return Copy(dest, src, elems);
00410 }
00411
00412 #undef BASE_CCMEM__SIMPLE_CONSTRUCTORS
00413
00415 template<typename T, typename U>
00416 inline T *RepeatConstruct(T *array, const U &init, size_t elems) {
00417 for (size_t i = 0; i < elems; ++i) {
00418 new(array + i) T(init);
00419 }
00420 return array;
00421 }
00422
00424 template<typename T>
00425 inline T *AllocConstruct(size_t elems = 1) {
00426 return Construct(Alloc<T>(elems), elems);
00427 }
00429 template<typename T, typename U>
00430 inline T *AllocCopyConstruct(const U *src, size_t elems = 1) {
00431 return CopyConstruct(Alloc<T>(elems), src, elems);
00432 }
00433 template<typename T>
00434 inline T *AllocCopyConstruct(const T *src, size_t elems = 1) {
00435 return AllocCopyConstruct<T, T>(src, elems);
00436 }
00438 template<typename T, typename U>
00439 inline T *AllocRepeatConstruct(const U &init, size_t elems) {
00440 return RepeatConstruct(Alloc<T>(elems), init, elems);
00441 }
00442 template<typename T>
00443 inline T *AllocRepeatConstruct(const T &init, size_t elems) {
00444 return AllocRepeatConstruct<T, T>(init, elems);
00445 }
00446
00448 template<typename T>
00449 inline void FreeDestruct(T *array, size_t elems = 1) {
00450 Free(Destruct(array, elems));
00451 }
00452
00453
00454
00456 template<typename T>
00457 inline T *PtrAddBytes(T *ptr, ptrdiff_t bytes) {
00458 return reinterpret_cast<T *>(
00459 reinterpret_cast<char *>(ptr) + bytes);
00460 }
00462 template<typename T>
00463 inline const T *PtrAddBytes(const T *ptr, ptrdiff_t bytes) {
00464 return reinterpret_cast<const T *>(
00465 reinterpret_cast<const char *>(ptr) + bytes);
00466 }
00468 template<typename T, typename U>
00469 inline ptrdiff_t PtrDiffBytes(const T *lhs, const U *rhs) {
00470 return reinterpret_cast<const char *>(lhs)
00471 - reinterpret_cast<const char *>(rhs);
00472 }
00474 template<typename T>
00475 inline ptrdiff_t PtrAbsAddr(const T *ptr) {
00476 return reinterpret_cast<ptrdiff_t>(ptr);
00477 }
00479 template<typename T, typename U>
00480 inline bool PtrsEqual(const T *lhs, const U *rhs) {
00481 return reinterpret_cast<size_t>(lhs)
00482 == reinterpret_cast<size_t>(rhs);
00483 }
00484
00486
00488 template<typename T>
00489 T *BitZeroBytes(T *array, size_t bytes) {
00490 return ZeroBytes(array, bytes);
00491 }
00493 template<typename T>
00494 T *BitZero(T *array, size_t elems = 1) {
00495 return Zero(array, elems);
00496 }
00498 template<typename T, typename U>
00499 T *BitCopyBytes(T *dest, const U *src, size_t bytes) {
00500 return CopyBytes(dest, src, bytes);
00501 }
00503 template<typename T>
00504 T *BitCopy(T *dest, const T *src, size_t elems = 1) {
00505 return Copy(dest, src, elems);
00506 }
00508 template<typename T>
00509 void BitSwap(T *a, T *b, size_t elems = 1) {
00510 Swap(a, b, elems);
00511 }
00512 };
00513
00514 #undef MEM__DEGUG_MEMORY
00515
00516 #endif