...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
C++ Standard Library compatible pool-based allocators.
This header provides two template types - pool_allocator and fast_pool_allocator - that can be used for fast and efficient memory allocation in conjunction with the C++ Standard Library containers.
These types both satisfy the Standard Allocator requirements [20.1.5] and the additional requirements in [20.1.5/4], so they can be used with either Standard or user-supplied containers.
In addition, the fast_pool_allocator also provides an additional allocation and an additional deallocation function:
Expression | Return Type | Semantic Equivalence | |
PoolAlloc::allocate() |
T * |
PoolAlloc::allocate(1) |
|
PoolAlloc::deallocate(p) |
void |
PoolAlloc::deallocate(p, 1) |
The typedef user_allocator publishes the value of the UserAllocator template parameter.
Notes
If the allocation functions run out of memory, they will throw std::bad_alloc
.
The underlying Pool type used by the allocators is accessible through the Singleton Pool Interface. The identifying tag used for pool_allocator is pool_allocator_tag, and the tag used for fast_pool_allocator is fast_pool_allocator_tag. All template parameters of the allocators (including implementation-specific ones) determine the type of the underlying Pool, with the exception of the first parameter T, whose size is used instead.
Since the size of T is used to determine the type of the underlying Pool, each allocator for different types of the same size will share the same underlying pool. The tag class prevents pools from being shared between pool_allocator and fast_pool_allocator. For example, on a system where sizeof(int) == sizeof(void *)
, pool_allocator<int>
and pool_allocator<void *>
will both allocate/deallocate from/to the same pool.
If there is only one thread running before main() starts and after main() ends, then both allocators are completely thread-safe.
Compiler and STL Notes
A number of common STL libraries contain bugs in their using of allocators. Specifically, they pass null pointers to the deallocate function, which is explicitly forbidden by the Standard [20.1.5 Table 32]. PoolAlloc will work around these libraries if it detects them; currently, workarounds are in place for: Borland C++ (Builder and command-line compiler) with default (RogueWave) library, ver. 5 and earlier, STLport (with any compiler), ver. 4.0 and earlier.
namespace boost { template<typename T, typename UserAllocator, typename Mutex, unsigned NextSize, unsigned MaxSize> class fast_pool_allocator; template<typename UserAllocator, typename Mutex, unsigned NextSize, unsigned MaxSize> class fast_pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>; struct fast_pool_allocator_tag; template<typename T, typename UserAllocator, typename Mutex, unsigned NextSize, unsigned MaxSize> class pool_allocator; template<typename UserAllocator, typename Mutex, unsigned NextSize, unsigned MaxSize> class pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>; struct pool_allocator_tag; }