Boost logo

Boost :

From: Alexander Nasonov (alnsn-boost_at_[hidden])
Date: 2005-06-21 16:56:32


Class template integral_promotion<T> returns promoted type for all types
listed in [conv.prom] except bit-fields. For other types it's noop. If
you're interested I can try to boostify it.

--
Alexander Nasonov
//
// integral_promotion.hpp
//
#include <boost/mpl/at.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_same.hpp>
template<class T>
struct is_short_integer
  : boost::mpl::or_<
        boost::is_same<T, char>
      , boost::is_same<T, signed char>
      , boost::is_same<T, unsigned char>
      , boost::is_same<T, signed short>
      , boost::is_same<T, unsigned short>
      >
{
};
template<int N>
struct sized_type
{
    typedef char (&type)[N];
};
sized_type<1>::type tester(int);
sized_type<2>::type tester(unsigned int);
sized_type<3>::type tester(long);
sized_type<4>::type tester(unsigned long);
template<class T>
struct integral_promotion_impl
{
    static T testee; // undefined
    typedef typename boost::mpl::at_c<
        boost::mpl::vector<int, unsigned int, long, unsigned long>
      , sizeof(tester(+testee)) - 1
        // Unary plus ^ promotes testee.
      >::type type;
};
template<class T>
struct integral_promotion
  : boost::mpl::eval_if<
        boost::mpl::or_<
            is_short_integer<T>
          , boost::is_same<T,bool>
          , boost::is_enum<T>
          >
      , integral_promotion_impl<T>
      , boost::mpl::identity<T>
      >
{
};
//
// test.cpp
//
// Tested on gcc 3.4.4 (cygming special) and
// Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for
80x86
#include "integral_promotion.hpp"
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
enum IntEnum { IntEnum_max = 1 };
int main()
{
    BOOST_MPL_ASSERT(( boost::is_same< integral_promotion<char>::type,
int> ));
    BOOST_MPL_ASSERT(( boost::is_same< integral_promotion<bool>::type,
int> ));
    BOOST_MPL_ASSERT(( boost::is_same< integral_promotion<int>::type,
int> ));
    BOOST_MPL_ASSERT(( boost::is_same< integral_promotion<long>::type,
long> ));
    BOOST_MPL_ASSERT(( boost::is_same< integral_promotion<IntEnum>::type,
int> ));
}

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