pool_allocator.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright (c) 2006-2018 Maxim Khizhinsky
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef CDSLIB_MEMORY_POOL_ALLOCATOR_H
  6. #define CDSLIB_MEMORY_POOL_ALLOCATOR_H
  7. #include <cds/details/defs.h>
  8. #include <utility>
  9. namespace cds { namespace memory {
  10. ///@defgroup cds_memory_pool Simple memory pool
  11. /// Pool allocator adapter
  12. /**
  13. This class is an adapter for an object pool. It gives \p std::allocator interface
  14. for the @ref cds_memory_pool "pool".
  15. Template arguments:
  16. - \p T - value type
  17. - \p Accessor - a functor to access to the pool object. The pool has the following interface:
  18. \code
  19. template <typename T>
  20. class pool {
  21. typedef T value_type ; // Object type maintained by pool
  22. T * allocate( size_t n ) ; // Allocate an array of object of type T
  23. void deallocate( T * p, size_t n ) ; // Deallocate the array p of size n
  24. };
  25. \endcode
  26. <b>Usage</b>
  27. Suppose, we have a pool with interface above. Usually, the pool is a static object:
  28. \code
  29. static pool<Foo> thePool;
  30. \endcode
  31. The \p %pool_allocator gives \p std::allocator interface for the pool.
  32. It is needed to declare an <i>accessor</i> functor to access to \p thePool:
  33. \code
  34. struct pool_accessor {
  35. typedef typename pool::value_type value_type;
  36. pool& operator()() const
  37. {
  38. return thePool;
  39. }
  40. };
  41. \endcode
  42. Now, <tt>cds::memory::pool_allocator< T, pool_accessor > </tt> can be used instead of \p std::allocator.
  43. */
  44. template <typename T, typename Accessor>
  45. class pool_allocator
  46. {
  47. //@cond
  48. public:
  49. typedef Accessor accessor_type;
  50. typedef size_t size_type;
  51. typedef ptrdiff_t difference_type;
  52. typedef T* pointer;
  53. typedef const T* const_pointer;
  54. typedef T& reference;
  55. typedef const T& const_reference;
  56. typedef T value_type;
  57. template <class U> struct rebind {
  58. typedef pool_allocator<U, accessor_type> other;
  59. };
  60. public:
  61. pool_allocator() noexcept
  62. {}
  63. pool_allocator(const pool_allocator&) noexcept
  64. {}
  65. template <class U> pool_allocator(const pool_allocator<U, accessor_type>&) noexcept
  66. {}
  67. ~pool_allocator()
  68. {}
  69. pointer address(reference x) const noexcept
  70. {
  71. return &x;
  72. }
  73. const_pointer address(const_reference x) const noexcept
  74. {
  75. return &x;
  76. }
  77. pointer allocate( size_type n, void const * /*hint*/ = 0)
  78. {
  79. static_assert( sizeof(value_type) <= sizeof(typename accessor_type::value_type), "Incompatible type" );
  80. return reinterpret_cast<pointer>( accessor_type()().allocate( n ));
  81. }
  82. void deallocate(pointer p, size_type n) noexcept
  83. {
  84. accessor_type()().deallocate( reinterpret_cast<typename accessor_type::value_type *>( p ), n );
  85. }
  86. size_type max_size() const noexcept
  87. {
  88. return size_t(-1) / sizeof(value_type);
  89. }
  90. template <class U, class... Args>
  91. void construct(U* p, Args&&... args)
  92. {
  93. new((void *)p) U( std::forward<Args>(args)...);
  94. }
  95. template <class U>
  96. void destroy(U* p)
  97. {
  98. p->~U();
  99. }
  100. //@endcond
  101. };
  102. }} // namespace cds::memory
  103. #endif // #ifndef CDSLIB_MEMORY_POOL_ALLOCATOR_H