www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - max() in phobos?

reply 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
Nov 06 2006
next sibling parent reply 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; } }
Nov 06 2006
next sibling parent reply 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
Nov 07 2006
parent reply 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 ); }
Nov 07 2006
parent 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
Nov 08 2006
prev sibling next sibling parent reply 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
Nov 07 2006
next sibling parent reply "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)..
Nov 07 2006
next sibling parent 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
Nov 08 2006
prev sibling parent reply 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
Nov 08 2006
parent reply 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
Nov 08 2006
parent reply 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
Nov 08 2006
parent reply 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!
Nov 09 2006
next sibling parent 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
Nov 09 2006
prev sibling next sibling parent 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
Nov 09 2006
prev sibling parent 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/
Nov 09 2006
prev sibling next sibling parent reply 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
Nov 08 2006
parent reply "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
Nov 13 2006
parent reply 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
Nov 14 2006
parent John Reimer <terminal.node gmail.com> writes:
LOL!

Well, I hope you don't charge too much! :D

-JJR
Nov 14 2006
prev sibling parent reply 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/
Nov 08 2006
parent %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
Nov 08 2006
prev sibling parent reply 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!
Nov 13 2006
parent "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..
Nov 14 2006
prev sibling parent 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.
Nov 06 2006