1
// Copyright (C) 2000, 2001 Stephen Cleary (shammah@voyager.net)
3
// This file can be redistributed and/or modified under the terms found
5
// This software and its documentation is provided "as is" without express or
6
// implied warranty, and with no claim as to its suitability for any purpose.
8
// See http://www.boost.org for updates, documentation, and revision history.
10
#ifndef BOOST_OBJECT_POOL_HPP
11
#define BOOST_OBJECT_POOL_HPP
13
#include <boost/pool/poolfwd.hpp>
16
#include <boost/pool/pool.hpp>
18
// The following code will be put into Boost.Config in a later revision
19
#if defined(BOOST_MSVC) || defined(__KCC)
20
# define BOOST_NO_TEMPLATE_CV_REF_OVERLOADS
23
// The following code might be put into some Boost.Config header in a later revision
25
# pragma option push -w-inl
28
// There are a few places in this file where the expression "this->m" is used.
29
// This expression is used to force instantiation-time name lookup, which I am
30
// informed is required for strict Standard compliance. It's only necessary
31
// if "m" is a member of a base class that is dependent on a template
33
// Thanks to Jens Maurer for pointing this out!
37
// T must have a non-throwing destructor
38
template <typename T, typename UserAllocator>
39
class object_pool: protected pool<UserAllocator>
42
typedef T element_type;
43
typedef UserAllocator user_allocator;
44
typedef typename pool<UserAllocator>::size_type size_type;
45
typedef typename pool<UserAllocator>::difference_type difference_type;
48
pool<UserAllocator> & store() { return *this; }
49
const pool<UserAllocator> & store() const { return *this; }
51
// for the sake of code readability :)
52
static void * & nextof(void * const ptr)
53
{ return *(static_cast<void **>(ptr)); }
56
// This constructor parameter is an extension!
57
explicit object_pool(const size_type next_size = 32)
58
:pool<UserAllocator>(sizeof(T), next_size) { }
62
// Returns 0 if out-of-memory
63
element_type * malloc()
64
{ return static_cast<element_type *>(store().ordered_malloc()); }
65
void free(element_type * const chunk)
66
{ store().ordered_free(chunk); }
67
bool is_from(element_type * const chunk) const
68
{ return store().is_from(chunk); }
70
element_type * construct()
72
element_type * const ret = malloc();
75
try { new (ret) element_type(); }
76
catch (...) { free(ret); throw; }
80
// Include automatically-generated file for family of template construct()
82
#ifndef BOOST_NO_TEMPLATE_CV_REF_OVERLOADS
83
# include <boost/pool/detail/pool_construct.inc>
85
# include <boost/pool/detail/pool_construct_simple.inc>
88
void destroy(element_type * const chunk)
94
// These functions are extensions!
95
size_type get_next_size() const { return store().get_next_size(); }
96
void set_next_size(const size_type x) { store().set_next_size(x); }
99
template <typename T, typename UserAllocator>
100
object_pool<T, UserAllocator>::~object_pool()
102
// handle trivial case
103
if (!this->list.valid())
106
details::PODptr<size_type> iter = this->list;
107
details::PODptr<size_type> next = iter;
109
// Start 'freed_iter' at beginning of free list
110
void * freed_iter = this->first;
112
const size_type partition_size = this->alloc_size();
119
// delete all contained objects that aren't freed
121
// Iterate 'i' through all chunks in the memory block
122
for (char * i = iter.begin(); i != iter.end(); i += partition_size)
124
// If this chunk is free
127
// Increment freed_iter to point to next in free list
128
freed_iter = nextof(freed_iter);
130
// Continue searching chunks in the memory block
134
// This chunk is not free (allocated), so call its destructor
135
static_cast<T *>(static_cast<void *>(i))->~T();
136
// and continue searching chunks in the memory block
140
UserAllocator::free(iter.begin());
144
} while (iter.valid());
146
// Make the block list empty so that the inherited destructor doesn't try to
148
this->list.invalidate();
153
// The following code might be put into some Boost.Config header in a later revision