# pool_alloc - Boost Pool Standard Allocators

## Introduction

pool_alloc.hpp provides two template types that can be used for fast and efficient memory allocation. 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 Standard or user-supplied containers. For information on other pool-based interfaces, see the other pool interfaces.

## Synopsis

    struct pool_allocator_tag { };

    template <typename T,
        typename UserAllocator = default_user_allocator_new_delete>
    class pool_allocator
    {
      public:
        typedef UserAllocator user_allocator;
        typedef T value_type;
        typedef value_type * pointer;
        typedef const value_type * const_pointer;
        typedef value_type & reference;
        typedef const value_type & const_reference;
        typedef typename pool<UserAllocator>::size_type size_type;
        typedef typename pool<UserAllcoator>::difference_type difference_type;

        template <typename U>
        struct rebind
        { typedef pool_allocator<U, UserAllocator> other; };

      public:
        pool_allocator();
        pool_allocator(const pool_allocator &);
        // The following is not explicit, mimicking std::allocator [20.4.1]
        template <typename U>
        pool_allocator(const pool_allocator<U, UserAllocator> &);
        pool_allocator & operator=(const pool_allocator &);
        ~pool_allocator();

        static pointer address(reference r);
        static const_pointer address(const_reference s);
        static size_type max_size();
        static void construct(pointer ptr, const value_type & t);
        static void destroy(pointer ptr);

        bool operator==(const pool_allocator &) const;
        bool operator!=(const pool_allocator &) const;

        static pointer allocate(size_type n);
        static pointer allocate(size_type n, pointer);
        static void deallocate(pointer ptr, size_type n);
    };

    struct fast_pool_allocator_tag { };

    template <typename T
        typename UserAllocator = default_user_allocator_new_delete>
    class fast_pool_allocator
    {
      public:
        typedef UserAllocator user_allocator;
        typedef T value_type;
        typedef value_type * pointer;
        typedef const value_type * const_pointer;
        typedef value_type & reference;
        typedef const value_type & const_reference;
        typedef typename pool<UserAllocator>::size_type size_type;
        typedef typename pool<UserAllocator>::difference_type difference_type;

        template <typename U>
        struct rebind
        { typedef fast_pool_allocator<U, UserAllocator> other; };

      public:
        fast_pool_allocator();
        fast_pool_allocator(const fast_pool_allocator &);
        // The following is not explicit, mimicking std::allocator [20.4.1]
        template <typename U>
        fast_pool_allocator(const fast_pool_allocator<U, UserAllocator> &);
        fast_pool_allocator & operator=(const fast_pool_allocator &);
        ~fast_pool_allocator();

        static pointer address(reference r);
        static const_pointer address(const_reference s);
        static size_type max_size();
        static void construct(pointer ptr, const value_type & t);
        static void destroy(pointer ptr);

        bool operator==(const fast_pool_allocator &) const;
        bool operator!=(const fast_pool_allocator &) const;

        static pointer allocate(size_type n);
        static pointer allocate(size_type n, pointer);
        static void deallocate(pointer ptr, size_type n);

        static pointer allocate();
        static void deallocate(pointer ptr);
    };

## Template Parameters

### T

The first template parameter is the type of object to allocate/deallocate.

### UserAllocator

Defines the method that the underlying Pool will use to allocate memory from the system. See User Allocators for details.

## Semantics

Both of the pool allocators above satisfy all Standard Allocator requirements, as laid out in the Standard [20.1.5]. They also both satisfy the additional requirements found in [20.1.5/4]; this permits their usage with any Standard-compliant container.

In addition, the fast_pool_allocator also provides an additional allocation and an additional deallocation function:

Symbol Table
Symbol | Meaning
--- | ---
PoolAlloc | fast_pool_allocator<T, UserAllocator>
p | value of type T *

Additional allocation/deallocation functions (fast_pool_allocator only)
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.

## The Fast Pool Allocator

pool_allocator is a more general-purpose solution, geared towards efficiently servicing requests for any number of contiguous chunks. fast_pool_allocator is also a general-purpose solution, but is geared towards efficiently servicing requests for one chunk at a time; it will work for contiguous chunks, but not as well as pool_allocator. If you are seriously concerned about performance, use fast_pool_allocator when dealing with containers such as std::list, and use pool_allocator when dealing with containers such as std::vector.

## Symbols

- boost::pool_allocator
- boost::pool_allocator_tag
- boost::fast_pool_allocator
- boost::fast_pool_allocator_tag

## Implementation Details

Copyright © 2000, 2001 Stephen Cleary (shammah@voyager.net)

This file can be redistributed and/or modified under the terms found in copyright.html

This software and its documentation is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.