Getting the largest type available

Well, depending on how badly you need this, you can try some serious metaprograming here...

Firstly, you will obviously need some kind of "pack" defining all available primitive types, so here it is:

template<typename... TYPES>
class pack
{};

typedef pack<float, double, long double, unsigned short, unsigned int,
    unsigned long, unsigned long long, short, int, long, long long> primitive_types;

Then you will need a way to sort these types in respect to size, so firstly, lets define a metafunction able to implement a strict weak ordering for the sizes:

template<typename L, typename R>
class smaller
{
    public:
        static const bool value = sizeof(L) < sizeof(R);
};

Now, the sorting algorithm. Here I've arbitrarily chosen merge sort, which required 3 other metafunctions: pack_cat for concatenating packs, pack_merge for merging them according to the order, and halve for breaking packs in 2 other packs.

template<typename, typename>
class pack_cat;

template<typename... L, typename... R>
class pack_cat<pack<L...>, pack<R...>>
{
    public:
        typedef pack<L..., R...> type;
};

template<template<typename, typename> class, typename, typename>
class pack_merge;

template<template<typename, typename> class MF, typename HL, typename... TL, typename HR, typename... TR>
class pack_merge<MF, pack<HL, TL...>, pack<HR, TR...>>
{
    public:
        typedef typename std::conditional<MF<HR, HL>::value,
                typename pack_cat<pack<HR>, typename pack_merge<MF, pack<HL, TL...>, pack<TR...>>::type>::type,
                typename pack_cat<pack<HL>, typename pack_merge<MF, pack<TL...>, pack<HR, TR...>>::type>::type>::type type;
};

template<template<typename, typename> class MF, typename H, typename... T>
class pack_merge<MF, pack<H, T...>, pack<>>
{
    public:
        typedef pack<H, T...> type;
};

template<template<typename, typename> class MF, typename... R>
class pack_merge<MF, pack<>, pack<R...>>
{
    public:
        typedef pack<R...> type;
};

template<typename>
class halve;

template<typename A, typename B, typename... T>
class halve<pack<A, B, T...>>
{
    public:
        typedef typename pack_cat<pack<A>, typename halve<pack<T...>>::L>::type L;
        typedef typename pack_cat<pack<B>, typename halve<pack<T...>>::R>::type R;
};

template<typename T>
class halve<pack<T>>
{
    public:
        typedef pack<T> L;
        typedef pack<> R;
};

template<>
class halve<pack<>>
{
    public:
        typedef pack<> L;
        typedef pack<> R;
};

template<template<typename, typename> class MF, typename P>
class pack_sort
{
    private:
        typedef typename halve<P>::L L;
        typedef typename halve<P>::R R;

    public:
        typedef typename pack_merge<MF, typename pack_sort<MF, L>::type, typename pack_sort<MF, R>::type>::type type;
};

template<template<typename, typename> class MF, typename H>
class pack_sort<MF, pack<H>>
{
    public:
        typedef pack<H> type;
};

template<template<typename, typename> class MF>
class pack_sort<MF, pack<>>
{
    public:
        typedef pack<> type;
};

Lastly you will need a metafunction for retrieving the last argument of a pack, which is straightforward to implement:

template<typename>
class pack_get_last;

template<typename H, typename... T>
class pack_get_last<pack<H, T...>>
{
    public:
        typedef typename pack_get_last<pack<T...>>::type type;

};

template<typename H>
class pack_get_last<pack<H>>
{
    public:
        typedef H type;
};

Now, a test program to prove you that all this junk code I wrote up there actually works:

#include <iostream>
#include <utility>

/* all those metafunctions come here */

int main()
{
    typename pack_get_last<typename pack_sort<smaller, primitive_types>::type>::type largest;

    if(std::is_same<decltype(largest), long double>::value)
        std::cout << "MATCH!\n";
}

Output in a x64 Linux machine using gcc 4.6, where long double is the largest available simple primitive type:

MATCH!

No, this isn't possible. However, you can pretty much guarantee that 64bit is the largest type- I don't know of any compiler that offers 128bit. Failing that, get your user to pass it in as a template parameter or use compiler-specific defines to make a typedef.


For integer types only, you can use the <cstdint> header, which allows you to do:

std::intmax_t largest;

I'm not aware of any such functionality that includes floating points types, though.