Boost logo

Boost :

Subject: [boost] Range-aware version of min and max
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2010-01-25 09:54:48


I am often frustrated by the inability of std::min and std::max to deal with
data types of different ranges. For example:

boost::uint64_t big = 9876543210ULL;
boost::uint32_t small = 12345;

boost::uint32_t smallest = std::min(big, small);

will generate a compiler warning about possible loss of data due to
converting from boost::uint64_t to boost::uint32_t. Obviously such a
scenario is impossible since by definition the result can be no larger than
the maximum value of a uint32.

Previously there was a discussion on the list about adding operators such as
is_addable, is_multipliable, is_less_comparable, etc. Using such a class,
one could re-write min and max as follows (I'm sure someone will come up
with a problem with this, or a better implementation, but anyway the idea
should be clear):

namespace boost {

template<class A, class B>
struct min_result
{
   typedef mpl::if_c<(integer_traits<A>::const_max <
integer_traits<B>::const_max), A, B>::type type;
};

template<class A, class B>
struct max_result
{
   typedef mpl::if_c<(integer_traits<A>::const_min >
integer_traits<B>::const_min), A, B>::type type;
};

template<class A, class B>
min_result<A,B>::type
min(const A& a, const B& b)
{
   return static_cast<min_result<A,B>::type>((a < b) ? a : b);
}

template<class A, class B>
max_result<A,B>::type
max(const A& a, const B& b)
{
   return static_cast<max_result<A,B>::type>((a > b) ? a : b);
}

I'm sure there's some implementation details I haven't considered, but is
there any fundamental reason why an approach like this would be flawed or
undesirable?

Zach


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