diff DEPENDENCIES/generic/include/boost/pool/pool_alloc.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/pool/pool_alloc.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -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