challenge: implement the max function
Don Clugston
dac at nospam.com.au
Mon Jan 22 01:17:26 PST 2007
Alain wrote:
> Don Clugston Wrote:
>
>> Andrei Alexandrescu (See Website For Email) wrote:
>>> Here's a simple challenge: implement the max function. Requirements:
>>>
>>> a) generic
>>> b) efficient
>>> c) preserve lvalueness when possible such that one can write e.g.
>>>
>>> max(arr[0], arr[1]) *= 0.9;
>>>
>>> d) should accept two or more arguments
>>> e) should return the "smartest" type, e.g. max of an unsigned int and
>>> unsigned long should return unsigned long
>>> f) short and easy to understand
>>>
>>> I don't think it's possible to implement the function to the spec in
>>> current D, so designs are allowed to invent new features, as long as
>>> they define them thoroughly.
>>>
>>> Looking forward to any takers!
>>>
>>>
>>> Andrei
>> ----
>> Here's an implementation I put into Tango a few days ago. Unlike some
>> other ones which have been posted, it does *not* require the types to
>> support operator '+'. This was only for two arguments, but I believe it
>> satisfies the other requirements. Should be easy to generalise.
>>
>> ----
>>
>> private {
>> // Implicitly convert to the smallest type which can store both T
>> and U; acts like an 'auto' template return type.
>> template SharedComparisonType(T, U) {
>> static if (is( typeof( (T x, U y){ return y<x? y: x;}) Q == return))
>> alias Q SharedComparisonType;
>> }
>> }
>>
>>
>> /** Return the minimum of x and y.
>> *
>> * Note: If x and y are floating-point numbers, and either is a NaN,
>> * x will be returned.
>> */
>> SharedComparisonType!(T, U) min(T, U)(T x, U y) {
>> return y<x? y : x;
>> }
>>
>> /** Return the maximum of x and y.
>> *
>> * Note: If x and y are floating-point numbers, and either is a NaN,
>> * x will be returned.
>> */
>> SharedComparisonType!(T,U) max(T, U)(T x, U y) {
>> return y>x? y : x;
>> }
>
> Fine !
> but it doesn't work for the following common use case:
> int[] mylist=[1,2,3,4,5];
> int mymax=max(mylist);
>
> Alain
Yes, as I said, it only works for the two-argument case.
It was intended as a direct replacement for C's
#define max(a, b) ((a)>(b)?(a):(b))
Just (for example) use Xinok's code, and replace typeof(X+Y) with
SharedComparisonType!(X, Y).
Still doesn't solve (c) though; that's a really interesting challenge.
But since ?: doesn't preserve lvalues (ie, the following doesn't compile):
real a = 5.2;
real b = 3.1;
(a> b? a : b) *= 0.7;
it seems to me that it's not really a template issue, but rather
something even more fundamental.
(Interestingly, auto c = (a> b? a : b).max; does compile; but if b is
an int, and a is a real, it always returns real.max, even if b<a).
More information about the Digitalmars-d
mailing list