1 | // |
---|---|
2 | // detail/object_pool.hpp |
3 | // ~~~~~~~~~~~~~~~~~~~~~~ |
4 | // |
5 | // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
9 | // |
10 | |
11 | #ifndef BOOST_ASIO_DETAIL_OBJECT_POOL_HPP |
12 | #define BOOST_ASIO_DETAIL_OBJECT_POOL_HPP |
13 | |
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) |
15 | # pragma once |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) |
17 | |
18 | #include <boost/asio/detail/noncopyable.hpp> |
19 | |
20 | #include <boost/asio/detail/push_options.hpp> |
21 | |
22 | namespace boost { |
23 | namespace asio { |
24 | namespace detail { |
25 | |
26 | template <typename Object> |
27 | class object_pool; |
28 | |
29 | class object_pool_access |
30 | { |
31 | public: |
32 | template <typename Object> |
33 | static Object* create() |
34 | { |
35 | return new Object; |
36 | } |
37 | |
38 | template <typename Object> |
39 | static void destroy(Object* o) |
40 | { |
41 | delete o; |
42 | } |
43 | |
44 | template <typename Object> |
45 | static Object*& next(Object* o) |
46 | { |
47 | return o->next_; |
48 | } |
49 | |
50 | template <typename Object> |
51 | static Object*& prev(Object* o) |
52 | { |
53 | return o->prev_; |
54 | } |
55 | }; |
56 | |
57 | template <typename Object> |
58 | class object_pool |
59 | : private noncopyable |
60 | { |
61 | public: |
62 | // Constructor. |
63 | object_pool() |
64 | : live_list_(0), |
65 | free_list_(0) |
66 | { |
67 | } |
68 | |
69 | // Destructor destroys all objects. |
70 | ~object_pool() |
71 | { |
72 | destroy_list(list: live_list_); |
73 | destroy_list(list: free_list_); |
74 | } |
75 | |
76 | // Get the object at the start of the live list. |
77 | Object* first() |
78 | { |
79 | return live_list_; |
80 | } |
81 | |
82 | // Allocate a new object. |
83 | Object* alloc() |
84 | { |
85 | Object* o = free_list_; |
86 | if (o) |
87 | free_list_ = object_pool_access::next(free_list_); |
88 | else |
89 | o = object_pool_access::create<Object>(); |
90 | |
91 | object_pool_access::next(o) = live_list_; |
92 | object_pool_access::prev(o) = 0; |
93 | if (live_list_) |
94 | object_pool_access::prev(live_list_) = o; |
95 | live_list_ = o; |
96 | |
97 | return o; |
98 | } |
99 | |
100 | // Free an object. Moves it to the free list. No destructors are run. |
101 | void free(Object* o) |
102 | { |
103 | if (live_list_ == o) |
104 | live_list_ = object_pool_access::next(o); |
105 | |
106 | if (object_pool_access::prev(o)) |
107 | { |
108 | object_pool_access::next(object_pool_access::prev(o)) |
109 | = object_pool_access::next(o); |
110 | } |
111 | |
112 | if (object_pool_access::next(o)) |
113 | { |
114 | object_pool_access::prev(object_pool_access::next(o)) |
115 | = object_pool_access::prev(o); |
116 | } |
117 | |
118 | object_pool_access::next(o) = free_list_; |
119 | object_pool_access::prev(o) = 0; |
120 | free_list_ = o; |
121 | } |
122 | |
123 | private: |
124 | // Helper function to destroy all elements in a list. |
125 | void destroy_list(Object* list) |
126 | { |
127 | while (list) |
128 | { |
129 | Object* o = list; |
130 | list = object_pool_access::next(o); |
131 | object_pool_access::destroy(o); |
132 | } |
133 | } |
134 | |
135 | // The list of live objects. |
136 | Object* live_list_; |
137 | |
138 | // The free list. |
139 | Object* free_list_; |
140 | }; |
141 | |
142 | } // namespace detail |
143 | } // namespace asio |
144 | } // namespace boost |
145 | |
146 | #include <boost/asio/detail/pop_options.hpp> |
147 | |
148 | #endif // BOOST_ASIO_DETAIL_OBJECT_POOL_HPP |
149 |