Boost logo

Boost :

From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2002-05-16 17:39:48


----- Original Message -----
From: "Herve Bronnimann" <hbr_at_[hidden]>
To: <boost_at_[hidden]>
Cc: <hbr_at_[hidden]>
Sent: Thursday, May 16, 2002 7:39 AM
Subject: [boost] Boost.(type|integer)_traits missing feature?

    boost::add_unsigned<T>::type returns the unsigned integral type,
                                    for builtin integral types (bool,
    char, short, int, long int, and
    their variants), and T otherwise

    boost::add_signed<T>::type returns the signed integral type,
                                    for builtin integral types (bool,
    char, short, int, long int, and
    their variants), and T otherwise

If you have a typelist of signed and unsigned integral types, you can do this in
a generic way like this:

------------------------

struct null_t; // list terminator

// typelist_t

template<class T, class U = null_t>
struct typelist_t {
    typedef T head;
    typedef U tail;
};

// typelist of unsigned integrals
// (unsigned on all platforms, that is)
typedef
typelist_t<
    unsigned char,
    typelist_t<
        unsigned short,
        typelist_t<
            unsigned,
            typelist_t<unsigned long>
>
>
> unsigned_integral_types;

// typelist of signed integrals
// (signed on all platforms, i.e. not 'char' or 'wchar_t', etc.)
typedef
typelist_t<
    signed char,
    typelist_t<
        short,
        typelist_t<
            int,
            typelist_t<long>
>
>
> signed_integral_types;

// compare the sizes of two types:

template<class A, class B>
struct is_same_size {
    static const bool value = sizeof(A) == sizeof(B);
};

template<class A, class B>
const bool is_same_size<A, B>::value;

// matching algorithm for typelists

template<
    class TL, // a typelist
    class T, // some type
    template<class, class> class op
        // operation to compare
        // T and each type in the typelist
        // until the operation 'returns' true
>
struct match;

template<
    class head,
    class T,
    template<class, class> class op
>
struct match<typelist_t<head, null_t>, T, op> {
    typedef typename
    select<op<head, T>::value, head, null_t>::type type;
};

template<
    class head,
    class tail,
    class T,
    template<class, class> class op
>
struct match<typelist_t<head, tail>, T, op> {
    typedef typename
    select<op<head, T>::value, head,
        typename match<tail, T, op>::type>::type type;
};

// get a signed or unsigned equivalently sized integral type
// note, this will even attempt to find a
// matching size integral for 'bool' or 'wchar_t' if possible

template<class T, class = unsigned>
struct numeric_equiv;

template<class T>
struct numeric_equiv<T, unsigned> {
    typedef typename
    select<!std::numeric_limits<T>::is_signed, T,
        typename match<unsigned_integral_types, T, is_same_size>::type
>::type type;
};

template<class T>
struct numeric_equiv<T, signed> {
    typedef typename
    select<std::numeric_limits<T>::is_signed, T,
        typename match<signed_integral_types, T, is_same_size>::type
>::type type;
};

-----------------

With this you can write:

numeric_equiv<T, unsigned>::type

-or-

numeric_equiv<T, signed>::type

--and it isn't machine-specific. Of course, this isn't Boost stuff, but maybe
the MPL has something like it. :)

Does this help?

Paul Mensonides


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk