Update contrib.
1 // Copyright (C) 2000, 2001 Stephen Cleary
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)
7 // See http://www.boost.org for updates, documentation, and revision history.
9 #ifndef BOOST_OBJECT_POOL_HPP
10 #define BOOST_OBJECT_POOL_HPP
12 #include <boost/pool/poolfwd.hpp>
15 #include <boost/pool/pool.hpp>
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
22 // The following code might be put into some Boost.Config header in a later revision
24 # pragma option push -w-inl
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
32 // Thanks to Jens Maurer for pointing this out!
36 // T must have a non-throwing destructor
37 template <typename T, typename UserAllocator>
38 class object_pool: protected pool<UserAllocator>
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;
47 pool<UserAllocator> & store() { return *this; }
48 const pool<UserAllocator> & store() const { return *this; }
50 // for the sake of code readability :)
51 static void * & nextof(void * const ptr)
52 { return *(static_cast<void **>(ptr)); }
55 // This constructor parameter is an extension!
56 explicit object_pool(const size_type next_size = 32)
57 :pool<UserAllocator>(sizeof(T), next_size) { }
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); }
69 element_type * construct()
71 element_type * const ret = malloc();
74 try { new (ret) element_type(); }
75 catch (...) { free(ret); throw; }
79 // Include automatically-generated file for family of template construct()
81 #ifndef BOOST_NO_TEMPLATE_CV_REF_OVERLOADS
82 # include <boost/pool/detail/pool_construct.inc>
84 # include <boost/pool/detail/pool_construct_simple.inc>
87 void destroy(element_type * const chunk)
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); }
98 template <typename T, typename UserAllocator>
99 object_pool<T, UserAllocator>::~object_pool()
101 // handle trivial case
102 if (!this->list.valid())
105 details::PODptr<size_type> iter = this->list;
106 details::PODptr<size_type> next = iter;
108 // Start 'freed_iter' at beginning of free list
109 void * freed_iter = this->first;
111 const size_type partition_size = this->alloc_size();
118 // delete all contained objects that aren't freed
120 // Iterate 'i' through all chunks in the memory block
121 for (char * i = iter.begin(); i != iter.end(); i += partition_size)
123 // If this chunk is free
126 // Increment freed_iter to point to next in free list
127 freed_iter = nextof(freed_iter);
129 // Continue searching chunks in the memory block
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
139 UserAllocator::free(iter.begin());
143 } while (iter.valid());
145 // Make the block list empty so that the inherited destructor doesn't try to
147 this->list.invalidate();
152 // The following code might be put into some Boost.Config header in a later revision