object_pool.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. #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>
  31. static void destroy(Object* o)
  32. {
  33. delete o;
  34. }
  35. template <typename Object>
  36. static Object*& next(Object* o)
  37. {
  38. return o->next_;
  39. }
  40. template <typename Object>
  41. static Object*& prev(Object* o)
  42. {
  43. return o->prev_;
  44. }
  45. };
  46. template <typename Object>
  47. class object_pool
  48. : private noncopyable
  49. {
  50. public:
  51. // Constructor.
  52. object_pool()
  53. : live_list_(0),
  54. free_list_(0)
  55. {
  56. }
  57. // Destructor destroys all objects.
  58. ~object_pool()
  59. {
  60. destroy_list(live_list_);
  61. destroy_list(free_list_);
  62. }
  63. // Get the object at the start of the live list.
  64. Object* first()
  65. {
  66. return live_list_;
  67. }
  68. // Allocate a new object.
  69. Object* alloc()
  70. {
  71. Object* o = free_list_;
  72. if (o)
  73. free_list_ = object_pool_access::next(free_list_);
  74. else
  75. o = object_pool_access::create<Object>();
  76. object_pool_access::next(o) = live_list_;
  77. object_pool_access::prev(o) = 0;
  78. if (live_list_)
  79. object_pool_access::prev(live_list_) = o;
  80. live_list_ = o;
  81. return o;
  82. }
  83. // Free an object. Moves it to the free list. No destructors are run.
  84. void free(Object* o)
  85. {
  86. if (live_list_ == o)
  87. live_list_ = object_pool_access::next(o);
  88. if (object_pool_access::prev(o))
  89. {
  90. object_pool_access::next(object_pool_access::prev(o))
  91. = object_pool_access::next(o);
  92. }
  93. if (object_pool_access::next(o))
  94. {
  95. object_pool_access::prev(object_pool_access::next(o))
  96. = object_pool_access::prev(o);
  97. }
  98. object_pool_access::next(o) = free_list_;
  99. object_pool_access::prev(o) = 0;
  100. free_list_ = o;
  101. }
  102. private:
  103. // Helper function to destroy all elements in a list.
  104. void destroy_list(Object* list)
  105. {
  106. while (list)
  107. {
  108. Object* o = list;
  109. list = object_pool_access::next(o);
  110. object_pool_access::destroy(o);
  111. }
  112. }
  113. // The list of live objects.
  114. Object* live_list_;
  115. // The free list.
  116. Object* free_list_;
  117. };
  118. } // namespace detail
  119. } // namespace asio
  120. } // namespace boost
  121. #include <boost/asio/detail/pop_options.hpp>
  122. #endif // BOOST_ASIO_DETAIL_OBJECT_POOL_HPP