#ifndef BOOST_SINGLETON_POOL_HPP
#define BOOST_SINGLETON_POOL_HPP
#include <boost/pool/poolfwd.hpp>
#include <boost/pool/pool.hpp>
#include <boost/pool/detail/guard.hpp>
#include <boost/type_traits/aligned_storage.hpp>
namespace boost {
template <typename Tag,
unsigned RequestedSize,
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
class singleton_pool
{
public:
typedef Tag tag;
typedef Mutex mutex; typedef UserAllocator user_allocator; typedef typename pool<UserAllocator>::size_type size_type; typedef typename pool<UserAllocator>::difference_type difference_type;
BOOST_STATIC_CONSTANT(unsigned, requested_size = RequestedSize); BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize);
private:
singleton_pool();
#ifndef BOOST_DOXYGEN
struct pool_type: public Mutex, public pool<UserAllocator>
{
pool_type() : pool<UserAllocator>(RequestedSize, NextSize, MaxSize) {}
};
#else
public:
static pool<UserAllocator> p; #endif
public:
static void * malloc BOOST_PREVENT_MACRO_SUBSTITUTION()
{ pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return (p.malloc)();
}
static void * ordered_malloc()
{ pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return p.ordered_malloc();
}
static void * ordered_malloc(const size_type n)
{ pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return p.ordered_malloc(n);
}
static bool is_from(void * const ptr)
{ pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return p.is_from(ptr);
}
static void free BOOST_PREVENT_MACRO_SUBSTITUTION(void * const ptr)
{ pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
(p.free)(ptr);
}
static void ordered_free(void * const ptr)
{ pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
p.ordered_free(ptr);
}
static void free BOOST_PREVENT_MACRO_SUBSTITUTION(void * const ptr, const size_type n)
{ pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
(p.free)(ptr, n);
}
static void ordered_free(void * const ptr, const size_type n)
{ pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
p.ordered_free(ptr, n);
}
static bool release_memory()
{ pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return p.release_memory();
}
static bool purge_memory()
{ pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return p.purge_memory();
}
private:
typedef boost::aligned_storage<sizeof(pool_type), boost::alignment_of<pool_type>::value> storage_type;
static storage_type storage;
static pool_type& get_pool()
{
static bool f = false;
if(!f)
{
f = true;
new (&storage) pool_type;
}
create_object.do_nothing();
return *static_cast<pool_type*>(static_cast<void*>(&storage));
}
struct object_creator
{
object_creator()
{ singleton_pool<Tag, RequestedSize, UserAllocator, Mutex, NextSize, MaxSize>::get_pool();
}
inline void do_nothing() const
{
}
};
static object_creator create_object;
};
template <typename Tag,
unsigned RequestedSize,
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
typename singleton_pool<Tag, RequestedSize, UserAllocator, Mutex, NextSize, MaxSize>::storage_type singleton_pool<Tag, RequestedSize, UserAllocator, Mutex, NextSize, MaxSize>::storage;
template <typename Tag,
unsigned RequestedSize,
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
typename singleton_pool<Tag, RequestedSize, UserAllocator, Mutex, NextSize, MaxSize>::object_creator singleton_pool<Tag, RequestedSize, UserAllocator, Mutex, NextSize, MaxSize>::create_object;
}
#endif