I'm trying to implement a class that's followed in memory by an array of some arbitrary type:
template<class T>
class Buf
{
size_t n;
int refs;
explicit Buf(size_t n) : n(n) { }
// other declarations are here as appropriate
// Followed in memory by:
// T items[n];
};
This would be easy with operator new
:
template<class T>
Buf<T> *make_buf(size_t n)
{
// Assume the caller will take care of constructing the array elements
return new(operator new(sizeof(Buf<T>) + sizeof(T) * n)) Buf<T>(n);
}
template<class T>
void free_buf(Buf<T> *p)
{
// Assume the caller has taken care of destroying the array elements
p->~Buf<T>();
return operator delete(p);
}
template<class T>
T *get_buf_array(Buf<T> *p)
{
return reinterpret_cast<T *>(reinterpret_cast<char *>(p) + sizeof(Buf<T>));
}
But now, how do I implement this using some standard-compliant allocator SomeAllocator
?
Is it guaranteed that SomeAllocator::rebind<char>::other::allocate
will return memory suitably aligned for any type of object? If so, am I otherwise safe to just use an allocator of some char type? If not, do I have any alternatives, or is this task impossible with allocators in general? (In the worst case I suppose I could cast the pointers to uintptr_t
and align them manually, but I'm wondering if there's a better way.)