$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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