Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:43:08

0001 //
0002 // detail/object_pool.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // defined(_MSC_VER) && (_MSC_VER >= 1200)
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   // Constructor.
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   // Destructor destroys all objects.
0086   ~object_pool()
0087   {
0088     destroy_list(live_list_);
0089     destroy_list(free_list_);
0090   }
0091 
0092   // Get the object at the start of the live list.
0093   Object* first()
0094   {
0095     return live_list_;
0096   }
0097 
0098   // Allocate a new object with an argument.
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   // Free an object. Moves it to the free list. No destructors are run.
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   // Helper function to destroy all elements in a list.
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   // The list of live objects.
0153   Object* live_list_;
0154 
0155   // The free list.
0156   Object* free_list_;
0157 };
0158 
0159 } // namespace detail
0160 } // namespace asio
0161 } // namespace boost
0162 
0163 #include <boost/asio/detail/pop_options.hpp>
0164 
0165 #endif // BOOST_ASIO_DETAIL_OBJECT_POOL_HPP