File indexing completed on 2025-12-16 09:43:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
0012 #define BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/noncopyable.hpp>
0019 #include <cstddef>
0020
0021 #include <boost/asio/detail/push_options.hpp>
0022
0023 namespace boost {
0024 namespace asio {
0025 namespace detail {
0026
0027 template <typename Object>
0028 class object_pool;
0029
0030 class object_pool_access
0031 {
0032 public:
0033 template <typename Object>
0034 static Object* create()
0035 {
0036 return new Object;
0037 }
0038
0039 template <typename Object, typename... Args>
0040 static Object* create(Args... args)
0041 {
0042 return new Object(args...);
0043 }
0044
0045 template <typename Object>
0046 static void destroy(Object* o)
0047 {
0048 delete o;
0049 }
0050
0051 template <typename Object>
0052 static Object*& next(Object* o)
0053 {
0054 return o->next_;
0055 }
0056
0057 template <typename Object>
0058 static Object*& prev(Object* o)
0059 {
0060 return o->prev_;
0061 }
0062 };
0063
0064 template <typename Object>
0065 class object_pool
0066 : private noncopyable
0067 {
0068 public:
0069
0070 template <typename... Args>
0071 object_pool(unsigned int preallocated, Args... args)
0072 : live_list_(0),
0073 free_list_(0)
0074 {
0075 while (preallocated > 0)
0076 {
0077 Object* o = object_pool_access::create<Object>(args...);
0078 object_pool_access::next(o) = free_list_;
0079 object_pool_access::prev(o) = 0;
0080 free_list_ = o;
0081 --preallocated;
0082 }
0083 }
0084
0085
0086 ~object_pool()
0087 {
0088 destroy_list(live_list_);
0089 destroy_list(free_list_);
0090 }
0091
0092
0093 Object* first()
0094 {
0095 return live_list_;
0096 }
0097
0098
0099 template <typename... Args>
0100 Object* alloc(Args... args)
0101 {
0102 Object* o = free_list_;
0103 if (o)
0104 free_list_ = object_pool_access::next(free_list_);
0105 else
0106 o = object_pool_access::create<Object>(args...);
0107
0108 object_pool_access::next(o) = live_list_;
0109 object_pool_access::prev(o) = 0;
0110 if (live_list_)
0111 object_pool_access::prev(live_list_) = o;
0112 live_list_ = o;
0113
0114 return o;
0115 }
0116
0117
0118 void free(Object* o)
0119 {
0120 if (live_list_ == o)
0121 live_list_ = object_pool_access::next(o);
0122
0123 if (object_pool_access::prev(o))
0124 {
0125 object_pool_access::next(object_pool_access::prev(o))
0126 = object_pool_access::next(o);
0127 }
0128
0129 if (object_pool_access::next(o))
0130 {
0131 object_pool_access::prev(object_pool_access::next(o))
0132 = object_pool_access::prev(o);
0133 }
0134
0135 object_pool_access::next(o) = free_list_;
0136 object_pool_access::prev(o) = 0;
0137 free_list_ = o;
0138 }
0139
0140 private:
0141
0142 void destroy_list(Object* list)
0143 {
0144 while (list)
0145 {
0146 Object* o = list;
0147 list = object_pool_access::next(o);
0148 object_pool_access::destroy(o);
0149 }
0150 }
0151
0152
0153 Object* live_list_;
0154
0155
0156 Object* free_list_;
0157 };
0158
0159 }
0160 }
0161 }
0162
0163 #include <boost/asio/detail/pop_options.hpp>
0164
0165 #endif