~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to boost/boost/pool/object_pool.hpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C) 2000, 2001 Stephen Cleary (shammah@voyager.net)
 
2
//
 
3
// This file can be redistributed and/or modified under the terms found
 
4
//  in "copyright.html"
 
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.
 
7
//
 
8
// See http://www.boost.org for updates, documentation, and revision history.
 
9
 
 
10
#ifndef BOOST_OBJECT_POOL_HPP
 
11
#define BOOST_OBJECT_POOL_HPP
 
12
 
 
13
#include <boost/pool/poolfwd.hpp>
 
14
 
 
15
// boost::pool
 
16
#include <boost/pool/pool.hpp>
 
17
 
 
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
 
21
#endif
 
22
 
 
23
// The following code might be put into some Boost.Config header in a later revision
 
24
#ifdef __BORLANDC__
 
25
# pragma option push -w-inl
 
26
#endif
 
27
 
 
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
 
32
//   parameter.
 
33
// Thanks to Jens Maurer for pointing this out!
 
34
 
 
35
namespace boost {
 
36
 
 
37
// T must have a non-throwing destructor
 
38
template <typename T, typename UserAllocator>
 
39
class object_pool: protected pool<UserAllocator>
 
40
{
 
41
  public:
 
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;
 
46
 
 
47
  protected:
 
48
    pool<UserAllocator> & store() { return *this; }
 
49
    const pool<UserAllocator> & store() const { return *this; }
 
50
 
 
51
    // for the sake of code readability :)
 
52
    static void * & nextof(void * const ptr)
 
53
    { return *(static_cast<void **>(ptr)); }
 
54
 
 
55
  public:
 
56
    // This constructor parameter is an extension!
 
57
    explicit object_pool(const size_type next_size = 32)
 
58
    :pool<UserAllocator>(sizeof(T), next_size) { }
 
59
 
 
60
    ~object_pool();
 
61
 
 
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); }
 
69
 
 
70
    element_type * construct()
 
71
    {
 
72
      element_type * const ret = malloc();
 
73
      if (ret == 0)
 
74
        return ret;
 
75
      try { new (ret) element_type(); }
 
76
      catch (...) { free(ret); throw; }
 
77
      return ret;
 
78
    }
 
79
 
 
80
    // Include automatically-generated file for family of template construct()
 
81
    //  functions
 
82
#ifndef BOOST_NO_TEMPLATE_CV_REF_OVERLOADS
 
83
#   include <boost/pool/detail/pool_construct.inc>
 
84
#else
 
85
#   include <boost/pool/detail/pool_construct_simple.inc>
 
86
#endif
 
87
 
 
88
    void destroy(element_type * const chunk)
 
89
    {
 
90
      chunk->~T();
 
91
      free(chunk);
 
92
    }
 
93
 
 
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); }
 
97
};
 
98
 
 
99
template <typename T, typename UserAllocator>
 
100
object_pool<T, UserAllocator>::~object_pool()
 
101
{
 
102
  // handle trivial case
 
103
  if (!this->list.valid())
 
104
    return;
 
105
 
 
106
  details::PODptr<size_type> iter = this->list;
 
107
  details::PODptr<size_type> next = iter;
 
108
 
 
109
  // Start 'freed_iter' at beginning of free list
 
110
  void * freed_iter = this->first;
 
111
 
 
112
  const size_type partition_size = this->alloc_size();
 
113
 
 
114
  do
 
115
  {
 
116
    // increment next
 
117
    next = next.next();
 
118
 
 
119
    // delete all contained objects that aren't freed
 
120
 
 
121
    // Iterate 'i' through all chunks in the memory block
 
122
    for (char * i = iter.begin(); i != iter.end(); i += partition_size)
 
123
    {
 
124
      // If this chunk is free
 
125
      if (i == freed_iter)
 
126
      {
 
127
        // Increment freed_iter to point to next in free list
 
128
        freed_iter = nextof(freed_iter);
 
129
 
 
130
        // Continue searching chunks in the memory block
 
131
        continue;
 
132
      }
 
133
 
 
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
 
137
    }
 
138
 
 
139
    // free storage
 
140
    UserAllocator::free(iter.begin());
 
141
 
 
142
    // increment iter
 
143
    iter = next;
 
144
  } while (iter.valid());
 
145
 
 
146
  // Make the block list empty so that the inherited destructor doesn't try to
 
147
  //  free it again.
 
148
  this->list.invalidate();
 
149
}
 
150
 
 
151
} // namespace boost
 
152
 
 
153
// The following code might be put into some Boost.Config header in a later revision
 
154
#ifdef __BORLANDC__
 
155
# pragma option pop
 
156
#endif
 
157
 
 
158
#endif