Skip to content

Instantly share code, notes, and snippets.

@thierryseegers
Last active December 3, 2015 17:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thierryseegers/47a95342a4d1ae1191b4 to your computer and use it in GitHub Desktop.
Save thierryseegers/47a95342a4d1ae1191b4 to your computer and use it in GitHub Desktop.
Allocate [n times T]+ in a single block of memory
using memory_block = std::unique_ptr<uint8_t[]>;
namespace detail
{
template<typename T>
std::size_t block_size(T* const, std::size_t const n)
{
return sizeof(T) * n + alignof(T) - 1;
}
template<typename T, typename U, typename... Args>
std::size_t block_size(T* const t, std::size_t const m, U* const u, std::size_t const n, Args&&... args)
{
return block_size(t, m) + block_size(u, n, args...);
}
template<typename T>
void block_assign(void*& p, std::size_t& space, T*& t, std::size_t const n)
{
t = reinterpret_cast<T*>(std::align(alignof(T), sizeof(T) * n, p, space));
p = reinterpret_cast<memory_block::element_type*>(p) + sizeof(T) * n;
space -= sizeof(T) * n;
}
template<typename T, typename... Args>
void block_assign(void*& p, std::size_t& space, T*& t, std::size_t const n, Args&&... args)
{
block_assign(p, space, t, n);
block_assign(p, space, args...);
}
}
template<typename T, typename... Args>
memory_block block_allocate(T*& t, std::size_t const n, Args&&... args)
{
std::size_t space = detail::block_size(t, n, args...);
memory_block b = std::make_unique<memory_block::element_type[]>(space);
void *p = b.get();
detail::block_assign(p, space, t, n, args...);
return b;
}
// Usage example.
// We want to allocate 6 integers, 4 floats and 12 chars all from within a single block of contiguous memory.
int *integers = nullptr;
float *floats = nullptr;
char *chars = nullptr;
auto const block = block_allocate(integers, 6, floats, 4, chars, 12);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment