object_pool.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. //
  2. // detail/object_pool.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2021 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. #ifndef BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
  11. #define BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/noncopyable.hpp>
  16. #include <boost/asio/detail/push_options.hpp>
  17. namespace boost {
  18. namespace asio {
  19. namespace detail {
  20. template <typename Object>
  21. class object_pool;
  22. class object_pool_access
  23. {
  24. public:
  25. template <typename Object>
  26. static Object* create()
  27. {
  28. return new Object;
  29. }
  30. template <typename Object, typename Arg>
  31. static Object* create(Arg arg)
  32. {
  33. return new Object(arg);
  34. }
  35. template <typename Object>
  36. static void destroy(Object* o)
  37. {
  38. delete o;
  39. }
  40. template <typename Object>
  41. static Object*& next(Object* o)
  42. {
  43. return o->next_;
  44. }
  45. template <typename Object>
  46. static Object*& prev(Object* o)
  47. {
  48. return o->prev_;
  49. }
  50. };
  51. template <typename Object>
  52. class object_pool
  53. : private noncopyable
  54. {
  55. public:
  56. // Constructor.
  57. object_pool()
  58. : live_list_(0),
  59. free_list_(0)
  60. {
  61. }
  62. // Destructor destroys all objects.
  63. ~object_pool()
  64. {
  65. destroy_list(live_list_);
  66. destroy_list(free_list_);
  67. }
  68. // Get the object at the start of the live list.
  69. Object* first()
  70. {
  71. return live_list_;
  72. }
  73. // Allocate a new object.
  74. Object* alloc()
  75. {
  76. Object* o = free_list_;
  77. if (o)
  78. free_list_ = object_pool_access::next(free_list_);
  79. else
  80. o = object_pool_access::create<Object>();
  81. object_pool_access::next(o) = live_list_;
  82. object_pool_access::prev(o) = 0;
  83. if (live_list_)
  84. object_pool_access::prev(live_list_) = o;
  85. live_list_ = o;
  86. return o;
  87. }
  88. // Allocate a new object with an argument.
  89. template <typename Arg>
  90. Object* alloc(Arg arg)
  91. {
  92. Object* o = free_list_;
  93. if (o)
  94. free_list_ = object_pool_access::next(free_list_);
  95. else
  96. o = object_pool_access::create<Object>(arg);
  97. object_pool_access::next(o) = live_list_;
  98. object_pool_access::prev(o) = 0;
  99. if (live_list_)
  100. object_pool_access::prev(live_list_) = o;
  101. live_list_ = o;
  102. return o;
  103. }
  104. // Free an object. Moves it to the free list. No destructors are run.
  105. void free(Object* o)
  106. {
  107. if (live_list_ == o)
  108. live_list_ = object_pool_access::next(o);
  109. if (object_pool_access::prev(o))
  110. {
  111. object_pool_access::next(object_pool_access::prev(o))
  112. = object_pool_access::next(o);
  113. }
  114. if (object_pool_access::next(o))
  115. {
  116. object_pool_access::prev(object_pool_access::next(o))
  117. = object_pool_access::prev(o);
  118. }
  119. object_pool_access::next(o) = free_list_;
  120. object_pool_access::prev(o) = 0;
  121. free_list_ = o;
  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. // The list of live objects.
  135. Object* live_list_;
  136. // The free list.
  137. Object* free_list_;
  138. };
  139. } // namespace detail
  140. } // namespace asio
  141. } // namespace boost
  142. #include <boost/asio/detail/pop_options.hpp>
  143. #endif // BOOST_ASIO_DETAIL_OBJECT_POOL_HPP