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