00001 #ifndef __LDK_MEMORY_HH__
00002 #define __LDK_MEMORY_HH__
00003
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00028
00033 #include "LDK/Types.h"
00034 #include "LDK/Threading.h"
00035 #include "LDK/TemplateMeta.h"
00036 #include "LDK/Singletons.h"
00037 #include "LDK/Exceptions.h"
00038 #include <vector>
00039 #include <list>
00040
00041
00042
00043 #include <string.h>
00044 #include <assert.h>
00045
00046 #ifdef DEBUG
00047 #define LDK_TRACK_ALLOCATION
00048 #endif //DEBUG
00049
00050 namespace LDK
00051 {
00052
00053
00054 #define BYTE_ALIGNMENT 16
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 #define LDK_SPARE_HEAPS 30
00068 #ifdef THIRTY_TWO_BIT
00069 #define LDK_HEAPSIZE_K 512
00070 #define LDK_MINCHUNKSIZE 16
00071 #elif defined SIXTY_FOUR_BIT
00072 #define LDK_HEAPSIZE_K 1024
00073 #define LDK_MINCHUNKSIZE 32
00074 #endif //THIRTY_TWO_BIT
00075
00076 #define LDK_MAXCHUNKSIZE ((LDK_HEAPSIZE_K*1024)/2)
00077
00078
00079
00080
00081
00082 #if LDK_HEAPSIZE_K % 2 != 0
00083 #error "LDK_HEAPSIZE_K must be even"
00084 #endif //LDK_HEAPSIZE_K % 2 == 0
00085
00086 #if LDK_MAXCHUNKSIZE < LDK_MINCHUNKSIZE
00087 #error "LDK_MAXCHUNKSIZE < LDK_MINCHUNKSIZE"
00088 #endif //LDK_MAXCHUNKSIZE < LDK_MINCHUNKSIZE
00089
00090 #if LDK_MINCHUNKSIZE % 2 != 0
00091 #error "LDK_MINCHUNKSIZE must be even"
00092 #endif //LDK_MINCHUNKSIZE % 2 != 0
00093
00094 #if LDK_MAXCHUNKSIZE % 2 != 0
00095 #warning "LDK_MAXCHUNKSIZE must be even"
00096 #endif //LDK_MAXCHUNKSIZE % 2 != 0
00097
00098 #if LDK_MAXCHUNKSIZE / 1024 > LDK_HEAPSIZE_K
00099 #error "LDK_MAXCHUNKSIZE / 1024 > HEAP_SIZE"
00100 #endif //LDK_MAXCHUNKSIZE / 1024 > LDK_HEAPSIZE_K
00101
00102 #ifdef THIRTY_TWO_BIT
00103 #if LDK_MINCHUNKSIZE < 16
00104 #warning "minimum chunk size is less than housekeeping size"
00105 #endif //LDK_MINCHUNKSIZE < 16
00106 #elif defined SIXTY_FOUR_BIT
00107 #if LDK_MINCHUNKSIZE < 32
00108 #warning "minimum chunk size is less than housekeeping size"
00109 #endif //LDK_MINCHUNKSIZE < 32
00110 #endif //THIRTY_TWO_BIT
00111
00112 #define MAX_CHUNKS_PER_HEAP (LDK_HEAPSIZE_K/ LDK_MINCHUNKSIZE)
00113
00114
00115
00116
00117
00118
00119 LDK_API void* alignedAlloc(size_t bytes, size_t align=BYTE_ALIGNMENT);
00120 LDK_API void alignedFree(void *mem);
00121
00122
00123
00124 inline void* bigAlloc(size_t size);
00125
00126 class LDK_API MetaPool;
00127
00128 namespace Details
00129 {
00130
00131 class LDK_API Heap;
00133
00134
00135
00136
00137
00139
00140 struct LDK_API Node
00141 {
00142
00143
00144 size_t mAllocSize;
00145
00146 Node* mNext;
00147
00148 Heap* mHeap;
00149
00150
00151 size_t mThreadID;
00152 };
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 inline Heap* getOwnerHeap(void* mem)
00164 {
00165
00166 return *(Heap**) (((char*)mem) - sizeof(size_t) - sizeof(Heap*));
00167 }
00168
00169
00170 inline Node* getNode(void* mem)
00171 {
00172 return (Node*)(((char*)mem) - sizeof(Node));
00173 }
00174
00175 class LDK_API Pool;
00176
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00196
00197 class LDK_API Heap
00198 {
00199 friend class LDK_API Pool;
00200
00201 void* mMemory;
00202
00203 size_t mNodeSize;
00204
00205 Node* mNextFree;
00206
00207 Node* mLastNode;
00208
00209 size_t mChunkSize;
00210
00211 size_t mAllocCount;
00212
00213 size_t mMaxAllocs;
00214
00215 Pool* mParent;
00216
00217 const size_t mSizeInBytes;
00218
00219 const size_t mRealSize;
00220
00221 void setup(Pool* parent, size_t chunkSize);
00222
00223
00224 public:
00225
00226
00227 inline void* operator new(size_t size)
00228 {
00229 void* mem = malloc(size);
00230 if(!mem)
00231 throw LDK_BADALLOC_ERROR;
00232 return mem;
00233 }
00234
00235 inline void operator delete(void* mem)
00236 {
00237 assert(mem);
00238 ::free(mem);
00239 }
00240
00241 inline Heap(Pool* parent, size_t chunkSize, size_t size) :
00242 mMemory(NULL),
00243 mChunkSize(chunkSize),
00244 mSizeInBytes(size),
00245 mRealSize(size+(MAX_CHUNKS_PER_HEAP*sizeof(Node)))
00246 {
00247 mMemory = alignedAlloc(mRealSize);
00248 setup(parent, chunkSize);
00249 }
00250
00251 inline ~Heap()
00252 {
00253 if(mMemory)
00254 alignedFree(mMemory);
00255 }
00256
00257
00258
00259
00260 inline Node* operator[](size_t idx) const
00261 {
00262 return reinterpret_cast<Node*>((char*)mMemory + (idx*mNodeSize));
00263 }
00264
00265 inline size_t chunkSize() const { return mChunkSize; }
00266
00267 inline size_t sizeInBytes() const { return mSizeInBytes; }
00268
00269 inline size_t allocCount() const { return mAllocCount; }
00270
00271 inline size_t maxAllocs() const { return mMaxAllocs; }
00272
00273 inline bool full() const { return !mNextFree; }
00274
00275 inline bool empty() const { return mAllocCount == 0; }
00276
00277
00278
00279
00280 inline void* allocChunk(size_t allocSize)
00281 {
00282 void *chunk = NULL;
00283 mNextFree->mAllocSize = allocSize;
00284 #ifndef NDEBUG
00285 mNextFree->mThreadID = currentThreadID();
00286 #endif
00287 chunk = (void*)(((char*)mNextFree) + sizeof(Node));
00288 mNextFree = mNextFree->mNext;
00289 mAllocCount++;
00290 return chunk;
00291 }
00292
00293
00294
00295
00296
00297 void freeChunk(void *mem);
00298 };
00299
00301
00302
00303
00304
00305
00307
00308 class LDK_API Pool
00309 {
00310 protected:
00311 friend class LDK_API Heap;
00312 friend class LDK_API LDK::MetaPool;
00313 Heap* mCurrentHeap;
00314 Heap* mSpareHeap;
00315 size_t mChunkSize;
00316 MetaPool* mParent;
00317 const size_t mDefaultHeapSize;
00318 #ifdef _MSC_VER
00319 #pragma warning (disable : 4251)
00320 #endif
00321 typedef std::vector<Heap*,MallocAllocator<Heap*> > HeapVector;
00322 HeapVector mHeaps;
00323 #ifdef _MSC_VER
00324 #pragma warning (default : 4251)
00325 #endif
00326
00327
00328
00329
00330
00331 void cleanup(Heap* h);
00332
00333 public:
00334
00335 Pool(MetaPool* parent, size_t chunkSize, size_t defaultHeapSize);
00336 ~Pool();
00337
00338
00339
00340
00341 void findHeap();
00342
00343
00344
00345
00346 inline void *allocChunk(size_t allocSize)
00347 {
00348 if(!mCurrentHeap || mCurrentHeap->full())
00349 findHeap();
00350 return mCurrentHeap->allocChunk(allocSize);
00351 }
00352
00353 inline size_t chunkSize() const { return mChunkSize; }
00354 inline size_t noOfHeaps() const { return mHeaps.size(); }
00355 inline size_t defaultHeapSize() const { return mDefaultHeapSize; }
00356 };
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 #define MIN_CHUNKSIZE LDK_MINCHUNKSIZE
00367 #define MAX_CHUNKSIZE LDK_MAXCHUNKSIZE
00368
00370
00372
00373 template <int Size>
00374 struct PoolCount
00375 {
00376 enum { value = PoolCount<Size/2>::value + 1 };
00377 };
00378
00379
00380 template <>
00381 struct LDK_API PoolCount<MIN_CHUNKSIZE>
00382 {
00383 enum { value = 1 };
00384 };
00385
00386 template <>
00387 struct LDK_API PoolCount<(MIN_CHUNKSIZE+(MIN_CHUNKSIZE/2))>
00388 {
00389 enum { value = 1 };
00390 };
00391
00392 template <>
00393 struct LDK_API PoolCount<(MIN_CHUNKSIZE+(MIN_CHUNKSIZE/3))>
00394 {
00395 enum { value = 1 };
00396 };
00397
00398
00399
00400 struct LDK_API NoOfPools
00401 {
00402 enum
00403 {
00404 max = MAX_CHUNKSIZE,
00405 maxIsPowerOf2 = Meta::PowerOf2<max>::value,
00406 pwrOf2 = PoolCount<(maxIsPowerOf2 ? max : (max-(max/3)))>::value,
00407 notPwrOf2 = PoolCount<(maxIsPowerOf2 ? (max-(max/4)) : max)>::value,
00408 value = pwrOf2 + notPwrOf2
00409 };
00410 };
00411
00413
00415 template <int Idx>
00416 class ChunkSize
00417 {
00418 struct MinChunkPowerOf2
00419 {
00420 enum
00421 {
00422 powerOf2 = !(Idx%2),
00423 value = powerOf2 ? ChunkSize<Idx+1>::value - ChunkSize<Idx+1>::value/3 :\
00424 ChunkSize<Idx+1>::value - ChunkSize<Idx+1>::value/4
00425 };
00426 };
00427 struct MinChunkNotPowerOf2
00428 {
00429 enum
00430 {
00431 powerOf2 = Idx%2,
00432 value = powerOf2 ? ChunkSize<Idx+1>::value - ChunkSize<Idx+1>::value/3 :\
00433 ChunkSize<Idx+1>::value - ChunkSize<Idx+1>::value/4
00434 };
00435 };
00436 public:
00437 enum
00438 {
00439 value = Meta::If<Meta::PowerOf2<MIN_CHUNKSIZE>::value, MinChunkPowerOf2,\
00440 MinChunkNotPowerOf2>::result::value
00441 };
00442 };
00443
00444
00445 template<>
00446 class LDK_API ChunkSize<NoOfPools::value>
00447 {
00448 struct LDK_API MaxChunkPowerOf2
00449 {
00450 enum { value = MAX_CHUNKSIZE + (MAX_CHUNKSIZE/2) };
00451 };
00452 struct LDK_API MaxChunkNotPowerOf2
00453 {
00454 enum { value = MAX_CHUNKSIZE + (MAX_CHUNKSIZE/3) };
00455 };
00456 public:
00457 enum
00458 {
00459 value = Meta::If<Meta::PowerOf2<MAX_CHUNKSIZE>::value,\
00460 MaxChunkPowerOf2, MaxChunkNotPowerOf2>::result::value
00461 };
00462 };
00463
00465
00467 template
00468 <
00469 int NoOfPools,
00470 int Size,
00471 int Idx=0
00472 >
00473 struct PoolIdxSearch
00474 {
00475 enum
00476 {
00477
00478 inRange = Size <= MAX_CHUNKSIZE? true : false,
00479
00480 fitsHereToo = (inRange && (Size < ChunkSize<Idx>::value)) ? true : false,
00481
00482 value = fitsHereToo ? Idx : PoolIdxSearch<NoOfPools,Size,Idx+1>::value
00483 };
00484 };
00485
00486
00487
00488 template <int Size>
00489 struct PoolIdxSearch<NoOfPools::value,Size,NoOfPools::value>
00490 {
00491 enum { value = -1 };
00492 };
00493
00494 #undef MIN_CHUNKSIZE
00495 #undef MAX_CHUNKSIZE
00496
00497
00498
00499
00500
00501
00502
00503 }
00504
00506
00507
00508
00509
00510
00511
00513 #ifdef _MSC_VER //non exported members
00514 #pragma warning (disable : 4251)
00515 #endif
00516 class LDK_API MetaPool
00517 {
00518 private:
00519
00520 friend class LDK_API Details::Pool;
00521
00522 typedef Details::NoOfPools NoOfPools;
00523
00524
00525 Details::Pool* mPools[NoOfPools::value];
00526
00527
00528
00529
00530
00531 typedef std::vector<Details::Heap*,MallocAllocator<Details::Heap*> > HeapVector;
00532 HeapVector mSpareHeaps;
00533
00534 #ifdef LDK_TRACK_ALLOCATION
00535 struct TrackedAlloc
00536 {
00537 void* mMem;
00538 int mLine;
00539 char mFile[128];
00540
00541 inline TrackedAlloc(const char* file=NULL, int line=0, void* mem=NULL)
00542 {
00543 mMem = mem;
00544 mLine = line;
00545 mFile[127]= '\0';
00546 strncpy(mFile,file,127);
00547 }
00548 };
00549 typedef std::list<TrackedAlloc,MallocAllocator<TrackedAlloc> > AllocList;
00550 AllocList mAllocs;
00551 #endif
00552
00553
00554 void addSpareHeap(Details::Heap* h);
00555 Details::Heap* findSpareHeap(size_t chunkSize);
00556
00557 public:
00558 #ifdef LDK_TRACK_ALLOCATION
00559 inline void trackAlloc(const char* file, int line, void* mem)
00560 {
00561 mAllocs.push_back(TrackedAlloc(file,line,mem));
00562 }
00563
00564 inline void untrackAlloc(void* mem)
00565 {
00566 AllocList::iterator i = mAllocs.end();
00567 if(!mAllocs.empty())
00568 {
00569 i--;
00570 while(i != mAllocs.begin())
00571 {
00572 if((*i).mMem == mem)
00573 {
00574 mAllocs.erase(i);
00575 return;
00576 }
00577 i--;
00578 }
00579 if((*i).mMem == mem)
00580 {
00581 mAllocs.erase(i);
00582 return;
00583 }
00584 }
00585 }
00586
00587
00588 void dumpAllocs();
00589 #endif
00590
00591 inline Details::Pool* pool(int idx)
00592 {
00593 return mPools[idx];
00594 }
00595
00596 MetaPool();
00597 ~MetaPool();
00598
00599
00600 void* alloc(const char* file, int line, size_t size);
00601
00602
00603
00604 void* realloc(const char* file, int line, void *mem, size_t newSize);
00605
00606
00607
00608 void dealloc(void *mem)
00609 {
00610 if(mem)
00611 {
00612 #ifdef LDK_TRACK_ALLOCATION
00613 untrackAlloc(mem);
00614 #endif
00615 Details::Heap *h = Details::getOwnerHeap(mem);
00616 if(!h)
00617 {
00618 alignedFree(Details::getNode(mem));
00619 return;
00620 }
00621 h->freeChunk(mem);
00622 }
00623 }
00624 };
00625 #ifdef _MSC_VER
00626 #pragma warning (default : 4251)
00627 #endif
00628
00629 typedef Singleton<MetaPool> MemorySingleton;
00630
00631
00632
00633 template<int Idx>
00634 struct CTAllocHelper
00635 {
00636 inline static void* alloc(const char* file, int line, size_t size)
00637 {
00638 MetaPool& mp = MemorySingleton::instance();
00639 void* mem = mp.pool(Idx)->allocChunk(size);
00640 #ifdef LDK_TRACK_ALLOCATION
00641 mp.trackAlloc(file,line,mem);
00642 #endif
00643 return mem;
00644 }
00645 };
00646
00647
00648
00649 template<size_t Size>
00650 struct RTAllocHelper
00651 {
00652 inline static void* alloc(const char* file, int line, size_t)
00653 {
00654 void* mem = bigAlloc(Size);
00655 #ifdef LDK_TRACK_ALLOCATION
00656 MemorySingleton::instance().trackAlloc(file,line,mem);
00657 #endif
00658 return mem;
00659 }
00660 };
00661
00662
00663
00664
00667
00704
00705 inline void* bigAlloc(size_t size)
00706 {
00707 void* mem = alignedAlloc(size+sizeof(Details::Node));
00708 Details::Node* n = reinterpret_cast<Details::Node*>(mem);
00709 n->mAllocSize = size;
00710 n->mNext = NULL;
00711 n->mHeap = NULL;
00712 #ifndef NDEBUG
00713 n->mThreadID = currentThreadID();
00714 #endif
00715 return (void*)((char*)mem+sizeof(Details::Node));
00716 }
00717
00718
00719
00720 template<size_t Size>
00721 inline void* alloc(const char* file, int line)
00722 {
00723 const int idx = Details::PoolIdxSearch<Details::NoOfPools::value,Size>::value;
00724 return Meta::If<idx!=-1,CTAllocHelper<idx>, \
00725 RTAllocHelper<Size> >::result::alloc(file,line,Size);
00726 }
00736 #define LDK_CTALLOC(size) LDK::alloc<size>(__FILE__,__LINE__)
00737
00749 #define LDK_CTTYPEALLOC(type,num) ((type*)LDK::alloc<sizeof(type)*num)>(__FILE__,__LINE__)
00750
00751 inline void* alloc(const char* file, int line, size_t size)
00752 {
00753 return MemorySingleton::instance().alloc(file,line,size);
00754 }
00764 #define LDK_RTALLOC(size) LDK::alloc(__FILE__,__LINE__,size)
00765
00777 #define LDK_RTTYPEALLOC(type,num) ((type*)LDK::alloc(__FILE__,__LINE__,sizeof(type)*num))
00778
00789 inline void dealloc(void* mem)
00790 {
00791 MemorySingleton::instance().dealloc(mem);
00792 }
00793
00794 inline void* realloc(const char* file, int line, void *mem, size_t newSize)
00795 {
00796 return MemorySingleton::instance().realloc(file,line,mem, newSize);
00797 }
00810 #define LDK_REALLOC(mem, newSize) LDK::realloc(__FILE__,__LINE__,mem,newSize)
00811
00832
00833 template <class T>
00834 inline T* create(const char* file, int line)
00835 {
00836 void* mem = LDK::alloc<sizeof(T)>(file,line);
00837 try
00838 {
00839 return new (mem) T();
00840 }
00841 catch(std::exception& e)
00842 {
00843 LDK::dealloc(mem);
00844 throw e;
00845 }
00846 catch(...)
00847 {
00848 LDK::dealloc(mem);
00849 throw;
00850 }
00851 };
00858 #define LDK_CREATE0(Type) LDK::create<Type >(__FILE__,__LINE__)
00859
00860
00861 template
00862 <
00863 class T,
00864 typename C1
00865 >
00866 inline T* create(const char* file, int line, C1 c1)
00867 {
00868 void* mem = LDK::alloc<sizeof(T)>(file,line);
00869 try
00870 {
00871 return new (mem) T(c1);
00872 }
00873 catch(std::exception& e)
00874 {
00875 LDK::dealloc(mem);
00876 throw e;
00877 }
00878 catch(...)
00879 {
00880 LDK::dealloc(mem);
00881 throw;
00882 }
00883 };
00890 #define LDK_CREATE1(Type,c1) LDK::create<Type >(__FILE__,__LINE__,c1)
00891
00892 template
00893 <
00894 class T,
00895 typename C1,
00896 typename C2
00897 >
00898 inline T* create(const char* file, int line, C1 c1, C2 c2)
00899 {
00900 void* mem = LDK::alloc<sizeof(T)>(file,line);
00901 try
00902 {
00903 return new (mem) T(c1,c2);
00904 }
00905 catch(std::exception& e)
00906 {
00907 LDK::dealloc(mem);
00908 throw e;
00909 }
00910 catch(...)
00911 {
00912 LDK::dealloc(mem);
00913 throw;
00914 }
00915 };
00916
00923 #define LDK_CREATE2(Type,c1,c2) LDK::create<Type >(__FILE__,__LINE__,c1,c2)
00924
00925 template
00926 <
00927 class T,
00928 typename C1,
00929 typename C2,
00930 typename C3
00931 >
00932 inline T* create(const char* file, int line, C1 c1, C2 c2, C3 c3)
00933 {
00934 void* mem = LDK::alloc<sizeof(T)>(file,line);
00935 try
00936 {
00937 return new (mem) T(c1,c2,c3);
00938 }
00939 catch(std::exception& e)
00940 {
00941 LDK::dealloc(mem);
00942 throw e;
00943 }
00944 catch(...)
00945 {
00946 LDK::dealloc(mem);
00947 throw;
00948 }
00949 };
00950
00957 #define LDK_CREATE3(Type,c1,c2,c3) LDK::create<Type >(__FILE__,__LINE__,c1,c2,c3)
00958
00959 template
00960 <
00961 class T,
00962 typename C1,
00963 typename C2,
00964 typename C3,
00965 typename C4
00966 >
00967 inline T* create(const char* file, int line, C1 c1, C2 c2, C3 c3, C4 c4)
00968 {
00969 void* mem = LDK::alloc<sizeof(T)>(file,line);
00970 try
00971 {
00972 return new (mem) T(c1,c2,c3,c4);
00973 }
00974 catch(std::exception& e)
00975 {
00976 LDK::dealloc(mem);
00977 throw e;
00978 }
00979 catch(...)
00980 {
00981 LDK::dealloc(mem);
00982 throw;
00983 }
00984 };
00985
00992 #define LDK_CREATE4(Type,c1,c2,c3,c4) LDK::create<Type >(__FILE__,__LINE__,c1,c2,c3,c4)
00993
00994 template
00995 <
00996 class T,
00997 typename C1,
00998 typename C2,
00999 typename C3,
01000 typename C4,
01001 typename C5
01002 >
01003 inline T* create(const char* file, int line, C1 c1, C2 c2, C3 c3, C4 c4, C5 c5)
01004 {
01005 void* mem = LDK::alloc<sizeof(T)>(file,line);
01006 try
01007 {
01008 return new (mem) T(c1,c2,c3,c4,c5);
01009 }
01010 catch(std::exception& e)
01011 {
01012 LDK::dealloc(mem);
01013 throw e;
01014 }
01015 catch(...)
01016 {
01017 LDK::dealloc(mem);
01018 throw;
01019 }
01020 };
01021
01028 #define LDK_CREATE5(Type,c1,c2,c3,c4,c5) LDK::create<Type >(__FILE__,__LINE__,c1,c2,c3,c4,c5)
01029
01030 template
01031 <
01032 class T,
01033 typename C1,
01034 typename C2,
01035 typename C3,
01036 typename C4,
01037 typename C5,
01038 typename C6
01039 >
01040 inline T* create(const char* file, int line, C1 c1, C2 c2, C3 c3, C4 c4, C5 c5, C6 c6)
01041 {
01042 void* mem = LDK::alloc<sizeof(T)>(file,line);
01043 try
01044 {
01045 return new (mem) T(c1,c2,c3,c4,c5,c6);
01046 }
01047 catch(std::exception& e)
01048 {
01049 LDK::dealloc(mem);
01050 throw e;
01051 }
01052 catch(...)
01053 {
01054 LDK::dealloc(mem);
01055 throw;
01056 }
01057 };
01058
01065 #define LDK_CREATE6(Type,c1,c2,c3,c4,c5,c6) LDK::create<Type >(__FILE__,__LINE__,\
01066 c1,c2,c3,c4,c5,c6)
01067
01068 template
01069 <
01070 class T,
01071 typename C1,
01072 typename C2,
01073 typename C3,
01074 typename C4,
01075 typename C5,
01076 typename C6,
01077 typename C7
01078 >
01079 inline T* create(const char* file, int line, C1 c1, C2 c2, C3 c3, C4 c4, C5 c5, C6 c6, C7 c7)
01080 {
01081 void* mem = LDK::alloc<sizeof(T)>(file,line);
01082 try
01083 {
01084 return new (mem) T(c1,c2,c3,c4,c5,c6,c7);
01085 }
01086 catch(std::exception& e)
01087 {
01088 LDK::dealloc(mem);
01089 throw e;
01090 }
01091 catch(...)
01092 {
01093 LDK::dealloc(mem);
01094 throw;
01095 }
01096 };
01097
01104 #define LDK_CREATE7(Type,c1,c2,c3,c4,c5,c6,c7) LDK::create<Type >(__FILE__,__LINE__,\
01105 c1,c2,c3,c4,c5,c6,c7)
01106
01107 template
01108 <
01109 class T,
01110 typename C1,
01111 typename C2,
01112 typename C3,
01113 typename C4,
01114 typename C5,
01115 typename C6,
01116 typename C7,
01117 typename C8
01118 >
01119 inline T* create(const char* file, int line, C1 c1, C2 c2, C3 c3, C4 c4, C5 c5, C6 c6, C7 c7, C8 c8)
01120 {
01121 void* mem = LDK::alloc<sizeof(T)>(file,line);
01122 try
01123 {
01124 return new (mem) T(c1,c2,c3,c4,c5,c6,c7,c8);
01125 }
01126 catch(std::exception& e)
01127 {
01128 LDK::dealloc(mem);
01129 throw e;
01130 }
01131 catch(...)
01132 {
01133 LDK::dealloc(mem);
01134 throw;
01135 }
01136 };
01143 #define LDK_CREATE8(Type,c1,c2,c3,c4,c5,c6,c7,c8) LDK::create<Type >(__FILE__,__LINE__,\
01144 c1,c2,c3,c4,c5,c6,c7,c8)
01145
01146 template
01147 <
01148 class T,
01149 typename C1,
01150 typename C2,
01151 typename C3,
01152 typename C4,
01153 typename C5,
01154 typename C6,
01155 typename C7,
01156 typename C8,
01157 typename C9
01158 >
01159 inline T* create(const char* file, int line, C1 c1, C2 c2, C3 c3, C4 c4, C5 c5, C6 c6, C7 c7, C8 c8, C9 c9)
01160 {
01161 void* mem = LDK::alloc<sizeof(T)>(file,line);
01162 try
01163 {
01164 return new (mem) T(c1,c2,c3,c4,c5,c6,c7,c8,c9);
01165 }
01166 catch(std::exception& e)
01167 {
01168 LDK::dealloc(mem);
01169 throw e;
01170 }
01171 catch(...)
01172 {
01173 LDK::dealloc(mem);
01174 throw;
01175 }
01176 };
01183 #define LDK_CREATE9(Type,c1,c2,c3,c4,c5,c6,c7,c8,c9) LDK::create<Type >(__FILE__,__LINE__,\
01184 c1,c2,c3,c4,c5,c6,c7,c8,c9)
01185
01186 template
01187 <
01188 class T,
01189 typename C1,
01190 typename C2,
01191 typename C3,
01192 typename C4,
01193 typename C5,
01194 typename C6,
01195 typename C7,
01196 typename C8,
01197 typename C9,
01198 typename C10
01199 >
01200 inline T* create(const char* file, int line, C1 c1, C2 c2, C3 c3, C4 c4, C5 c5, C6 c6, C7 c7, C8 c8, C9 c9, C10 c10)
01201 {
01202 void* mem = LDK::alloc<sizeof(T)>(file,line);
01203 try
01204 {
01205 return new (mem) T(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10);
01206 }
01207 catch(std::exception& e)
01208 {
01209 LDK::dealloc(mem);
01210 throw e;
01211 }
01212 catch(...)
01213 {
01214 LDK::dealloc(mem);
01215 throw;
01216 }
01217 };
01224 #define LDK_CREATE10(Type,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10) LDK::create<Type >(__FILE__,__LINE__,\
01225 c1,c2,c3,c4,c5,c6,c7,c8,c9,c10)
01226
01232 template <class T>
01233 inline void destroy(const T* o)
01234 {
01235
01236 T* obj = const_cast<T*>(o);
01237 if(obj)
01238 {
01239 obj->~T();
01240 LDK::dealloc(obj);
01241 }
01242 }
01243
01250 #define LDK_ALLOCATORS \
01251 inline void* operator new(size_t size)\
01252 {\
01253 return LDK::alloc(size);\
01254 }\
01255 inline void operator delete(void* mem)\
01256 {\
01257 LDK::dealloc(mem);\
01258 }\
01259 inline void* operator new[](size_t size)\
01260 {\
01261 return LDK::alloc(size);\
01262 }\
01263 inline void operator delete[](void* mem)\
01264 {\
01265 LDK::dealloc(mem);\
01266 }
01267
01269
01270 }
01271
01272 #include "LDK/STLAllocator.h"
01273 #include "LDK/STLMallocAllocator.h"
01274
01275
01276 #undef BYTE_ALIGNMENT
01277 #undef MAX_CHUNKS_PER_HEAP
01278
01279 #endif //__LDK_MEMORY_HH__