os/ossrv/ossrv_pub/boost_apis/boost/pool/object_pool.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (C) 2000, 2001 Stephen Cleary
     2 //
     3 // Distributed under the Boost Software License, Version 1.0. (See
     4 // accompanying file LICENSE_1_0.txt or copy at
     5 // http://www.boost.org/LICENSE_1_0.txt)
     6 //
     7 // See http://www.boost.org for updates, documentation, and revision history.
     8 
     9 #ifndef BOOST_OBJECT_POOL_HPP
    10 #define BOOST_OBJECT_POOL_HPP
    11 
    12 #include <boost/pool/poolfwd.hpp>
    13 
    14 // boost::pool
    15 #include <boost/pool/pool.hpp>
    16 
    17 // The following code will be put into Boost.Config in a later revision
    18 #if defined(BOOST_MSVC) || defined(__KCC)
    19 # define BOOST_NO_TEMPLATE_CV_REF_OVERLOADS
    20 #endif
    21 
    22 // The following code might be put into some Boost.Config header in a later revision
    23 #ifdef __BORLANDC__
    24 # pragma option push -w-inl
    25 #endif
    26 
    27 // There are a few places in this file where the expression "this->m" is used.
    28 // This expression is used to force instantiation-time name lookup, which I am
    29 //   informed is required for strict Standard compliance.  It's only necessary
    30 //   if "m" is a member of a base class that is dependent on a template
    31 //   parameter.
    32 // Thanks to Jens Maurer for pointing this out!
    33 
    34 namespace boost {
    35 
    36 // T must have a non-throwing destructor
    37 template <typename T, typename UserAllocator>
    38 class object_pool: protected pool<UserAllocator>
    39 {
    40   public:
    41     typedef T element_type;
    42     typedef UserAllocator user_allocator;
    43     typedef typename pool<UserAllocator>::size_type size_type;
    44     typedef typename pool<UserAllocator>::difference_type difference_type;
    45 
    46   protected:
    47     pool<UserAllocator> & store() { return *this; }
    48     const pool<UserAllocator> & store() const { return *this; }
    49 
    50     // for the sake of code readability :)
    51     static void * & nextof(void * const ptr)
    52     { return *(static_cast<void **>(ptr)); }
    53 
    54   public:
    55     // This constructor parameter is an extension!
    56     explicit object_pool(const size_type next_size = 32)
    57     :pool<UserAllocator>(sizeof(T), next_size) { }
    58 
    59     ~object_pool();
    60 
    61     // Returns 0 if out-of-memory
    62     element_type * malloc()
    63     { return static_cast<element_type *>(store().ordered_malloc()); }
    64     void free(element_type * const chunk)
    65     { store().ordered_free(chunk); }
    66     bool is_from(element_type * const chunk) const
    67     { return store().is_from(chunk); }
    68 
    69     element_type * construct()
    70     {
    71       element_type * const ret = malloc();
    72       if (ret == 0)
    73         return ret;
    74       try { new (ret) element_type(); }
    75       catch (...) { free(ret); throw; }
    76       return ret;
    77     }
    78 
    79     // Include automatically-generated file for family of template construct()
    80     //  functions
    81 #ifndef BOOST_NO_TEMPLATE_CV_REF_OVERLOADS
    82 #   include <boost/pool/detail/pool_construct.inc>
    83 #else
    84 #   include <boost/pool/detail/pool_construct_simple.inc>
    85 #endif
    86 
    87     void destroy(element_type * const chunk)
    88     {
    89       chunk->~T();
    90       free(chunk);
    91     }
    92 
    93     // These functions are extensions!
    94     size_type get_next_size() const { return store().get_next_size(); }
    95     void set_next_size(const size_type x) { store().set_next_size(x); }
    96 };
    97 
    98 template <typename T, typename UserAllocator>
    99 object_pool<T, UserAllocator>::~object_pool()
   100 {
   101   // handle trivial case
   102   if (!this->list.valid())
   103     return;
   104 
   105   details::PODptr<size_type> iter = this->list;
   106   details::PODptr<size_type> next = iter;
   107 
   108   // Start 'freed_iter' at beginning of free list
   109   void * freed_iter = this->first;
   110 
   111   const size_type partition_size = this->alloc_size();
   112 
   113   do
   114   {
   115     // increment next
   116     next = next.next();
   117 
   118     // delete all contained objects that aren't freed
   119 
   120     // Iterate 'i' through all chunks in the memory block
   121     for (char * i = iter.begin(); i != iter.end(); i += partition_size)
   122     {
   123       // If this chunk is free
   124       if (i == freed_iter)
   125       {
   126         // Increment freed_iter to point to next in free list
   127         freed_iter = nextof(freed_iter);
   128 
   129         // Continue searching chunks in the memory block
   130         continue;
   131       }
   132 
   133       // This chunk is not free (allocated), so call its destructor
   134       static_cast<T *>(static_cast<void *>(i))->~T();
   135       // and continue searching chunks in the memory block
   136     }
   137 
   138     // free storage
   139     UserAllocator::free(iter.begin());
   140 
   141     // increment iter
   142     iter = next;
   143   } while (iter.valid());
   144 
   145   // Make the block list empty so that the inherited destructor doesn't try to
   146   //  free it again.
   147   this->list.invalidate();
   148 }
   149 
   150 } // namespace boost
   151 
   152 // The following code might be put into some Boost.Config header in a later revision
   153 #ifdef __BORLANDC__
   154 # pragma option pop
   155 #endif
   156 
   157 #endif