|
phdMesh Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* phdMesh : Parallel Heterogneous Dynamic unstructured Mesh */ 00003 /* Copyright (2007) Sandia Corporation */ 00004 /* */ 00005 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00006 /* license for use of this work by or on behalf of the U.S. Government. */ 00007 /* */ 00008 /* This library is free software; you can redistribute it and/or modify */ 00009 /* it under the terms of the GNU Lesser General Public License as */ 00010 /* published by the Free Software Foundation; either version 2.1 of the */ 00011 /* License, or (at your option) any later version. */ 00012 /* */ 00013 /* This library is distributed in the hope that it will be useful, */ 00014 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 00015 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ 00016 /* Lesser General Public License for more details. */ 00017 /* */ 00018 /* You should have received a copy of the GNU Lesser General Public */ 00019 /* License along with this library; if not, write to the Free Software */ 00020 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ 00021 /* USA */ 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 ) { // Initialize on the first call 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
1.7.4