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
00032
00033
00034
00035
00036
00037
00038 namespace Gecode { namespace Support {
00039
00048 template<class T, class A, int blocksize = 512>
00049 class BlockAllocator {
00050 private:
00052 A& a;
00054 class Block {
00055 public:
00056 T b[blocksize];
00057 Block* next;
00058 };
00060 Block* b;
00062 T* n;
00064 size_t _size;
00066 void allocate(void);
00067 public:
00069 BlockAllocator(A& a);
00071 ~BlockAllocator(void);
00073 A& allocator(void);
00075 T* operator ()(void);
00077 size_t size(void) const;
00078 };
00079
00087 template<class T, class A, int blocksize = 512>
00088 class BlockClient {
00089 public:
00091 static void* operator new(size_t s, BlockAllocator<T,A,blocksize>& ba);
00093 static void operator delete(void*, BlockAllocator<T,A,blocksize>& ba);
00095 static void operator delete(void*);
00096 };
00097
00098
00099
00100 template<class T, class A, int blocksize>
00101 forceinline
00102 BlockAllocator<T,A,blocksize>::BlockAllocator(A& a0) : a(a0) {
00103 b = static_cast<Block*>(a.ralloc(sizeof(Block)));
00104 b->next = NULL;
00105 n = &b->b[blocksize];
00106 _size = sizeof(Block);
00107 }
00108
00109 template<class T, class A, int blocksize>
00110 forceinline
00111 BlockAllocator<T,A,blocksize>::~BlockAllocator(void) {
00112 while (b != NULL) {
00113 Block* f = b; b = b->next;
00114 a.rfree(f,sizeof(Block));
00115 }
00116 }
00117
00118 template<class T, class A, int blocksize>
00119 forceinline A&
00120 BlockAllocator<T,A,blocksize>::allocator(void) {
00121 return a;
00122 }
00123
00124 template<class T, class A, int blocksize>
00125 forceinline T*
00126 BlockAllocator<T,A,blocksize>::operator ()(void) {
00127 T* t = --n;
00128 if (t == &b->b[0])
00129 allocate();
00130 return t;
00131 }
00132
00133 template<class T, class A, int blocksize>
00134 void
00135 BlockAllocator<T,A,blocksize>::allocate(void) {
00136
00137 Block* nb = static_cast<Block*>(a.ralloc(sizeof(Block)));
00138 nb->next = b; b = nb;
00139 n = &nb->b[blocksize];
00140 _size += sizeof(Block);
00141 }
00142
00143 template<class T, class A, int blocksize>
00144 forceinline size_t
00145 BlockAllocator<T,A,blocksize>::size(void) const {
00146 return _size;
00147 }
00148
00149
00150
00151 template<class T, class A, int blocksize>
00152 forceinline void
00153 BlockClient<T,A,blocksize>::operator
00154 delete(void*,BlockAllocator<T,A,blocksize>&) {
00155 }
00156 template<class T, class A, int blocksize>
00157 forceinline void
00158 BlockClient<T,A,blocksize>::operator delete(void*) {
00159 }
00160 template<class T, class A, int blocksize>
00161 forceinline void*
00162 BlockClient<T,A,blocksize>::operator new(size_t,
00163 BlockAllocator<T,A,blocksize>& ba) {
00164 return ba();
00165 }
00166
00167 }}
00168
00169