#ifndef BOOST_POOL_ALLOC_HPP
#define BOOST_POOL_ALLOC_HPP
#include <boost/limits.hpp>
#include <new>
#include <boost/throw_exception.hpp>
#include <boost/pool/poolfwd.hpp>
#include <boost/pool/singleton_pool.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config.hpp>
#ifdef BOOST_HAS_VARIADIC_TMPL
#include <utility>
#endif
#ifdef BOOST_POOL_INSTRUMENT
#include <iostream>
#include <iomanip>
#endif
#if defined(_RWSTD_VER) || defined(__SGI_STL_PORT) || \
BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x582))
#define BOOST_NO_PROPER_STL_DEALLOCATE
#endif
namespace boost {
#ifdef BOOST_POOL_INSTRUMENT
template <bool b>
struct debug_info
{
static unsigned allocated;
};
template <bool b>
unsigned debug_info<b>::allocated = 0;
#endif
struct pool_allocator_tag
{
};
template <typename T,
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
class pool_allocator
{
public:
typedef T value_type; typedef UserAllocator user_allocator; typedef Mutex mutex; BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize);
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 pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
};
public:
pool_allocator()
{
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
NextSize, MaxSize>::is_from(0);
}
template <typename U>
pool_allocator(const pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &)
{
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
NextSize, MaxSize>::is_from(0);
}
static pointer address(reference r)
{ return &r; }
static const_pointer address(const_reference s)
{ return &s; }
static size_type max_size()
{ return (std::numeric_limits<size_type>::max)(); }
#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
template <typename U, typename... Args>
static void construct(U* ptr, Args&&... args)
{ new (ptr) U(std::forward<Args>(args)...); }
#else
static void construct(const pointer ptr, const value_type & t)
{ new (ptr) T(t); }
#endif
static void destroy(const pointer ptr)
{
ptr->~T();
(void) ptr; }
bool operator==(const pool_allocator &) const
{ return true; }
bool operator!=(const pool_allocator &) const
{ return false; }
static pointer allocate(const size_type n)
{
#ifdef BOOST_POOL_INSTRUMENT
debug_info<true>::allocated += n * sizeof(T);
std::cout << "Allocating " << n << " * " << sizeof(T) << " bytes...\n"
"Total allocated is now " << debug_info<true>::allocated << std::endl;
#endif
const pointer ret = static_cast<pointer>(
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
NextSize, MaxSize>::ordered_malloc(n) );
if ((ret == 0) && n)
boost::throw_exception(std::bad_alloc());
return ret;
}
static pointer allocate(const size_type n, const void * const)
{ return allocate(n);
}
static void deallocate(const pointer ptr, const size_type n)
{ #ifdef BOOST_POOL_INSTRUMENT
debug_info<true>::allocated -= n * sizeof(T);
std::cout << "Deallocating " << n << " * " << sizeof(T) << " bytes...\n"
"Total allocated is now " << debug_info<true>::allocated << std::endl;
#endif
#ifdef BOOST_NO_PROPER_STL_DEALLOCATE
if (ptr == 0 || n == 0)
return;
#endif
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
NextSize, MaxSize>::ordered_free(ptr, n);
}
};
template<
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize>
class pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>
{
public:
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
template <class U>
struct rebind
{
typedef pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
};
};
struct fast_pool_allocator_tag
{
};
template <typename T,
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
class fast_pool_allocator
{
public:
typedef T value_type;
typedef UserAllocator user_allocator;
typedef Mutex mutex;
BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize);
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, Mutex, NextSize, MaxSize> other;
};
public:
fast_pool_allocator()
{
singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
}
template <typename U>
fast_pool_allocator(
const fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &)
{
singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
}
static pointer address(reference r)
{
return &r;
}
static const_pointer address(const_reference s)
{ return &s; }
static size_type max_size()
{ return (std::numeric_limits<size_type>::max)(); }
#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
template <typename U, typename... Args>
void construct(U* ptr, Args&&... args)
{ new (ptr) U(std::forward<Args>(args)...); }
#else
void construct(const pointer ptr, const value_type & t)
{ new (ptr) T(t); }
#endif
void destroy(const pointer ptr)
{ ptr->~T();
(void) ptr; }
bool operator==(const fast_pool_allocator &) const
{ return true; }
bool operator!=(const fast_pool_allocator &) const
{ return false; }
static pointer allocate(const size_type n)
{
const pointer ret = (n == 1) ?
static_cast<pointer>(
(singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::malloc)() ) :
static_cast<pointer>(
singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::ordered_malloc(n) );
if (ret == 0)
boost::throw_exception(std::bad_alloc());
return ret;
}
static pointer allocate(const size_type n, const void * const)
{ return allocate(n);
}
static pointer allocate()
{ const pointer ret = static_cast<pointer>(
(singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::malloc)() );
if (ret == 0)
boost::throw_exception(std::bad_alloc());
return ret;
}
static void deallocate(const pointer ptr, const size_type n)
{
#ifdef BOOST_NO_PROPER_STL_DEALLOCATE
if (ptr == 0 || n == 0)
return;
#endif
if (n == 1)
(singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr);
else
(singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr, n);
}
static void deallocate(const pointer ptr)
{ (singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr);
}
};
template<
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
class fast_pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>
{
public:
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
template <class U> struct rebind
{
typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
};
};
}
#endif