max() in phobos?
Sean Kelly
sean at f4.ca
Tue Nov 7 22:41:58 PST 2006
Bill Baxter wrote:
> 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:
I rewrote the code to work a bit better and added some more tests.
However, I think it should probably error when comparing a signed and
unsigned integer type. At the moment, it accepts this and the choice of
return type is somewhat arbitrary. Also, I haven't tested interfaces
and am not sure they should be comparable anyway, but I added support
for them for the heck of it. I'd play with it a bit more but I'm tired
and bed is calling :-)
template commonBaseTypeOf( T, U )
{
static assert( ( is( T == class ) && is( U == class ) ) ||
( is( T == interface ) && is( U == interface ) ),
"Supplied types are not siblings." );
static if( is( T : U ) )
alias U commonBaseTypeOf;
else static if( is( U : T ) )
alias T commonBaseTypeOf;
else static if( is( T == class ) )
alias Object commonBaseTypeOf;
else
static assert( false, "Interfaces have no generic parent." );
}
template bestCommonTypeOf( T, U )
{
static if( is( T == class ) || is( U == class ) ||
is( T == interface ) || is( U == interface ) )
{
alias commonBaseTypeOf!( T, U ) bestCommonTypeOf;
}
else static if( is( T : U ) && is( U : T ) )
{
static if( T.sizeof >= U.sizeof )
alias T bestCommonTypeOf;
else
alias U bestCommonTypeOf;
}
else static if( is( U : T ) )
alias T bestCommonTypeOf;
else static if( is( T : U ) )
alias U bestCommonTypeOf;
else
static assert( false, "Unable to find common type." );
}
template min( T, U )
{
bestCommonTypeOf!(T, U) min( T t, U u )
{
alias bestCommonTypeOf!(T, U) rt;
if( cast(rt) t < cast(rt) u )
return t;
return u;
}
}
template max( T, U )
{
bestCommonTypeOf!(T, U) max( T t, U u )
{
alias bestCommonTypeOf!(T, U) rt;
if( cast(rt) t > cast(rt) u )
return t;
return 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) );
class B
{
this( int v )
{
value = v;
}
int opCmp( B rhs )
{
return value - rhs.value;
}
int opCmp( Object rhs )
{
return opCmp( cast(B) rhs );
}
private int value;
}
class C : B
{
this( int v )
{
super( v );
}
}
class D : B
{
this( int v )
{
super( v );
}
}
// BUG? what to do about implicit signed-unsigned conversion?
static assert( is( bestCommonTypeOf!( int, uint ) == int ) );
static assert( is( bestCommonTypeOf!( uint, int ) == uint ) );
static assert( is( bestCommonTypeOf!( byte, long ) == long ) );
static assert( is( bestCommonTypeOf!( long, byte ) == long ) );
static assert( is( bestCommonTypeOf!( long, float ) == float ) );
static assert( is( bestCommonTypeOf!( float, long ) == float ) );
static assert( is( bestCommonTypeOf!( float, real ) == real ) );
static assert( is( bestCommonTypeOf!( cfloat, creal ) == creal ) );
static assert( is( bestCommonTypeOf!( creal, cfloat ) == creal ) );
static assert( is( bestCommonTypeOf!( B, C ) == B ) );
static assert( is( bestCommonTypeOf!( C, B ) == B ) );
static assert( is( bestCommonTypeOf!( C, D ) == Object ) );
static assert( is( bestCommonTypeOf!( D, C ) == Object ) );
B b = new B( 1 );
C c = new C( 2 );
D d = new D( 3 );
assert( min( b, c ) == b );
assert( max( b, c ) == c );
assert( min( c, d ) == c );
assert( max( c, d ) == d );
}
More information about the Digitalmars-d-learn
mailing list