|
Archives
D Programming
D
D.gnu
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger
C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows
digitalmars.empire
digitalmars.DMDScript
|
digitalmars.D.learn - max() in phobos?
↑ ↓ ← → Bill Baxter <wbaxter gmail.com> writes:
Is there a generic 'max' function anywhere in phobos?
The closest I could find was std.math.fmax().
Grepping Phobos, I find there is a generic max()/min() pair in called
"std.math2". Is math2 an official part of the library? Can I count on
it being there? Or is that stuff that's slated to be moved into
std.math eventually?
--bb
↑ ↓ ← → Sean Kelly <sean f4.ca> writes:
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.
/**
* 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( T : U )
alias T largestOrConvertible;
else static if( 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) max( T t, U u )
{
return t > u ? t : u;
}
}
template min( T, U )
{
largestOrConvertible!(T,U) min( T t, U u )
{
return t < u ? t : u;
}
}
↑ ↓ ← → Bill Baxter <wbaxter gmail.com> writes:
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
↑ ↓ ← → Sean Kelly <sean f4.ca> writes:
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 );
}
↑ ↓ ← → Bill Baxter <dnewsgroup billbaxter.com> writes:
Sean Kelly wrote:
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 :-)
Great. About signed types, I think
auto c = max(a,b)
should pick the same type for c that the compiler would pick for
auto c = a+b;
--bb
↑ ↓ ← → David Qualls <davidlqualls yahoo.com> writes:
== Quote from Sean Kelly (sean f4.ca)'s article
Bill Baxter wrote:
Is there a generic 'max' function anywhere in phobos?
The closest I could find was std.math.fmax().
something like the code below should work. ...
...much code omitted...
...
template max( T, U )
{
largestOrConvertible!(T,U) max( T t, U u )
{
return t > u ? t : u;
}
}
template min( T, U )
{
largestOrConvertible!(T,U) min( T t, U u )
{
return t < u ? t : u;
}
}
So, is it possible to use templates to define generic binary
operators; like 'and' and 'or', or a unary operator like 'not'?
After looking at the mass of code it takes to implement a simple
generic max() or min() function in D, I'm really starting to pine
for my C preprocessor...
#define max(a,b) ((a)>(b)?(a):(b))
Yeah, I know it breaks if a or b include side effects, but it's
extremely READABLE! (And back on my old soap-box, even FORTRAN and
Basic include English binary logic operators ;-)
DQ
↑ ↓ ← → "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"David Qualls" <davidlqualls yahoo.com> wrote in message
news:eirqai$he$1 digitaldaemon.com...
So, is it possible to use templates to define generic binary
operators; like 'and' and 'or', or a unary operator like 'not'?
Not like the way you'd use the iso646 ones. It'd be really unnatural:
if(not(and(a, or(b, c))))
...
After looking at the mass of code it takes to implement a simple
generic max() or min() function in D, I'm really starting to pine
for my C preprocessor...
#define max(a,b) ((a)>(b)?(a):(b))
Yeah, I know it breaks if a or b include side effects, but it's
extremely READABLE! (And back on my old soap-box, even FORTRAN and
Basic include English binary logic operators ;-)
Well, if you make the max function a bit less generic, restricting it to
just one input type, it becomes
T max(T)(T a, T b)
{
return (a > b) ? a : b;
}
Which is pretty readable to me, and probably covers most of the use cases.
Most of that conversion stuff in Sean's implementation is probably type
trait stuff which would best belong in std.traits (when it comes out)..
↑ ↓ ← → Sean Kelly <sean f4.ca> writes:
Jarrett Billingsley wrote:
"David Qualls" <davidlqualls yahoo.com> wrote in message
news:eirqai$he$1 digitaldaemon.com...
So, is it possible to use templates to define generic binary
operators; like 'and' and 'or', or a unary operator like 'not'?
Not like the way you'd use the iso646 ones. It'd be really unnatural:
if(not(and(a, or(b, c))))
...
Yup. These are in C++ only to allow expressions to be built using
template composition for use in algorithms. And the result quickly gets
annoyingly complex and hard to read. Lambda expression are a much
clearer replacement, which we have to some degree with lazy parameters
and anonymous delegates. By contrast, C++ uses fancy classes with
cleverly overloaded operators and some global placeholders. It works
fairly well all things considered, but the code behind it is a bit much.
After looking at the mass of code it takes to implement a simple
generic max() or min() function in D, I'm really starting to pine
for my C preprocessor...
#define max(a,b) ((a)>(b)?(a):(b))
Yeah, I know it breaks if a or b include side effects, but it's
extremely READABLE! (And back on my old soap-box, even FORTRAN and
Basic include English binary logic operators ;-)
Well, if you make the max function a bit less generic, restricting it to
just one input type, it becomes
T max(T)(T a, T b)
{
return (a > b) ? a : b;
}
Which is pretty readable to me, and probably covers most of the use cases.
Most of that conversion stuff in Sean's implementation is probably type
trait stuff which would best belong in std.traits (when it comes out)..
Agreed on both counts. My template was really to avoid requiring the
user to explicitly specify template type parameters of the types of a
and b are different, to make min/max behave as close to the C macro as
possible.
Sean
↑ ↓ ← → Bill Baxter <dnewsgroup billbaxter.com> writes:
Jarrett Billingsley wrote:
"David Qualls" <davidlqualls yahoo.com> wrote in message
news:eirqai$he$1 digitaldaemon.com...
So, is it possible to use templates to define generic binary
operators; like 'and' and 'or', or a unary operator like 'not'?
Not like the way you'd use the iso646 ones. It'd be really unnatural:
if(not(and(a, or(b, c))))
...
I'm a Lisp user you insensitive clod! That looks perfectly natural to
me! :-)
T max(T)(T a, T b)
{
return (a > b) ? a : b;
}
Which is pretty readable to me, and probably covers most of the use cases.
Most of that conversion stuff in Sean's implementation is probably type
trait stuff which would best belong in std.traits (when it comes out)..
But it's very annoying in C++.
float x = 17;
std::max(x,0); // error! which max do you mean - float or int?
std::max(x,0.0); // error! which max do you mean - float or double?
std::max(x,0.0f); // ok, both float
Especially annoying for containers parameterized by numeric type. Then
you don't know what to use for the literal you're comparing against, so
you've got to use a cast.
T x = 17; // could be float,double,real,int etc
std::max(x, cast(T)0); // ugh.
--bb
↑ ↓ ← → Sean Kelly <sean f4.ca> writes:
Bill Baxter wrote:
Especially annoying for containers parameterized by numeric type. Then
you don't know what to use for the literal you're comparing against, so
you've got to use a cast.
T x = 17; // could be float,double,real,int etc
std::max(x, cast(T)0); // ugh.
In all fairness, this can be rewritten as:
std::max<T>( x, 0 );
By the way, I had to add casts to my min/max functions to allow class
types to be comparable. For example:
class A
{
int opCmp( A rhs ) { ... }
int opCmp( Object rhs ) { ... }
}
class B : A {}
class C : A {}
A a = new A;
B b = new B;
C c = new C;
min( a, b ); // 1
min( b, a ); // 2
min( b, c ); // 3
In cases 1 and 2, opCmp(A) should be called, but the call is ambiguous
since b is convertible to both A and Object. And in case 3,
opCmp(Object) should be called, since the mechanism isn't smart enough
to figure out that b and c have a common user-defined parent. Casting
fixes both of these, though it pained me to add it :-)
Sean
↑ ↓ ← → Bill Baxter <dnewsgroup billbaxter.com> writes:
Sean Kelly wrote:
Bill Baxter wrote:
Especially annoying for containers parameterized by numeric type. Then
you don't know what to use for the literal you're comparing against,
so you've got to use a cast.
T x = 17; // could be float,double,real,int etc
std::max(x, cast(T)0); // ugh.
In all fairness, this can be rewritten as:
std::max<T>( x, 0 );
The cast is not so bad in real C++ either:
std::max(x, T(0));
But my point was just that the extra information is not necessary for
the macro version. The intended meaning of max(x,0) is clear enough to
the reader, so the compiler should be able to handle it without
complaining, too.
--bb
↑ ↓ ← → David Qualls <davidlqualls yahoo.com> writes:
== Quote from Bill Baxter (dnewsgroup billbaxter.com)'s article
But my point was just that the extra information is not
the macro version. The intended meaning of max(x,0) is clear
the reader, so the compiler should be able to handle it without
complaining, too.
--bb
EXACTLY! I also think you (mostly) nailed it with
About signed types, I think
auto c = max(a,b)
should pick the same type for c that the compiler would pick for
auto c = a+b;
except I don't think max(10U , -1) should return -1 cast to an
unsigned!
↑ ↓ ← → Bill Baxter <wbaxter gmail.com> writes:
David Qualls wrote:
== Quote from Bill Baxter (dnewsgroup billbaxter.com)'s article
But my point was just that the extra information is not
necessary for
the macro version. The intended meaning of max(x,0) is clear
enough to
the reader, so the compiler should be able to handle it without
complaining, too.
--bb
EXACTLY! I also think you (mostly) nailed it with
About signed types, I think
auto c = max(a,b)
should pick the same type for c that the compiler would pick for
auto c = a+b;
except I don't think max(10U , -1) should return -1 cast to an
unsigned!
Oof. No it should not. But the macro would fail there too. At least
in D, (10U<-1) evaluates to true.
--bb
↑ ↓ ← → Sean Kelly <sean f4.ca> writes:
David Qualls wrote:
== Quote from Bill Baxter (dnewsgroup billbaxter.com)'s article
But my point was just that the extra information is not
the macro version. The intended meaning of max(x,0) is clear
the reader, so the compiler should be able to handle it without
complaining, too.
--bb
EXACTLY! I also think you (mostly) nailed it with
About signed types, I think
auto c = max(a,b)
should pick the same type for c that the compiler would pick for
auto c = a+b;
except I don't think max(10U , -1) should return -1 cast to an
unsigned!
The addition promotion rules for integers are essentially as follows:
int + uint = uint
uint + long = long
(anything smaller than int) + (anything smaller than int) = int
It would be easy enough to simply use typeof(T.init + U.init) for
concrete types and throw out a bunch of static ifs, but I'm not sure if
integer promotion is desired here. Suggestions?
Sean
↑ ↓ ← → Daniel Keep <daniel.keep.lists gmail.com> writes:
David Qualls wrote:
== Quote from Bill Baxter (dnewsgroup billbaxter.com)'s article
But my point was just that the extra information is not
the macro version. The intended meaning of max(x,0) is clear
the reader, so the compiler should be able to handle it without
complaining, too.
--bb
EXACTLY! I also think you (mostly) nailed it with
About signed types, I think
auto c = max(a,b)
should pick the same type for c that the compiler would pick for
auto c = a+b;
except I don't think max(10U , -1) should return -1 cast to an
unsigned!
One thing I did when I was playing around with some MMX code was write a
template that figured out the "expression-safe" type of something.
Basically, it was the type for which any expression involving the base
type could be contained in. I used it to ensure that stuff like int+int
wouldn't overflow.
You could always say that when combining a signed and unsigned type,
take the signed type large enough to hold either. If the user has a
problem with having to cast it back, tell him to use arguments of the
same type, damnit!
"But I don't *wanna*!"
"Tough. Don't wanna deal with types? Go program in PHP."
"I'll behave..."
-- Daniel
--
Unlike Knuth, I have neither proven or tried the above; it may not even
make sense.
v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D
i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
↑ ↓ ← → Sean Kelly <sean f4.ca> writes:
David Qualls wrote:
So, is it possible to use templates to define generic binary
operators; like 'and' and 'or', or a unary operator like 'not'?
They're in the C++ standard library, so I don't see why not.
After looking at the mass of code it takes to implement a simple
generic max() or min() function in D, I'm really starting to pine
for my C preprocessor...
#define max(a,b) ((a)>(b)?(a):(b))
Yeah, I know it breaks if a or b include side effects, but it's
extremely READABLE!
There has been a lot of work done in the C++ community to produce a
template function that is as functional as this simple macro. In fact,
I think Andrei actually wrote a series of articles on it. I think we
can do better in D because of the improved compile-time type
information, but it's difficult to match the simplicity of macro code
replacement.
Sean
↑ ↓ ← → "John Reimer" <terminal.node gmail.com> writes:
On Wed, 08 Nov 2006 05:48:58 -0800, Sean Kelly <sean f4.ca> wrote:
David Qualls wrote:
So, is it possible to use templates to define generic binary
operators; like 'and' and 'or', or a unary operator like 'not'?
They're in the C++ standard library, so I don't see why not.
After looking at the mass of code it takes to implement a simple
generic max() or min() function in D, I'm really starting to pine
for my C preprocessor...
#define max(a,b) ((a)>(b)?(a):(b))
Yeah, I know it breaks if a or b include side effects, but it's
extremely READABLE!
There has been a lot of work done in the C++ community to produce a
template function that is as functional as this simple macro. In fact,
I think Andrei actually wrote a series of articles on it. I think we
can do better in D because of the improved compile-time type
information, but it's difficult to match the simplicity of macro code
replacement.
Sean
Blech! I do not find C/C++ macros readable! This small sample is hardly
representative of the abuse of the preprocessor that exists in most of
C/C++ land and is hardly an argument for having a PP in D. Abuse of the
CPP has made a horrid mess of code and makes it impossible to determine
what is /really/ going on in there (I especially resent macros in macros
in macros :P ). I, for one, don't miss the preprocessor's absence from
D. D compile-time features are gradually progressing to the state where
almost all CPP functionality is possible, anyway. Those that are addicted
to the CPP might do better to take a break from it and start experimenting
with the D system.
Sure the CPP may inline things efficiently, but it's really just a poor
man's templating system... a hack that's gone horribly wayward since long
ago.
Oh... that feels better. It seems I periodically have to bash the CPP...
at least once a year, at least. :)
-JJR
↑ ↓ ← → David Qualls <davidlqualls yahoo.com> writes:
== Quote from John Reimer (terminal.node gmail.com)'s article
On Wed, 08 Nov 2006 05:48:58 -0800, Sean Kelly <sean f4.ca>
David Qualls wrote:
After looking at the mass of code it takes to implement a
simple generic max() or min() function in D, I'm really
starting to pine
for my C preprocessor...
Blech! I do not find C/C++ macros readable!
Oh... that feels better. It seems I periodically have to bash
the CPP...
at least once a year, at least. :)
-JJR
Well, since I was the one that brought it up, I feel I deserve
payment for the positive psycho-therapy you just experienced!
;-)
David
↑ ↓ ← → John Reimer <terminal.node gmail.com> writes:
LOL!
Well, I hope you don't charge too much! :D
-JJR
↑ ↓ ← → mike <vertex gmx.at> writes:
Am 08.11.2006, 06:35 Uhr, schrieb David Qualls <davidlqualls yahoo.com>:=
After looking at the mass of code it takes to implement a simple
generic max() or min() function in D, I'm really starting to pine
for my C preprocessor...
#define max(a,b) ((a)>(b)?(a):(b))
Hmm, if you really want to you could run D code through CPP anyway befor=
e =
passing it to DMD. Shouldn't be that hard to make a script for that.
-Mike
-- =
Erstellt mit Operas revolution=E4rem E-Mail-Modul: http://www.opera.com/=
mail/
↑ ↓ ← → %u <davidlqualls yahoo.com> writes:
== Quote from mike (vertex gmx.at)'s article
Hmm, if you really want to you could run D code through CPP
e =
passing it to DMD. Shouldn't be that hard to make a script for
-Mike
-- =
Erstellt mit Operas revolution=E4rem E-Mail-Modul:
mail/
I was actually thinking about doing just that. Still though, the
real competitor here is either Basic, Fortran, or C with
sufficient macros that I can take my code to a board room and
explain it to intelligent people who are not programmers. Yes, I
can write in pseudo code for them, but then there's always the
question of whether I did the translation from pseudo into D
correctly. Once I digress to using a custom script or program to
preprocess the text before submitting it to the compiler, I'm
building a tool chain that: a)won't work with a standard compiler
distribution (you also have to have my preprocessing tool along
with it), b)is subject to being rejected due to complexity.
An alternate approach I might take is to simply write psuedo code
for every single line of code:
//if BOTH y and z are true.
if( y && z ) // then
{
which I think to most of us seems like a waste of keystrokes, and
a bit cluttered.
David
↑ ↓ ← → Reiner Pope <reiner.pope REMOVE.THIS.gmail.com> writes:
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.
/**
* 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( T : U )
alias T largestOrConvertible;
else static if( 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) max( T t, U u )
{
return t > u ? t : u;
}
}
template min( T, U )
{
largestOrConvertible!(T,U) min( T t, U u )
{
return t < u ? t : u;
}
}
return values:
auto max (T, U) (T t, U u)
{
return t > u ? t : u;
}
Problem solved!
↑ ↓ ← → "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Reiner Pope" <reiner.pope REMOVE.THIS.gmail.com> wrote in message
news:ejbpi0$194t$1 digitaldaemon.com...
We could do all of this code, or we could just have type inference for
return values:
auto max (T, U) (T t, U u)
{
return t > u ? t : u;
}
Problem solved!
That's true. D already does return type deduction for delegate literals..
↑ ↓ ← → Don Clugston <dac nospam.com.au> writes:
Bill Baxter wrote:
Is there a generic 'max' function anywhere in phobos?
The closest I could find was std.math.fmax().
Grepping Phobos, I find there is a generic max()/min() pair in called
"std.math2". Is math2 an official part of the library? Can I count on
it being there? Or is that stuff that's slated to be moved into
std.math eventually?
It should be removed. Almost all of the worthwhile stuff in it was moved
into std.math. The rest is obsolete, dating from the days before D had
templates.
|
|