|
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