Agoston Bejo wrote:
Hi!
Let's consider this function object:
template
struct mixed_plus :
public binary_function
{
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
// 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 {
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
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
{
typedef unsigned long type;
};
template<>
struct arith_result_helper
{
typedef unsigned long type;
};
#endif
template
struct arith_result
{
typedef typename arith_result_helper<
typename promote<T>::type, typename promote<U>::type>
::type type;
};