Added boost header
This commit is contained in:
488
test/external/boost/pool/pool_alloc.hpp
vendored
Normal file
488
test/external/boost/pool/pool_alloc.hpp
vendored
Normal file
@@ -0,0 +1,488 @@
|
||||
// Copyright (C) 2000, 2001 Stephen Cleary
|
||||
// Copyright (C) 2010 Paul A. Bristow added Doxygen comments.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_POOL_ALLOC_HPP
|
||||
#define BOOST_POOL_ALLOC_HPP
|
||||
|
||||
/*!
|
||||
\file
|
||||
\brief C++ Standard Library compatible pool-based allocators.
|
||||
\details This header provides two template types -
|
||||
\ref pool_allocator and \ref 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:
|
||||
|
||||
<table>
|
||||
<tr><th>Expression</th><th>Return Type</th><th>Semantic Equivalence<th></tr>
|
||||
<tr><td><tt>PoolAlloc::allocate()</tt></td><td><tt>T *</tt></td><td><tt>PoolAlloc::allocate(1)</tt></tr>
|
||||
<tr><td><tt>PoolAlloc::deallocate(p)</tt></td><td>void</tt></td><td><tt>PoolAlloc::deallocate(p, 1)</tt></tr>
|
||||
</table>
|
||||
|
||||
The typedef user_allocator publishes the value of the UserAllocator template parameter.
|
||||
|
||||
<b>Notes</b>
|
||||
|
||||
If the allocation functions run out of memory, they will throw <tt>std::bad_alloc</tt>.
|
||||
|
||||
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
|
||||
<tt>sizeof(int) == sizeof(void *)</tt>, <tt>pool_allocator<int></tt> and <tt>pool_allocator<void *></tt>
|
||||
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.
|
||||
|
||||
<b>Compiler and STL Notes</b>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// std::numeric_limits
|
||||
#include <boost/limits.hpp>
|
||||
// new, std::bad_alloc
|
||||
#include <new>
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/pool/poolfwd.hpp>
|
||||
|
||||
// boost::singleton_pool
|
||||
#include <boost/pool/singleton_pool.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#ifdef BOOST_POOL_INSTRUMENT
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#endif
|
||||
|
||||
// The following code will be put into Boost.Config in a later revision
|
||||
#if defined(_RWSTD_VER) || defined(__SGI_STL_PORT) || \
|
||||
BOOST_WORKAROUND(__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
|
||||
|
||||
//! Simple tag type used by pool_allocator as an argument to the
|
||||
//! underlying singleton_pool.
|
||||
struct pool_allocator_tag
|
||||
{
|
||||
};
|
||||
|
||||
/*! \brief A C++ Standard Library conforming allocator, based on an underlying pool.
|
||||
|
||||
Template parameters for pool_allocator are defined as follows:
|
||||
|
||||
<b>T</b> Type of object to allocate/deallocate.
|
||||
|
||||
<b>UserAllocator</B>. Defines the method that the underlying Pool will use to allocate memory from the system. See
|
||||
<a href="boost_pool/pool/pooling.html#boost_pool.pool.pooling.user_allocator">User Allocators</a> for details.
|
||||
|
||||
<b>Mutex</b> Allows the user to determine the type of synchronization to be used on the underlying singleton_pool.
|
||||
|
||||
<b>NextSize</b> The value of this parameter is passed to the underlying singleton_pool when it is created.
|
||||
|
||||
<b>MaxSize</b> Limit on the maximum size used.
|
||||
|
||||
\attention
|
||||
The underlying singleton_pool used by the this allocator
|
||||
constructs a pool instance that
|
||||
<b>is never freed</b>. This means that memory allocated
|
||||
by the allocator can be still used after main() has
|
||||
completed, but may mean that some memory checking programs
|
||||
will complain about leaks.
|
||||
|
||||
|
||||
*/
|
||||
template <typename T,
|
||||
typename UserAllocator,
|
||||
typename Mutex,
|
||||
unsigned NextSize,
|
||||
unsigned MaxSize >
|
||||
class pool_allocator
|
||||
{
|
||||
public:
|
||||
typedef T value_type; //!< value_type of template parameter T.
|
||||
typedef UserAllocator user_allocator; //!< allocator that defines the method that the underlying Pool will use to allocate memory from the system.
|
||||
typedef Mutex mutex; //!< typedef mutex publishes the value of the template parameter Mutex.
|
||||
BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize); //!< next_size publishes the values of the template parameter 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;
|
||||
|
||||
//! \brief Nested class rebind allows for transformation from
|
||||
//! pool_allocator<T> to pool_allocator<U>.
|
||||
//!
|
||||
//! Nested class rebind allows for transformation from
|
||||
//! pool_allocator<T> to pool_allocator<U> via the member
|
||||
//! typedef other.
|
||||
template <typename U>
|
||||
struct rebind
|
||||
{ //
|
||||
typedef pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
|
||||
};
|
||||
|
||||
public:
|
||||
pool_allocator()
|
||||
{ /*! Results in default construction of the underlying singleton_pool IFF an
|
||||
instance of this allocator is constructed during global initialization (
|
||||
required to ensure construction of singleton_pool IFF an
|
||||
instance of this allocator is constructed during global
|
||||
initialization. See ticket #2359 for a complete explanation at
|
||||
http://svn.boost.org/trac/boost/ticket/2359) .
|
||||
*/
|
||||
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
|
||||
NextSize, MaxSize>::is_from(0);
|
||||
}
|
||||
|
||||
// default copy constructor.
|
||||
|
||||
// default assignment operator.
|
||||
|
||||
// not explicit, mimicking std::allocator [20.4.1]
|
||||
template <typename U>
|
||||
pool_allocator(const pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &)
|
||||
{ /*! Results in the default construction of the underlying singleton_pool, this
|
||||
is required to ensure construction of singleton_pool IFF an
|
||||
instance of this allocator is constructed during global
|
||||
initialization. See ticket #2359 for a complete explanation
|
||||
at http://svn.boost.org/trac/boost/ticket/2359 .
|
||||
*/
|
||||
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
|
||||
NextSize, MaxSize>::is_from(0);
|
||||
}
|
||||
|
||||
// default destructor
|
||||
|
||||
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)(); }
|
||||
static void construct(const pointer ptr, const value_type & t)
|
||||
{ new (ptr) T(t); }
|
||||
static void destroy(const pointer ptr)
|
||||
{
|
||||
ptr->~T();
|
||||
(void) ptr; // avoid unused variable warning.
|
||||
}
|
||||
|
||||
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)
|
||||
{ //! allocate n bytes
|
||||
//! \param n bytes to allocate.
|
||||
//! \param unused.
|
||||
return allocate(n);
|
||||
}
|
||||
static void deallocate(const pointer ptr, const size_type n)
|
||||
{ //! Deallocate n bytes from ptr
|
||||
//! \param ptr location to deallocate from.
|
||||
//! \param n number of bytes to deallocate.
|
||||
#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);
|
||||
}
|
||||
};
|
||||
|
||||
/*! \brief Specialization of pool_allocator<void>.
|
||||
|
||||
Specialization of pool_allocator for type void: required by the standard to make this a conforming allocator type.
|
||||
*/
|
||||
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;
|
||||
//! \brief Nested class rebind allows for transformation from
|
||||
//! pool_allocator<T> to pool_allocator<U>.
|
||||
//!
|
||||
//! Nested class rebind allows for transformation from
|
||||
//! pool_allocator<T> to pool_allocator<U> via the member
|
||||
//! typedef other.
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
|
||||
};
|
||||
};
|
||||
|
||||
//! Simple tag type used by fast_pool_allocator as a template parameter to the underlying singleton_pool.
|
||||
struct fast_pool_allocator_tag
|
||||
{
|
||||
};
|
||||
|
||||
/*! \brief A C++ Standard Library conforming allocator geared towards allocating single chunks.
|
||||
|
||||
While class template <tt>pool_allocator</tt> is a more general-purpose solution geared towards
|
||||
efficiently servicing requests for any number of contiguous chunks,
|
||||
<tt>fast_pool_allocator</tt> 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 <tt>pool_allocator</tt>.
|
||||
|
||||
If you are seriously concerned about performance,
|
||||
use <tt>fast_pool_allocator</tt> when dealing with containers such as <tt>std::list</tt>,
|
||||
and use <tt>pool_allocator</tt> when dealing with containers such as <tt>std::vector</tt>.
|
||||
|
||||
The template parameters are defined as follows:
|
||||
|
||||
<b>T</b> Type of object to allocate/deallocate.
|
||||
|
||||
<b>UserAllocator</b>. Defines the method that the underlying Pool will use to allocate memory from the system.
|
||||
See <a href="boost_pool/pool/pooling.html#boost_pool.pool.pooling.user_allocator">User Allocators</a> for details.
|
||||
|
||||
<b>Mutex</b> Allows the user to determine the type of synchronization to be used on the underlying <tt>singleton_pool</tt>.
|
||||
|
||||
<b>NextSize</b> The value of this parameter is passed to the underlying Pool when it is created.
|
||||
|
||||
<b>MaxSize</b> Limit on the maximum size used.
|
||||
|
||||
\attention
|
||||
The underlying singleton_pool used by the this allocator
|
||||
constructs a pool instance that
|
||||
<b>is never freed</b>. This means that memory allocated
|
||||
by the allocator can be still used after main() has
|
||||
completed, but may mean that some memory checking programs
|
||||
will complain about leaks.
|
||||
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
//! \brief Nested class rebind allows for transformation from
|
||||
//! fast_pool_allocator<T> to fast_pool_allocator<U>.
|
||||
//!
|
||||
//! Nested class rebind allows for transformation from
|
||||
//! fast_pool_allocator<T> to fast_pool_allocator<U> via the member
|
||||
//! typedef other.
|
||||
template <typename U>
|
||||
struct rebind
|
||||
{
|
||||
typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
|
||||
};
|
||||
|
||||
public:
|
||||
fast_pool_allocator()
|
||||
{
|
||||
//! Ensures construction of the underlying singleton_pool IFF an
|
||||
//! instance of this allocator is constructed during global
|
||||
//! initialization. See ticket #2359 for a complete explanation
|
||||
//! at http://svn.boost.org/trac/boost/ticket/2359 .
|
||||
singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
||||
UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
|
||||
}
|
||||
|
||||
// Default copy constructor used.
|
||||
|
||||
// Default assignment operator used.
|
||||
|
||||
// Not explicit, mimicking std::allocator [20.4.1]
|
||||
template <typename U>
|
||||
fast_pool_allocator(
|
||||
const fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &)
|
||||
{
|
||||
//! Ensures construction of the underlying singleton_pool IFF an
|
||||
//! instance of this allocator is constructed during global
|
||||
//! initialization. See ticket #2359 for a complete explanation
|
||||
//! at http://svn.boost.org/trac/boost/ticket/2359 .
|
||||
singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
||||
UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
|
||||
}
|
||||
|
||||
// Default destructor used.
|
||||
|
||||
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)(); }
|
||||
void construct(const pointer ptr, const value_type & t)
|
||||
{ new (ptr) T(t); }
|
||||
void destroy(const pointer ptr)
|
||||
{ //! Destroy ptr using destructor.
|
||||
ptr->~T();
|
||||
(void) ptr; // Avoid unused variable warning.
|
||||
}
|
||||
|
||||
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)
|
||||
{ //! Allocate memory .
|
||||
return allocate(n);
|
||||
}
|
||||
static pointer allocate()
|
||||
{ //! Allocate memory.
|
||||
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)
|
||||
{ //! Deallocate memory.
|
||||
|
||||
#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)
|
||||
{ //! deallocate/free
|
||||
(singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
||||
UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
/*! \brief Specialization of fast_pool_allocator<void>.
|
||||
|
||||
Specialization of fast_pool_allocator<void> required to make the allocator standard-conforming.
|
||||
*/
|
||||
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;
|
||||
|
||||
//! \brief Nested class rebind allows for transformation from
|
||||
//! fast_pool_allocator<T> to fast_pool_allocator<U>.
|
||||
//!
|
||||
//! Nested class rebind allows for transformation from
|
||||
//! fast_pool_allocator<T> to fast_pool_allocator<U> via the member
|
||||
//! typedef other.
|
||||
template <class U> struct rebind
|
||||
{
|
||||
typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user