1 // Copyright (C) 2000, 2001 Stephen Cleary 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See 4 // accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 // 7 // See http://www.boost.org for updates, documentation, and revision history. 8 9 #ifndef BOOST_POOL_ALLOC_HPP 10 #define BOOST_POOL_ALLOC_HPP 11 12 // std::numeric_limits 13 #include <boost/limits.hpp> 14 // new, std::bad_alloc 15 #include <new> 16 17 #include <boost/pool/poolfwd.hpp> 18 19 // boost::singleton_pool 20 #include <boost/pool/singleton_pool.hpp> 21 22 // The following code will be put into Boost.Config in a later revision 23 #if defined(_RWSTD_VER) || defined(__SGI_STL_PORT) 24 // Needed, as of bcc 5.5 and STLPort 4.5b8 25 #define BOOST_NO_PROPER_STL_DEALLOCATE 26 #endif 27 28 namespace boost { 29 30 struct pool_allocator_tag { }; 31 32 template <typename T, 33 typename UserAllocator, 34 typename Mutex, 35 unsigned NextSize> 36 class pool_allocator 37 { 38 public: 39 typedef T value_type; 40 typedef UserAllocator user_allocator; 41 typedef Mutex mutex; 42 BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize); 43 44 typedef value_type * pointer; 45 typedef const value_type * const_pointer; 46 typedef value_type & reference; 47 typedef const value_type & const_reference; 48 typedef typename pool<UserAllocator>::size_type size_type; 49 typedef typename pool<UserAllocator>::difference_type difference_type; 50 51 template <typename U> 52 struct rebind 53 { 54 typedef pool_allocator<U, UserAllocator, Mutex, NextSize> other; 55 }; 56 57 public: pool_allocator()58 pool_allocator() { } 59 60 // default copy constructor 61 62 // default assignment operator 63 64 // not explicit, mimicking std::allocator [20.4.1] 65 template <typename U> pool_allocator(const pool_allocator<U,UserAllocator,Mutex,NextSize> &)66 pool_allocator(const pool_allocator<U, UserAllocator, Mutex, NextSize> &) 67 { } 68 69 // default destructor 70 address(reference r)71 static pointer address(reference r) 72 { return &r; } address(const_reference s)73 static const_pointer address(const_reference s) 74 { return &s; } max_size()75 static size_type max_size() 76 { return (std::numeric_limits<size_type>::max)(); } construct(const pointer ptr,const value_type & t)77 static void construct(const pointer ptr, const value_type & t) 78 { new (ptr) T(t); } destroy(const pointer ptr)79 static void destroy(const pointer ptr) 80 { 81 ptr->~T(); 82 (void) ptr; // avoid unused variable warning 83 } 84 operator ==(const pool_allocator &) const85 bool operator==(const pool_allocator &) const 86 { return true; } operator !=(const pool_allocator &) const87 bool operator!=(const pool_allocator &) const 88 { return false; } 89 allocate(const size_type n)90 static pointer allocate(const size_type n) 91 { 92 const pointer ret = static_cast<pointer>( 93 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex, 94 NextSize>::ordered_malloc(n) ); 95 if (ret == 0) 96 throw std::bad_alloc(); 97 return ret; 98 } allocate(const size_type n,const void * const)99 static pointer allocate(const size_type n, const void * const) 100 { return allocate(n); } deallocate(const pointer ptr,const size_type n)101 static void deallocate(const pointer ptr, const size_type n) 102 { 103 #ifdef BOOST_NO_PROPER_STL_DEALLOCATE 104 if (ptr == 0 || n == 0) 105 return; 106 #endif 107 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex, 108 NextSize>::ordered_free(ptr, n); 109 } 110 }; 111 112 struct fast_pool_allocator_tag { }; 113 114 template <typename T, 115 typename UserAllocator, 116 typename Mutex, 117 unsigned NextSize> 118 class fast_pool_allocator 119 { 120 public: 121 typedef T value_type; 122 typedef UserAllocator user_allocator; 123 typedef Mutex mutex; 124 BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize); 125 126 typedef value_type * pointer; 127 typedef const value_type * const_pointer; 128 typedef value_type & reference; 129 typedef const value_type & const_reference; 130 typedef typename pool<UserAllocator>::size_type size_type; 131 typedef typename pool<UserAllocator>::difference_type difference_type; 132 133 template <typename U> 134 struct rebind 135 { 136 typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize> other; 137 }; 138 139 public: fast_pool_allocator()140 fast_pool_allocator() { } 141 142 // default copy constructor 143 144 // default assignment operator 145 146 // not explicit, mimicking std::allocator [20.4.1] 147 template <typename U> fast_pool_allocator(const fast_pool_allocator<U,UserAllocator,Mutex,NextSize> &)148 fast_pool_allocator( 149 const fast_pool_allocator<U, UserAllocator, Mutex, NextSize> &) 150 { } 151 152 // default destructor 153 address(reference r)154 static pointer address(reference r) 155 { return &r; } address(const_reference s)156 static const_pointer address(const_reference s) 157 { return &s; } max_size()158 static size_type max_size() 159 { return (std::numeric_limits<size_type>::max)(); } construct(const pointer ptr,const value_type & t)160 void construct(const pointer ptr, const value_type & t) 161 { new (ptr) T(t); } destroy(const pointer ptr)162 void destroy(const pointer ptr) 163 { 164 ptr->~T(); 165 (void) ptr; // avoid unused variable warning 166 } 167 operator ==(const fast_pool_allocator &) const168 bool operator==(const fast_pool_allocator &) const 169 { return true; } operator !=(const fast_pool_allocator &) const170 bool operator!=(const fast_pool_allocator &) const 171 { return false; } 172 allocate(const size_type n)173 static pointer allocate(const size_type n) 174 { 175 const pointer ret = (n == 1) ? 176 static_cast<pointer>( 177 singleton_pool<fast_pool_allocator_tag, sizeof(T), 178 UserAllocator, Mutex, NextSize>::malloc() ) : 179 static_cast<pointer>( 180 singleton_pool<fast_pool_allocator_tag, sizeof(T), 181 UserAllocator, Mutex, NextSize>::ordered_malloc(n) ); 182 if (ret == 0) 183 throw std::bad_alloc(); 184 return ret; 185 } allocate(const size_type n,const void * const)186 static pointer allocate(const size_type n, const void * const) 187 { return allocate(n); } allocate()188 static pointer allocate() 189 { 190 const pointer ret = static_cast<pointer>( 191 singleton_pool<fast_pool_allocator_tag, sizeof(T), 192 UserAllocator, Mutex, NextSize>::malloc() ); 193 if (ret == 0) 194 throw std::bad_alloc(); 195 return ret; 196 } deallocate(const pointer ptr,const size_type n)197 static void deallocate(const pointer ptr, const size_type n) 198 { 199 #ifdef BOOST_NO_PROPER_STL_DEALLOCATE 200 if (ptr == 0 || n == 0) 201 return; 202 #endif 203 if (n == 1) 204 singleton_pool<fast_pool_allocator_tag, sizeof(T), 205 UserAllocator, Mutex, NextSize>::free(ptr); 206 else 207 singleton_pool<fast_pool_allocator_tag, sizeof(T), 208 UserAllocator, Mutex, NextSize>::free(ptr, n); 209 } deallocate(const pointer ptr)210 static void deallocate(const pointer ptr) 211 { 212 singleton_pool<fast_pool_allocator_tag, sizeof(T), 213 UserAllocator, Mutex, NextSize>::free(ptr); 214 } 215 }; 216 217 } // namespace boost 218 219 #endif 220