]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // detail/object_pool.hpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
5 | // Copyright (c) 2003-2016 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(live_list_); | |
73 | destroy_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 |