max() in phobos?

Bill Baxter wbaxter at gmail.com
Tue Nov 7 13:45:04 PST 2006


Sean Kelly wrote:
> Bill Baxter wrote:
> 
>> Is there a generic 'max' function anywhere in phobos?
>> The closest I could find was std.math.fmax().
> 
> 
> Not that works for all input types, as far as I know.  However, 
> something like the code below should work.  This is off the top of my 
> head so it may have bugs, but it's a general idea of what such a 
> template function may need to do.

Great!  How do we get it into std.math?

Here's one with the typos fixed and unittests:

/**
  * Returns the largest of the two supplied types, or the first type if
  * the sizes are identical.  If either type is an object then both must
  * be objects of either the same type or where one is a base class of
  * the other.  Interfaces are not supported.
  */
template largestOrConvertible( T, U )
{
     static if( is( T : Object ) || is( U : Object ) )
     {
         static assert( is( T : Object ) && is( U : Object ),
                        "Types incompatible." );

         static if( is(T : U) )
             alias T largestOrConvertible;
         else static if( is(U : T) )
             alias U largestOrConvertible;
         else static assert( false, "Object types must be related." );
     }
     else static if( is( T : Interface ) || is( U : Interface ) )
         static assert( false, "Interface types not yet supported." );
     else static if( T.sizeof < U.sizeof )
         alias U largestOf;  // concrete type, U larger
     else alias T largestOf; // concrete type, T larger or equal
}

template max( T, U )
{
     largestOrConvertible!(T,U).largestOf max( T t, U u )
     {
         return t > u ? t : u;
     }
}
template min( T, U )
{
     largestOrConvertible!(T,U).largestOf min( T t, U u )
     {
         return t < u ? t : u;
     }
}
unittest {
     int ismall=1, ibig=5;
     byte bsmall=1, bbig=5;
     float fsmall=1, fbig=5;
     double dsmall=1, dbig=5;
     assert(max(ibig,ismall)==ibig);
     assert(max(ismall,ibig)==ibig);
     assert(min(ibig,ismall)==ismall);
     assert(min(ismall,ibig)==ismall);

     assert(max(fbig,fsmall)==fbig);
     assert(max(fsmall,fbig)==fbig);
     assert(min(fbig,fsmall)==fsmall);
     assert(min(fsmall,fbig)==fsmall);

     assert(min(dsmall,fbig)==dsmall);
     assert(max(dsmall,fbig)==fbig);
     assert(min(dbig,fsmall)==fsmall);
     assert(max(dbig,fsmall)==dbig);

     assert( is(typeof(min(dsmall,fbig)) == double) );
     assert( is(typeof(max(dsmall,fbig)) == double) );
     assert( is(typeof(min(dbig,fsmall)) == double) );
     assert( is(typeof(max(dbig,fsmall)) == double) );

     assert( is(typeof(min(bsmall,ibig))==int) );
     assert( is(typeof(max(bsmall,ibig))==int) );
     assert( is(typeof(min(bbig,ismall))==int) );
     assert( is(typeof(max(bbig,ismall))==int) );
}

--bb



More information about the Digitalmars-d-learn mailing list