简体   繁体   中英

Coupling memory pool allocator to various memory pools hosting the allocated instances

There is an stateless memory pool allocator class:

template<typename T>
class pool_allocator {
public:
    using value_type = T;
    using pointer = value_type *;

    /* Default constructor */
    constexpr pool_allocator( void ) noexcept = default;

    /* Converting constructor used for rebinding */
    template<typename U>
    constexpr pool_allocator( const pool_allocator<U> & ) noexcept {}

    [[nodiscard]] pointer allocate( size_t n, [[maybe_unused]] const pointer hint = nullptr ) const noexcept {
        return get_pool().allocate( n );
    }

    void deallocate( pointer ptr, size_t n ) const noexcept {
        get_pool().deallocate( ptr, n );
    }

private:
    /* Must be defined in particular .cpp files */
    /* POINT OF INTERREST HERE: */
    static auto & get_pool( void ) noexcept;
};

The logic behind is there is the specialization of get_pool() member function which is intended to return particular memory pool of defined type where the instance of T shall be allocated, for example:

class sample { ... };

in .cpp file:

memory_pool<sample, 10> sample_storage;  // memory pool capable of holding up to 10 instances of 'sample'

finally there comes the specialization of get_pool() function template in .cpp file:

template<>
auto & pool_allocator<sample>::get_pool( void ) noexcept {
    return sample_storage; // return the memory_pool instance defined above
}

The problem is such template specialization is available only in .cpp compilation unit and prevents the usage of auto get_pool() in other compilation unit ( the type of auto placeholder cannot be deduced as the body of get_pool() function template specialization is not available )

There fore I would like to somehow get rid of auto as return type of get_pool() .

The problem I face is mainly with the size of the memory_pool which is unknown to the allocator itself. Anyway, the memory_pool is also my implementation so I can du whatever adoptions required (eg further using declarations or whatever else is needed). Just a skeleton of it:

template<typename T, size_t CAPACITY>
class memory_pool {
public:
    using element_type = T;
    using pointer = element_type *;

    constexpr size_t capacity( void ) noexcept {
        return CAPACITY;
    }
...
};

Here is the solution I used - to implement the traits class which holds the information about the pool size:

template<typename T>
class memory_pool {
public:
    using traits = memory_pool_traits<T>;
    using element_type = typename traits::element_type;
    using pointer = element_type *;

    static constexpr size_t capacity { traits::capacity };
...
};

The allocator:

template<typename T>
class pool_allocator {
public:
    using value_type = T;
    using pointer = value_type *;

    /* Default constructor */
    constexpr pool_allocator( void ) noexcept = default;

    /* Converting constructor used for rebinding */
    template<typename U>
    constexpr pool_allocator( const pool_allocator<U> & ) noexcept {}

    [[nodiscard]] pointer allocate( size_t n, [[maybe_unused]] const pointer hint = nullptr ) const noexcept {
        return get_pool().allocate( n );
    }

    void deallocate( pointer ptr, size_t n ) const noexcept {
        get_pool().deallocate( ptr, n );
    }

private:
    static memory_pool<T> & get_pool( void ) noexcept;
};

For any particular type there shall be traits class:

// Primary template
template<typename T> struct memory_pool_traits;

Let there be the sample for which I would like to define the memory_pool :

class sample { ... };

...and aside of that the setup - the traits - for the respective memory_pool :

template<>
struct memory_pool_traits<sample> {
    using element_type = sample;
    static constexpr size_t capacity { 10 };
};

In the .cpp file there is the definition of the pool itself and the get_pool() function:

memory_pool<sample> sample_storage;

template<>
memory_pool<sample> & pool_allocator<sample>::get_pool( void ) noexcept {
    return sample_storage;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM