Boost logo

Boost Users :

From: Ben Hutchings (ben.hutchings_at_[hidden])
Date: 2004-12-06 10:02:40


Agoston Bejo wrote:
> Hi!
> Let's consider this function object:
>
>
> template<typename TLeft, typename TRight>
> struct mixed_plus :
> public binary_function<TLeft, TRight, TLeft>
> {
> result_type operator()
> (first_argument_type left, second_argument_type right)
> const
> {
> return left + right;
> }
> };

I think it could be:
     typedef decltype(*(const TLeft *)0 + *(const TRight *)0)
         result_type;
except that decltype is merely a proposal at the moment.

If you're only interested in arithmetic on built-in types, I wrote some
code a while back that computes arithmetic result types.

Ben.

#include <boost/mpl/if.hpp>

// We can't call the min() and max() functions in
// std::numeric_limits<T> so we must use the old C macros to get
// the limits of each type.
#include <climits>
#include <cwchar>

// PROMOTE_HELPER tests whether a low-ranked type should be
// promoted to int or to unsigned int, according to standard
// section 4.5 paragraph 1. It is probably possible to write this
// as a template but I don't see how.
#define PROMOTE_HELPER(min, max) \
     typedef boost::mpl::if_c<min >= INT_MIN && max <= INT_MAX, \
                              int, unsigned int>::type \
         type;

// The default is not to promote.
template<typename T> struct promote { typedef T type; };
// The following specialisations cover the various types that
// are always promoted by the usual arithmetic conversions.
template<> struct promote<bool> { typedef int type; };
template<> struct promote<char> {
     PROMOTE_HELPER(CHAR_MIN, CHAR_MAX)
};
template<> struct promote<signed char> {
     PROMOTE_HELPER(SCHAR_MIN, SCHAR_MAX)
};
template<> struct promote<unsigned char> {
     PROMOTE_HELPER(0, UCHAR_MAX)
};
template<> struct promote<short> {
     PROMOTE_HELPER(SHRT_MIN, SHRT_MAX)
};
template<> struct promote<unsigned short> {
     PROMOTE_HELPER(0, USHRT_MAX)
};
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<> struct promote<wchar_t> {
     typedef boost::mpl::if_c<
         WCHAR_MIN >= INT_MIN && WCHAR_MAX <= INT_MAX,
         int,
         boost::mpl::if_c<
             WCHAR_MIN >= 0 && WCHAR_MAX <= UINT_MAX,
             unsigned,
             boost::mpl::if_c<
                 WCHAR_MIN >= LONG_MIN && WCHAR_MAX <= LONG_MAX,
                 long, unsigned long>::type>::type>::type
         type;
};
#endif

template<typename T> struct rank;
template<> struct rank<int> { enum { value = 0 }; };
template<> struct rank<unsigned> { enum { value = 1 }; };
template<> struct rank<long> { enum { value = 2 }; };
template<> struct rank<unsigned long> { enum { value = 3 }; };
template<> struct rank<float> { enum { value = 4 }; };
template<> struct rank<double> { enum { value = 5 }; };
template<> struct rank<long double> { enum { value = 6 }; };

template<typename T, typename U>
struct arith_result_helper
{
     typedef typename boost::mpl::if_c<
         rank<T>::value >= rank<U>::value, T, U>::type
         type;
};
#if UINT_MAX > LONG_MAX
     template<>
     struct arith_result_helper<unsigned, long>
     {
         typedef unsigned long type;
     };
     template<>
     struct arith_result_helper<long, unsigned>
     {
         typedef unsigned long type;
     };
#endif

template<typename T, typename U>
struct arith_result
{
     typedef typename arith_result_helper<
         typename promote<T>::type, typename promote<U>::type>
         ::type type;
};


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net