| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- // Copyright (c) 2006-2018 Maxim Khizhinsky
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
- #ifndef CDSLIB_MEMORY_POOL_ALLOCATOR_H
- #define CDSLIB_MEMORY_POOL_ALLOCATOR_H
- #include <cds/details/defs.h>
- #include <utility>
- namespace cds { namespace memory {
- ///@defgroup cds_memory_pool Simple memory pool
- /// Pool allocator adapter
- /**
- This class is an adapter for an object pool. It gives \p std::allocator interface
- for the @ref cds_memory_pool "pool".
- Template arguments:
- - \p T - value type
- - \p Accessor - a functor to access to the pool object. The pool has the following interface:
- \code
- template <typename T>
- class pool {
- typedef T value_type ; // Object type maintained by pool
- T * allocate( size_t n ) ; // Allocate an array of object of type T
- void deallocate( T * p, size_t n ) ; // Deallocate the array p of size n
- };
- \endcode
- <b>Usage</b>
- Suppose, we have a pool with interface above. Usually, the pool is a static object:
- \code
- static pool<Foo> thePool;
- \endcode
- The \p %pool_allocator gives \p std::allocator interface for the pool.
- It is needed to declare an <i>accessor</i> functor to access to \p thePool:
- \code
- struct pool_accessor {
- typedef typename pool::value_type value_type;
- pool& operator()() const
- {
- return thePool;
- }
- };
- \endcode
- Now, <tt>cds::memory::pool_allocator< T, pool_accessor > </tt> can be used instead of \p std::allocator.
- */
- template <typename T, typename Accessor>
- class pool_allocator
- {
- //@cond
- public:
- typedef Accessor accessor_type;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T value_type;
- template <class U> struct rebind {
- typedef pool_allocator<U, accessor_type> other;
- };
- public:
- pool_allocator() noexcept
- {}
- pool_allocator(const pool_allocator&) noexcept
- {}
- template <class U> pool_allocator(const pool_allocator<U, accessor_type>&) noexcept
- {}
- ~pool_allocator()
- {}
- pointer address(reference x) const noexcept
- {
- return &x;
- }
- const_pointer address(const_reference x) const noexcept
- {
- return &x;
- }
- pointer allocate( size_type n, void const * /*hint*/ = 0)
- {
- static_assert( sizeof(value_type) <= sizeof(typename accessor_type::value_type), "Incompatible type" );
- return reinterpret_cast<pointer>( accessor_type()().allocate( n ));
- }
- void deallocate(pointer p, size_type n) noexcept
- {
- accessor_type()().deallocate( reinterpret_cast<typename accessor_type::value_type *>( p ), n );
- }
- size_type max_size() const noexcept
- {
- return size_t(-1) / sizeof(value_type);
- }
- template <class U, class... Args>
- void construct(U* p, Args&&... args)
- {
- new((void *)p) U( std::forward<Args>(args)...);
- }
- template <class U>
- void destroy(U* p)
- {
- p->~U();
- }
- //@endcond
- };
- }} // namespace cds::memory
- #endif // #ifndef CDSLIB_MEMORY_POOL_ALLOCATOR_H
|