Reputation: 45414
I want to have a little class which manages raw memory with this API
template<class allocator = std::allocator<char> >
class raw_memory
{
static_assert(std::is_same<char, typename allocator::value_type>::value,
"raw_memory: allocator must deal in char");
public:
raw_memory() = default;
raw_memory(raw_memory&&) = default;
raw_memory&operator=(raw_memory&&) = default;
explicit raw_memory(size_t, allocator const& = allocator());
~raw_memory(); // deletes any memory
char*get(); // returns pter to (begin of) memory
void resize(size_t); // re-allocates if necessary, may delete old data
size_t size() const; // returns number of bytes currently hold
raw_memory(raw_memory const&) = delete;
raw_memory&operator=(raw_memory const&) = delete;
raw_memory(raw_memory&) = delete;
raw_memory&operator=(raw_memory&) = delete;
};
The template parameter allocator
allows for different memory alignment options.
I was thinking about using std::unique_ptr<char, Deleter>
, as a member (or base) (plus a size_t
holding the number of bytes). What to use as Deleter? Or is there a better way to achieve all that?
Upvotes: 1
Views: 1685
Reputation: 10797
Since you let the users of your class to specify an allocator as a type argument, you must reference this argument for both allocation and deallocation. For this reason, the commend made by @Kerrek (although tricky and nice usage of pointer to function) is invalid, because you do want to use the allocator methods passed as an argument.
Using unique_ptr can work for you. As you correctly commented you must provide your own deleter, and per my comments above, it must be based on the allocator class passed as an agument to your template.
SIDE NOTE: Please be aware you have a syntax error in your template declaration. See my sample code below for the correct syntax (i.e. you must have the keyword 'template'):
template< class A = std::allocator<char> >
class raw_memory
{
private:
A m_al;
std::unique_ptr< char, std::function<void(char*)> > m_buffer;
public:
raw_memory( size_t size, const A& al = A() )
:m_al(al)
,m_buffer( m_al.allocate(size), [this, size](char* ptr){ m_al.deallocate(ptr,size); } )
{
}
};
Few things to note:
Upvotes: 2