Background
This is for a memory manager in a game engine. I have a freelist
implemented, and would like to have a compile-time list if these. (A MPL or Fusion vector, for example). The freelist
's correspond to allocation sizes, and when allocating/deallocating objects of size less than a constant, they will go to the corresponding freelist
.
In the end, this means small objects globally have amortized constant time allocation and constant time deallocation. (Yay.)
Problem
The problem is generating the types I need, so I may eventually use Fusion to instantiate those types. The types in use are (shortened, etc.):
template <size_t N>
struct data_block
{
size_t mSize; // = N
char mData[N];
};
template <typename T, size_t ElementsPerPage,
template <typename> class Allocator = std::allocator >
class freelist { /* ... */ };
template <typename T>
class callocator; // allocator that uses malloc/free
The freelist
's will manage data_block
's of power-of-2 sizes, starting from a minimum going to a maximum. So what I want is:
static const size_t MinimumSmallSize = 4; // anything smaller gets rounded up
static const size_t MaximumSmallSize = 512; // anything bigger goes to the large allocator
static const size_t ElementsPerPage = 4096;
// mpl magic
To generate this:
typedef boost::mpl::vector<
freelist<data_block<4>, ElementsPerPage, callocator>,
freelist<data_block<8>, ElementsPerPage, callocator>
// ...
freelist<data_block<256>, ElementsPerPage, callocator>
freelist<data_block<512>, ElementsPerPage, callocator>
> free_list_collection;
Obviously, I could do this by hand but I'd rather avoid that for a more general and tweakable interface. Using the Fusion vector in code should be simpler than hard-coded members, too.
Question
I'm not sure the best way to go about this; I've never used MPL extensively before. Any ideas? I had a few poor ideas such as making a range, then remove_if
it's not power of 2, etc., but surely that's not best. Maybe something recursive instead, that doubles each time, pushing into my result vector? I'm not sure how to go about that.