Chris@16
|
1 // Copyright (C) 2000, 2001 Stephen Cleary
|
Chris@16
|
2 // Copyright (C) 2010 Paul A. Bristow added Doxygen comments.
|
Chris@16
|
3 //
|
Chris@16
|
4 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
5 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 //
|
Chris@16
|
8 // See http://www.boost.org for updates, documentation, and revision history.
|
Chris@16
|
9
|
Chris@16
|
10 #ifndef BOOST_POOL_ALLOC_HPP
|
Chris@16
|
11 #define BOOST_POOL_ALLOC_HPP
|
Chris@16
|
12
|
Chris@16
|
13 /*!
|
Chris@16
|
14 \file
|
Chris@16
|
15 \brief C++ Standard Library compatible pool-based allocators.
|
Chris@16
|
16 \details This header provides two template types -
|
Chris@16
|
17 \ref pool_allocator and \ref fast_pool_allocator -
|
Chris@16
|
18 that can be used for fast and efficient memory allocation
|
Chris@16
|
19 in conjunction with the C++ Standard Library containers.
|
Chris@16
|
20
|
Chris@16
|
21 These types both satisfy the Standard Allocator requirements [20.1.5]
|
Chris@16
|
22 and the additional requirements in [20.1.5/4],
|
Chris@16
|
23 so they can be used with either Standard or user-supplied containers.
|
Chris@16
|
24
|
Chris@16
|
25 In addition, the fast_pool_allocator also provides an additional allocation
|
Chris@16
|
26 and an additional deallocation function:
|
Chris@16
|
27
|
Chris@16
|
28 <table>
|
Chris@16
|
29 <tr><th>Expression</th><th>Return Type</th><th>Semantic Equivalence<th></tr>
|
Chris@16
|
30 <tr><td><tt>PoolAlloc::allocate()</tt></td><td><tt>T *</tt></td><td><tt>PoolAlloc::allocate(1)</tt></tr>
|
Chris@16
|
31 <tr><td><tt>PoolAlloc::deallocate(p)</tt></td><td>void</tt></td><td><tt>PoolAlloc::deallocate(p, 1)</tt></tr>
|
Chris@16
|
32 </table>
|
Chris@16
|
33
|
Chris@16
|
34 The typedef user_allocator publishes the value of the UserAllocator template parameter.
|
Chris@16
|
35
|
Chris@16
|
36 <b>Notes</b>
|
Chris@16
|
37
|
Chris@16
|
38 If the allocation functions run out of memory, they will throw <tt>std::bad_alloc</tt>.
|
Chris@16
|
39
|
Chris@16
|
40 The underlying Pool type used by the allocators is accessible through the Singleton Pool Interface.
|
Chris@16
|
41 The identifying tag used for pool_allocator is pool_allocator_tag,
|
Chris@16
|
42 and the tag used for fast_pool_allocator is fast_pool_allocator_tag.
|
Chris@16
|
43 All template parameters of the allocators (including implementation-specific ones)
|
Chris@16
|
44 determine the type of the underlying Pool,
|
Chris@16
|
45 with the exception of the first parameter T, whose size is used instead.
|
Chris@16
|
46
|
Chris@16
|
47 Since the size of T is used to determine the type of the underlying Pool,
|
Chris@16
|
48 each allocator for different types of the same size will share the same underlying pool.
|
Chris@16
|
49 The tag class prevents pools from being shared between pool_allocator and fast_pool_allocator.
|
Chris@16
|
50 For example, on a system where
|
Chris@16
|
51 <tt>sizeof(int) == sizeof(void *)</tt>, <tt>pool_allocator<int></tt> and <tt>pool_allocator<void *></tt>
|
Chris@16
|
52 will both allocate/deallocate from/to the same pool.
|
Chris@16
|
53
|
Chris@16
|
54 If there is only one thread running before main() starts and after main() ends,
|
Chris@16
|
55 then both allocators are completely thread-safe.
|
Chris@16
|
56
|
Chris@16
|
57 <b>Compiler and STL Notes</b>
|
Chris@16
|
58
|
Chris@16
|
59 A number of common STL libraries contain bugs in their using of allocators.
|
Chris@16
|
60 Specifically, they pass null pointers to the deallocate function,
|
Chris@16
|
61 which is explicitly forbidden by the Standard [20.1.5 Table 32].
|
Chris@16
|
62 PoolAlloc will work around these libraries if it detects them;
|
Chris@16
|
63 currently, workarounds are in place for:
|
Chris@16
|
64 Borland C++ (Builder and command-line compiler)
|
Chris@16
|
65 with default (RogueWave) library, ver. 5 and earlier,
|
Chris@16
|
66 STLport (with any compiler), ver. 4.0 and earlier.
|
Chris@16
|
67 */
|
Chris@16
|
68
|
Chris@16
|
69 // std::numeric_limits
|
Chris@16
|
70 #include <boost/limits.hpp>
|
Chris@16
|
71 // new, std::bad_alloc
|
Chris@16
|
72 #include <new>
|
Chris@16
|
73
|
Chris@16
|
74 #include <boost/throw_exception.hpp>
|
Chris@16
|
75 #include <boost/pool/poolfwd.hpp>
|
Chris@16
|
76
|
Chris@16
|
77 // boost::singleton_pool
|
Chris@16
|
78 #include <boost/pool/singleton_pool.hpp>
|
Chris@16
|
79
|
Chris@16
|
80 #include <boost/detail/workaround.hpp>
|
Chris@16
|
81
|
Chris@16
|
82 #ifdef BOOST_POOL_INSTRUMENT
|
Chris@16
|
83 #include <iostream>
|
Chris@16
|
84 #include <iomanip>
|
Chris@16
|
85 #endif
|
Chris@16
|
86
|
Chris@16
|
87 // The following code will be put into Boost.Config in a later revision
|
Chris@16
|
88 #if defined(_RWSTD_VER) || defined(__SGI_STL_PORT) || \
|
Chris@16
|
89 BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
Chris@16
|
90 #define BOOST_NO_PROPER_STL_DEALLOCATE
|
Chris@16
|
91 #endif
|
Chris@16
|
92
|
Chris@16
|
93 namespace boost {
|
Chris@16
|
94
|
Chris@16
|
95 #ifdef BOOST_POOL_INSTRUMENT
|
Chris@16
|
96
|
Chris@16
|
97 template <bool b>
|
Chris@16
|
98 struct debug_info
|
Chris@16
|
99 {
|
Chris@16
|
100 static unsigned allocated;
|
Chris@16
|
101 };
|
Chris@16
|
102
|
Chris@16
|
103 template <bool b>
|
Chris@16
|
104 unsigned debug_info<b>::allocated = 0;
|
Chris@16
|
105
|
Chris@16
|
106 #endif
|
Chris@16
|
107
|
Chris@16
|
108 //! Simple tag type used by pool_allocator as an argument to the
|
Chris@16
|
109 //! underlying singleton_pool.
|
Chris@16
|
110 struct pool_allocator_tag
|
Chris@16
|
111 {
|
Chris@16
|
112 };
|
Chris@16
|
113
|
Chris@16
|
114 /*! \brief A C++ Standard Library conforming allocator, based on an underlying pool.
|
Chris@16
|
115
|
Chris@16
|
116 Template parameters for pool_allocator are defined as follows:
|
Chris@16
|
117
|
Chris@16
|
118 <b>T</b> Type of object to allocate/deallocate.
|
Chris@16
|
119
|
Chris@16
|
120 <b>UserAllocator</B>. Defines the method that the underlying Pool will use to allocate memory from the system. See
|
Chris@16
|
121 <a href="boost_pool/pool/pooling.html#boost_pool.pool.pooling.user_allocator">User Allocators</a> for details.
|
Chris@16
|
122
|
Chris@16
|
123 <b>Mutex</b> Allows the user to determine the type of synchronization to be used on the underlying singleton_pool.
|
Chris@16
|
124
|
Chris@16
|
125 <b>NextSize</b> The value of this parameter is passed to the underlying singleton_pool when it is created.
|
Chris@16
|
126
|
Chris@16
|
127 <b>MaxSize</b> Limit on the maximum size used.
|
Chris@16
|
128
|
Chris@16
|
129 \attention
|
Chris@16
|
130 The underlying singleton_pool used by the this allocator
|
Chris@16
|
131 constructs a pool instance that
|
Chris@16
|
132 <b>is never freed</b>. This means that memory allocated
|
Chris@16
|
133 by the allocator can be still used after main() has
|
Chris@16
|
134 completed, but may mean that some memory checking programs
|
Chris@16
|
135 will complain about leaks.
|
Chris@16
|
136
|
Chris@16
|
137
|
Chris@16
|
138 */
|
Chris@16
|
139 template <typename T,
|
Chris@16
|
140 typename UserAllocator,
|
Chris@16
|
141 typename Mutex,
|
Chris@16
|
142 unsigned NextSize,
|
Chris@16
|
143 unsigned MaxSize >
|
Chris@16
|
144 class pool_allocator
|
Chris@16
|
145 {
|
Chris@16
|
146 public:
|
Chris@16
|
147 typedef T value_type; //!< value_type of template parameter T.
|
Chris@16
|
148 typedef UserAllocator user_allocator; //!< allocator that defines the method that the underlying Pool will use to allocate memory from the system.
|
Chris@16
|
149 typedef Mutex mutex; //!< typedef mutex publishes the value of the template parameter Mutex.
|
Chris@16
|
150 BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize); //!< next_size publishes the values of the template parameter NextSize.
|
Chris@16
|
151
|
Chris@16
|
152 typedef value_type * pointer; //!<
|
Chris@16
|
153 typedef const value_type * const_pointer;
|
Chris@16
|
154 typedef value_type & reference;
|
Chris@16
|
155 typedef const value_type & const_reference;
|
Chris@16
|
156 typedef typename pool<UserAllocator>::size_type size_type;
|
Chris@16
|
157 typedef typename pool<UserAllocator>::difference_type difference_type;
|
Chris@16
|
158
|
Chris@16
|
159 //! \brief Nested class rebind allows for transformation from
|
Chris@16
|
160 //! pool_allocator<T> to pool_allocator<U>.
|
Chris@16
|
161 //!
|
Chris@16
|
162 //! Nested class rebind allows for transformation from
|
Chris@16
|
163 //! pool_allocator<T> to pool_allocator<U> via the member
|
Chris@16
|
164 //! typedef other.
|
Chris@16
|
165 template <typename U>
|
Chris@16
|
166 struct rebind
|
Chris@16
|
167 { //
|
Chris@16
|
168 typedef pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
|
Chris@16
|
169 };
|
Chris@16
|
170
|
Chris@16
|
171 public:
|
Chris@16
|
172 pool_allocator()
|
Chris@16
|
173 { /*! Results in default construction of the underlying singleton_pool IFF an
|
Chris@16
|
174 instance of this allocator is constructed during global initialization (
|
Chris@16
|
175 required to ensure construction of singleton_pool IFF an
|
Chris@16
|
176 instance of this allocator is constructed during global
|
Chris@16
|
177 initialization. See ticket #2359 for a complete explanation at
|
Chris@16
|
178 http://svn.boost.org/trac/boost/ticket/2359) .
|
Chris@16
|
179 */
|
Chris@16
|
180 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
|
Chris@16
|
181 NextSize, MaxSize>::is_from(0);
|
Chris@16
|
182 }
|
Chris@16
|
183
|
Chris@16
|
184 // default copy constructor.
|
Chris@16
|
185
|
Chris@16
|
186 // default assignment operator.
|
Chris@16
|
187
|
Chris@16
|
188 // not explicit, mimicking std::allocator [20.4.1]
|
Chris@16
|
189 template <typename U>
|
Chris@16
|
190 pool_allocator(const pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &)
|
Chris@16
|
191 { /*! Results in the default construction of the underlying singleton_pool, this
|
Chris@16
|
192 is required to ensure construction of singleton_pool IFF an
|
Chris@16
|
193 instance of this allocator is constructed during global
|
Chris@16
|
194 initialization. See ticket #2359 for a complete explanation
|
Chris@16
|
195 at http://svn.boost.org/trac/boost/ticket/2359 .
|
Chris@16
|
196 */
|
Chris@16
|
197 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
|
Chris@16
|
198 NextSize, MaxSize>::is_from(0);
|
Chris@16
|
199 }
|
Chris@16
|
200
|
Chris@16
|
201 // default destructor
|
Chris@16
|
202
|
Chris@16
|
203 static pointer address(reference r)
|
Chris@16
|
204 { return &r; }
|
Chris@16
|
205 static const_pointer address(const_reference s)
|
Chris@16
|
206 { return &s; }
|
Chris@16
|
207 static size_type max_size()
|
Chris@16
|
208 { return (std::numeric_limits<size_type>::max)(); }
|
Chris@16
|
209 static void construct(const pointer ptr, const value_type & t)
|
Chris@16
|
210 { new (ptr) T(t); }
|
Chris@16
|
211 static void destroy(const pointer ptr)
|
Chris@16
|
212 {
|
Chris@16
|
213 ptr->~T();
|
Chris@16
|
214 (void) ptr; // avoid unused variable warning.
|
Chris@16
|
215 }
|
Chris@16
|
216
|
Chris@16
|
217 bool operator==(const pool_allocator &) const
|
Chris@16
|
218 { return true; }
|
Chris@16
|
219 bool operator!=(const pool_allocator &) const
|
Chris@16
|
220 { return false; }
|
Chris@16
|
221
|
Chris@16
|
222 static pointer allocate(const size_type n)
|
Chris@16
|
223 {
|
Chris@16
|
224 #ifdef BOOST_POOL_INSTRUMENT
|
Chris@16
|
225 debug_info<true>::allocated += n * sizeof(T);
|
Chris@16
|
226 std::cout << "Allocating " << n << " * " << sizeof(T) << " bytes...\n"
|
Chris@16
|
227 "Total allocated is now " << debug_info<true>::allocated << std::endl;
|
Chris@16
|
228 #endif
|
Chris@16
|
229 const pointer ret = static_cast<pointer>(
|
Chris@16
|
230 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
|
Chris@16
|
231 NextSize, MaxSize>::ordered_malloc(n) );
|
Chris@16
|
232 if ((ret == 0) && n)
|
Chris@16
|
233 boost::throw_exception(std::bad_alloc());
|
Chris@16
|
234 return ret;
|
Chris@16
|
235 }
|
Chris@16
|
236 static pointer allocate(const size_type n, const void * const)
|
Chris@16
|
237 { //! allocate n bytes
|
Chris@16
|
238 //! \param n bytes to allocate.
|
Chris@16
|
239 //! \param unused.
|
Chris@16
|
240 return allocate(n);
|
Chris@16
|
241 }
|
Chris@16
|
242 static void deallocate(const pointer ptr, const size_type n)
|
Chris@16
|
243 { //! Deallocate n bytes from ptr
|
Chris@16
|
244 //! \param ptr location to deallocate from.
|
Chris@16
|
245 //! \param n number of bytes to deallocate.
|
Chris@16
|
246 #ifdef BOOST_POOL_INSTRUMENT
|
Chris@16
|
247 debug_info<true>::allocated -= n * sizeof(T);
|
Chris@16
|
248 std::cout << "Deallocating " << n << " * " << sizeof(T) << " bytes...\n"
|
Chris@16
|
249 "Total allocated is now " << debug_info<true>::allocated << std::endl;
|
Chris@16
|
250 #endif
|
Chris@16
|
251 #ifdef BOOST_NO_PROPER_STL_DEALLOCATE
|
Chris@16
|
252 if (ptr == 0 || n == 0)
|
Chris@16
|
253 return;
|
Chris@16
|
254 #endif
|
Chris@16
|
255 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
|
Chris@16
|
256 NextSize, MaxSize>::ordered_free(ptr, n);
|
Chris@16
|
257 }
|
Chris@16
|
258 };
|
Chris@16
|
259
|
Chris@16
|
260 /*! \brief Specialization of pool_allocator<void>.
|
Chris@16
|
261
|
Chris@16
|
262 Specialization of pool_allocator for type void: required by the standard to make this a conforming allocator type.
|
Chris@16
|
263 */
|
Chris@16
|
264 template<
|
Chris@16
|
265 typename UserAllocator,
|
Chris@16
|
266 typename Mutex,
|
Chris@16
|
267 unsigned NextSize,
|
Chris@16
|
268 unsigned MaxSize>
|
Chris@16
|
269 class pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>
|
Chris@16
|
270 {
|
Chris@16
|
271 public:
|
Chris@16
|
272 typedef void* pointer;
|
Chris@16
|
273 typedef const void* const_pointer;
|
Chris@16
|
274 typedef void value_type;
|
Chris@16
|
275 //! \brief Nested class rebind allows for transformation from
|
Chris@16
|
276 //! pool_allocator<T> to pool_allocator<U>.
|
Chris@16
|
277 //!
|
Chris@16
|
278 //! Nested class rebind allows for transformation from
|
Chris@16
|
279 //! pool_allocator<T> to pool_allocator<U> via the member
|
Chris@16
|
280 //! typedef other.
|
Chris@16
|
281 template <class U>
|
Chris@16
|
282 struct rebind
|
Chris@16
|
283 {
|
Chris@16
|
284 typedef pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
|
Chris@16
|
285 };
|
Chris@16
|
286 };
|
Chris@16
|
287
|
Chris@16
|
288 //! Simple tag type used by fast_pool_allocator as a template parameter to the underlying singleton_pool.
|
Chris@16
|
289 struct fast_pool_allocator_tag
|
Chris@16
|
290 {
|
Chris@16
|
291 };
|
Chris@16
|
292
|
Chris@16
|
293 /*! \brief A C++ Standard Library conforming allocator geared towards allocating single chunks.
|
Chris@16
|
294
|
Chris@16
|
295 While class template <tt>pool_allocator</tt> is a more general-purpose solution geared towards
|
Chris@16
|
296 efficiently servicing requests for any number of contiguous chunks,
|
Chris@16
|
297 <tt>fast_pool_allocator</tt> is also a general-purpose solution,
|
Chris@16
|
298 but is geared towards efficiently servicing requests for one chunk at a time;
|
Chris@16
|
299 it will work for contiguous chunks, but not as well as <tt>pool_allocator</tt>.
|
Chris@16
|
300
|
Chris@16
|
301 If you are seriously concerned about performance,
|
Chris@16
|
302 use <tt>fast_pool_allocator</tt> when dealing with containers such as <tt>std::list</tt>,
|
Chris@16
|
303 and use <tt>pool_allocator</tt> when dealing with containers such as <tt>std::vector</tt>.
|
Chris@16
|
304
|
Chris@16
|
305 The template parameters are defined as follows:
|
Chris@16
|
306
|
Chris@16
|
307 <b>T</b> Type of object to allocate/deallocate.
|
Chris@16
|
308
|
Chris@16
|
309 <b>UserAllocator</b>. Defines the method that the underlying Pool will use to allocate memory from the system.
|
Chris@16
|
310 See <a href="boost_pool/pool/pooling.html#boost_pool.pool.pooling.user_allocator">User Allocators</a> for details.
|
Chris@16
|
311
|
Chris@16
|
312 <b>Mutex</b> Allows the user to determine the type of synchronization to be used on the underlying <tt>singleton_pool</tt>.
|
Chris@16
|
313
|
Chris@16
|
314 <b>NextSize</b> The value of this parameter is passed to the underlying Pool when it is created.
|
Chris@16
|
315
|
Chris@16
|
316 <b>MaxSize</b> Limit on the maximum size used.
|
Chris@16
|
317
|
Chris@16
|
318 \attention
|
Chris@16
|
319 The underlying singleton_pool used by the this allocator
|
Chris@16
|
320 constructs a pool instance that
|
Chris@16
|
321 <b>is never freed</b>. This means that memory allocated
|
Chris@16
|
322 by the allocator can be still used after main() has
|
Chris@16
|
323 completed, but may mean that some memory checking programs
|
Chris@16
|
324 will complain about leaks.
|
Chris@16
|
325
|
Chris@16
|
326 */
|
Chris@16
|
327
|
Chris@16
|
328 template <typename T,
|
Chris@16
|
329 typename UserAllocator,
|
Chris@16
|
330 typename Mutex,
|
Chris@16
|
331 unsigned NextSize,
|
Chris@16
|
332 unsigned MaxSize >
|
Chris@16
|
333 class fast_pool_allocator
|
Chris@16
|
334 {
|
Chris@16
|
335 public:
|
Chris@16
|
336 typedef T value_type;
|
Chris@16
|
337 typedef UserAllocator user_allocator;
|
Chris@16
|
338 typedef Mutex mutex;
|
Chris@16
|
339 BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize);
|
Chris@16
|
340
|
Chris@16
|
341 typedef value_type * pointer;
|
Chris@16
|
342 typedef const value_type * const_pointer;
|
Chris@16
|
343 typedef value_type & reference;
|
Chris@16
|
344 typedef const value_type & const_reference;
|
Chris@16
|
345 typedef typename pool<UserAllocator>::size_type size_type;
|
Chris@16
|
346 typedef typename pool<UserAllocator>::difference_type difference_type;
|
Chris@16
|
347
|
Chris@16
|
348 //! \brief Nested class rebind allows for transformation from
|
Chris@16
|
349 //! fast_pool_allocator<T> to fast_pool_allocator<U>.
|
Chris@16
|
350 //!
|
Chris@16
|
351 //! Nested class rebind allows for transformation from
|
Chris@16
|
352 //! fast_pool_allocator<T> to fast_pool_allocator<U> via the member
|
Chris@16
|
353 //! typedef other.
|
Chris@16
|
354 template <typename U>
|
Chris@16
|
355 struct rebind
|
Chris@16
|
356 {
|
Chris@16
|
357 typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
|
Chris@16
|
358 };
|
Chris@16
|
359
|
Chris@16
|
360 public:
|
Chris@16
|
361 fast_pool_allocator()
|
Chris@16
|
362 {
|
Chris@16
|
363 //! Ensures construction of the underlying singleton_pool IFF an
|
Chris@16
|
364 //! instance of this allocator is constructed during global
|
Chris@16
|
365 //! initialization. See ticket #2359 for a complete explanation
|
Chris@16
|
366 //! at http://svn.boost.org/trac/boost/ticket/2359 .
|
Chris@16
|
367 singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
Chris@16
|
368 UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
|
Chris@16
|
369 }
|
Chris@16
|
370
|
Chris@16
|
371 // Default copy constructor used.
|
Chris@16
|
372
|
Chris@16
|
373 // Default assignment operator used.
|
Chris@16
|
374
|
Chris@16
|
375 // Not explicit, mimicking std::allocator [20.4.1]
|
Chris@16
|
376 template <typename U>
|
Chris@16
|
377 fast_pool_allocator(
|
Chris@16
|
378 const fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &)
|
Chris@16
|
379 {
|
Chris@16
|
380 //! Ensures construction of the underlying singleton_pool IFF an
|
Chris@16
|
381 //! instance of this allocator is constructed during global
|
Chris@16
|
382 //! initialization. See ticket #2359 for a complete explanation
|
Chris@16
|
383 //! at http://svn.boost.org/trac/boost/ticket/2359 .
|
Chris@16
|
384 singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
Chris@16
|
385 UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
|
Chris@16
|
386 }
|
Chris@16
|
387
|
Chris@16
|
388 // Default destructor used.
|
Chris@16
|
389
|
Chris@16
|
390 static pointer address(reference r)
|
Chris@16
|
391 {
|
Chris@16
|
392 return &r;
|
Chris@16
|
393 }
|
Chris@16
|
394 static const_pointer address(const_reference s)
|
Chris@16
|
395 { return &s; }
|
Chris@16
|
396 static size_type max_size()
|
Chris@16
|
397 { return (std::numeric_limits<size_type>::max)(); }
|
Chris@16
|
398 void construct(const pointer ptr, const value_type & t)
|
Chris@16
|
399 { new (ptr) T(t); }
|
Chris@16
|
400 void destroy(const pointer ptr)
|
Chris@16
|
401 { //! Destroy ptr using destructor.
|
Chris@16
|
402 ptr->~T();
|
Chris@16
|
403 (void) ptr; // Avoid unused variable warning.
|
Chris@16
|
404 }
|
Chris@16
|
405
|
Chris@16
|
406 bool operator==(const fast_pool_allocator &) const
|
Chris@16
|
407 { return true; }
|
Chris@16
|
408 bool operator!=(const fast_pool_allocator &) const
|
Chris@16
|
409 { return false; }
|
Chris@16
|
410
|
Chris@16
|
411 static pointer allocate(const size_type n)
|
Chris@16
|
412 {
|
Chris@16
|
413 const pointer ret = (n == 1) ?
|
Chris@16
|
414 static_cast<pointer>(
|
Chris@16
|
415 (singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
Chris@16
|
416 UserAllocator, Mutex, NextSize, MaxSize>::malloc)() ) :
|
Chris@16
|
417 static_cast<pointer>(
|
Chris@16
|
418 singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
Chris@16
|
419 UserAllocator, Mutex, NextSize, MaxSize>::ordered_malloc(n) );
|
Chris@16
|
420 if (ret == 0)
|
Chris@16
|
421 boost::throw_exception(std::bad_alloc());
|
Chris@16
|
422 return ret;
|
Chris@16
|
423 }
|
Chris@16
|
424 static pointer allocate(const size_type n, const void * const)
|
Chris@16
|
425 { //! Allocate memory .
|
Chris@16
|
426 return allocate(n);
|
Chris@16
|
427 }
|
Chris@16
|
428 static pointer allocate()
|
Chris@16
|
429 { //! Allocate memory.
|
Chris@16
|
430 const pointer ret = static_cast<pointer>(
|
Chris@16
|
431 (singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
Chris@16
|
432 UserAllocator, Mutex, NextSize, MaxSize>::malloc)() );
|
Chris@16
|
433 if (ret == 0)
|
Chris@16
|
434 boost::throw_exception(std::bad_alloc());
|
Chris@16
|
435 return ret;
|
Chris@16
|
436 }
|
Chris@16
|
437 static void deallocate(const pointer ptr, const size_type n)
|
Chris@16
|
438 { //! Deallocate memory.
|
Chris@16
|
439
|
Chris@16
|
440 #ifdef BOOST_NO_PROPER_STL_DEALLOCATE
|
Chris@16
|
441 if (ptr == 0 || n == 0)
|
Chris@16
|
442 return;
|
Chris@16
|
443 #endif
|
Chris@16
|
444 if (n == 1)
|
Chris@16
|
445 (singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
Chris@16
|
446 UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr);
|
Chris@16
|
447 else
|
Chris@16
|
448 (singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
Chris@16
|
449 UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr, n);
|
Chris@16
|
450 }
|
Chris@16
|
451 static void deallocate(const pointer ptr)
|
Chris@16
|
452 { //! deallocate/free
|
Chris@16
|
453 (singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
Chris@16
|
454 UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr);
|
Chris@16
|
455 }
|
Chris@16
|
456 };
|
Chris@16
|
457
|
Chris@16
|
458 /*! \brief Specialization of fast_pool_allocator<void>.
|
Chris@16
|
459
|
Chris@16
|
460 Specialization of fast_pool_allocator<void> required to make the allocator standard-conforming.
|
Chris@16
|
461 */
|
Chris@16
|
462 template<
|
Chris@16
|
463 typename UserAllocator,
|
Chris@16
|
464 typename Mutex,
|
Chris@16
|
465 unsigned NextSize,
|
Chris@16
|
466 unsigned MaxSize >
|
Chris@16
|
467 class fast_pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>
|
Chris@16
|
468 {
|
Chris@16
|
469 public:
|
Chris@16
|
470 typedef void* pointer;
|
Chris@16
|
471 typedef const void* const_pointer;
|
Chris@16
|
472 typedef void value_type;
|
Chris@16
|
473
|
Chris@16
|
474 //! \brief Nested class rebind allows for transformation from
|
Chris@16
|
475 //! fast_pool_allocator<T> to fast_pool_allocator<U>.
|
Chris@16
|
476 //!
|
Chris@16
|
477 //! Nested class rebind allows for transformation from
|
Chris@16
|
478 //! fast_pool_allocator<T> to fast_pool_allocator<U> via the member
|
Chris@16
|
479 //! typedef other.
|
Chris@16
|
480 template <class U> struct rebind
|
Chris@16
|
481 {
|
Chris@16
|
482 typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
|
Chris@16
|
483 };
|
Chris@16
|
484 };
|
Chris@16
|
485
|
Chris@16
|
486 } // namespace boost
|
Chris@16
|
487
|
Chris@16
|
488 #endif
|