/* 

Sometimes you need to calculate at compile time the biggest object to
statically allocate pools or arrays.

The Big template returns the size of the biggest object.
The BigT template returns the type of the biggest object.

As they are recursive template, you can use them with as many types as you
want ( see sample use ).

This is probably common knowledge but it took use quite a while to figure
out a good way to do it without macros ....

*/

// Return the size of the biggest type.
template <class a, class b>
class Big
{
public:
      static const unsigned int Res = sizeof(a) > sizeof(b) ? sizeof(a) : sizeof(b);
};

template <class a,class b,class c>
class Big<Big<a,b>,c>
{
public:
      static const unsigned int Res = Big<a,b>::Res > sizeof(c) ? Big<a,b>::Res : sizeof(c);
};

template <class a,class b,bool First>
class Rank
{
public:
      typedef a Res;
};

template <class a,class b>
class Rank <a,b,false>
{
public:
      typedef b Res;
};

// Return the type of the biggest type.
template <class a,class b>
class BigT
{
public:
      typedef Rank<a,b,(sizeof(a) > sizeof(b))>::Res Res;
};

template <class a,class b,class c>
class BigT<BigT<a,b>,c>
{
public:
      typedef Rank<BigT<a,b>,c,(sizeof(BigT<a,b>::Res) > sizeof(c))>::Res Res;
};


// Sample use.

class a
{
      int m_a;
};

class b
{
      short m_b;
};

class c
{
      char m_c;
};

// Allocate the memory needed to store 8 of the biggest from a,b,c.

const int BiggestTypeSize = Big<Big<a,b>,c>::Res;

char MyMem[BiggestTypeSize * 8];

// Allocate an array of 8 elements of the biggest from a,b,c.

typedef BigT<BigT<a,b>,c>::Res BiggestType;

BiggestType MyArray[8];

// Unit test.

static bool TestA = Big<Big<a,b>,c>::Res == sizeof(int); // Should be 1.

static bool TestB = sizeof(BigT<BigT<a,b>,c>::Res) == sizeof(int); // Should be 1.


Laurent Benadiba & Dushan Leska