Boost logo

Boost :

Subject: Re: [boost] Range-aware version of min and max
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2010-01-26 17:36:32


On Mon, Jan 25, 2010 at 10:19 AM, Niels Dekker - address until 2010-10-10 <
niels_address_until_2010-10-10_at_[hidden]> wrote:

> Zachary Turner wrote:
>
>> 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.
>>
>
> It doesn't seem to compile: http://codepad.org/IiFba8MF I guess you mean:
>
> boost::uint32_t smallest = std::min<boost::uint32_t>(big, small);
>
> 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 (...):
>>
>>
>> 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);
>> }
>>
>
> Excuse me, where do you use is_addable, is_multipliable,
> is_less_comparable?

I don't use is_addable, is_multipliable, but is_less_comparable should be
needed in order to determine if min is even a valid operation, and
is_greater_comparable would be needed to determine if max is a valid
operation, right? I only mentioned the others because the implementations
are all equivalent.

>
>
>
> 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?
>>
>
> I think your suggestion is quite reasonable, but I see two drawbacks:
>
> * It only seems to support numeric types. Why not support the minimum of
> two datetime objects, or the minimun of two std::string objects?
>
Seems reasonable, but how would it select which type is to be returned? My
original idea was that it would simply return whichever type had a smaller
max (or larger min, depending on the operation). At first glance it appears
more difficult to deal with this problem in a completely generic fashion
when we bring in arbitrary types.

>
> * It returns by-value. In general, I prefer min/max to return a reference
> to the object itself, instead of a copy. Like std::min and std::max
> (C++03).
>
> Both drawbacks could be avoided by renaming your function, for example to
> numeric_min_value.

I like that idea. Although we might as well still return by reference.

Are there any potential problems with using sizeof() to determine which type
to return? Is there a better method that is more aware of the actual ranges
supported by the types?

Zach


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