00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #ifndef util_FixedPoolAlloc_hpp
00029 #define util_FixedPoolAlloc_hpp
00030
00031 #include <cstddef>
00032
00033 namespace phdmesh {
00034
00035 void ** fixed_pool_buffer_init( const std::size_t nbyte_total ,
00036 const std::size_t nbyte ,
00037 void ** );
00038
00039 void throw_fixed_pool_buffer_bad_size( const std::size_t nbyte_total ,
00040 const std::size_t nbyte_first ,
00041 const std::size_t nbyte );
00042
00043 void throw_fixed_pool_buffer_exhausted( const std::size_t nbyte_total ,
00044 const std::size_t nbyte );
00045
00046 void throw_fixed_pool_buffer_bad_deallocate( const std::size_t ,
00047 void * const );
00048
00049 template<unsigned NBYTE>
00050 class FixedPoolBuffer {
00051 private:
00052
00053 enum { NWORD = NBYTE / sizeof(void*) };
00054
00055 std::size_t size ;
00056 void ** link ;
00057 void * mem[ NWORD ];
00058
00059 FixedPoolBuffer( const FixedPoolBuffer<NBYTE> & );
00060 FixedPoolBuffer<NBYTE> & operator = ( const FixedPoolBuffer<NBYTE> & );
00061
00062 public:
00063
00064 ~FixedPoolBuffer() {}
00065
00066 FixedPoolBuffer() : size(0) { link = mem ; }
00067
00068 bool full() const { return ! link ; }
00069
00070 void * allocate( std::size_t nbyte )
00071 {
00072 void * p = NULL ;
00073 if ( nbyte ) {
00074 if ( ! size ) {
00075 size = nbyte ;
00076 fixed_pool_buffer_init(NBYTE,size,link);
00077 }
00078 else if ( nbyte != size ) {
00079 throw_fixed_pool_buffer_bad_size(NBYTE,size,nbyte);
00080 }
00081 if ( ! link ) {
00082 throw_fixed_pool_buffer_exhausted(NBYTE,nbyte);
00083 }
00084 p = link ;
00085 link = reinterpret_cast<void**>( *link );
00086 }
00087 return p ;
00088 }
00089
00090 void deallocate( void * p , std::size_t nbyte )
00091 {
00092 if ( nbyte != size ) {
00093 throw_fixed_pool_buffer_bad_size(NBYTE,size,nbyte);
00094 }
00095 void ** const vp = reinterpret_cast<void**>(p);
00096 if ( vp < mem || ( mem + NWORD - size ) < vp ) {
00097 throw_fixed_pool_buffer_bad_deallocate(NBYTE,p);
00098 }
00099 *vp = link ;
00100 link = reinterpret_cast<void**>(vp);
00101 return ;
00102 }
00103 };
00104
00105
00106 template<unsigned NBYTE,typename T=void*>
00107 class FixedPoolAllocator {
00108 private:
00109
00110 FixedPoolBuffer<NBYTE> * buffer ;
00111
00112 FixedPoolAllocator<NBYTE,T> &
00113 operator = ( const FixedPoolAllocator<NBYTE,T> & );
00114
00115 template<unsigned M,typename U> friend class FixedPoolAllocator ;
00116
00117 public:
00118
00119 typedef FixedPoolBuffer<NBYTE> buffer_type ;
00120
00121 typedef T value_type;
00122 typedef std::size_t size_type;
00123 typedef T* pointer;
00124 typedef const T* const_pointer;
00125 typedef T& reference;
00126 typedef const T& const_reference;
00127 typedef std::ptrdiff_t difference_type;
00128
00129 pointer address( reference value ) const { return & value ; }
00130 const_pointer address( const_reference value ) const { return & value ; }
00131
00132 ~FixedPoolAllocator() {}
00133
00134 FixedPoolAllocator() : buffer(NULL) {}
00135
00136 FixedPoolAllocator( const FixedPoolAllocator<NBYTE,T> & a )
00137 : buffer(a.buffer) {}
00138
00139 explicit FixedPoolAllocator( buffer_type & b ) : buffer( & b ) {}
00140
00141 template<typename U>
00142 struct rebind { typedef FixedPoolAllocator<NBYTE,U> other ; };
00143
00144 template<typename U>
00145 FixedPoolAllocator( const FixedPoolAllocator<NBYTE,U> & a )
00146 : buffer(a.buffer) {}
00147
00148 pointer allocate( size_type n , const void * = NULL )
00149 { return reinterpret_cast<pointer>( buffer->allocate( n * sizeof(T) ) ); }
00150
00151 void deallocate( pointer p , size_type n )
00152 { buffer->deallocate(p, n * sizeof(T) ); }
00153
00154 void construct( pointer p , const T & val ) { new(p) T(val); }
00155 void destroy( pointer p ) { p->~T(); }
00156
00157 template<typename U>
00158 void construct( U * p , const U & val ) { new(p) U(val); }
00159
00160 template<typename U>
00161 void destroy( U * p ) { p->~U(); }
00162
00163 size_type max_size() const { return NBYTE / sizeof(T) ; }
00164 };
00165
00166 template<unsigned NBYTE,typename T>
00167 bool operator == ( const FixedPoolAllocator<NBYTE,T> & lhs ,
00168 const FixedPoolAllocator<NBYTE,T> & rhs )
00169 { return lhs.buffer == rhs.buffer ; }
00170
00171 template<unsigned NBYTE,typename T>
00172 bool operator != ( const FixedPoolAllocator<NBYTE,T> & lhs ,
00173 const FixedPoolAllocator<NBYTE,T> & rhs )
00174 { return lhs.buffer != rhs.buffer ; }
00175
00176 }
00177
00178 #endif
00179