www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - templated isNaN

reply "Paolo Invernizzi" <paolo.invernizzi gmail.com> writes:
Someone can suggest me a convenient way to declare an 'isNaN' 
templated function that plays well with the 'standard.math.isNaN'?

The target is to be able to define isNaN functions for my custom 
structures, and I want to keep the same name...

---
import std.math;

bool isNaN(T)(T t) if(is(T==string)){ return true; }

// that is really necessary? What if I have my isNaN in different 
modules? Must duplicate?
// bool isNaN(T)(T t) if(is(T:real)) { return std.math.isNaN(t); }

void foo(){
	bool b = isNaN(0.0);
}

/d471/f783.d(9): Error: template f783.isNaN does not match any 
function template declaration. Candidates are:
/d471/f783.d(3):        f783.isNaN(T)(T t) if (is(T == string))
/d471/f783.d(9): Error: template f783.isNaN(T)(T t) if (is(T == 
string)) cannot deduce template function from argument types 
!()(double)
---

Thanks in advance!

- Paolo Invernizzi
Aug 24 2013
next sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
Hello all,

Suppose that I have a struct like e.g.:

     struct A
     {
         void foo(int n) { ... }
         void foo(Range)(Range r) { ... }
         int bar() { ... }
         int bar(double x) { ... }
         // ... and others ...
     }

... an I want to wrap it in another struct, B.  If I do this manually it would 
be something like,

     struct B
     {
         private A a;
         void foo(int n) { return a.foo(n); }
         void foo(Range)(Range r) { return a.foo(r); }
         // ... etc ...
     }

But suppose that I don't a priori know the list of functions (and function 
arguments) that need to be wrapped.  How could I go about working this out,
with 
a generic programming approach?

More specifically, how could I work this out limited to a specific function of
A 
(say, foo) ... ?

Thanks & best wishes,

     -- Joe
Aug 24 2013
parent "Paolo Invernizzi" <paolo.invernizzi gmail.com> writes:
On Saturday, 24 August 2013 at 12:12:29 UTC, Joseph Rushton 
Wakeling wrote:

Hi Joseph,

I'm not really a D guru like others, but...

 ... an I want to wrap it in another struct, B.  If I do this 
 manually it would be something like,

     struct B
     {
         private A a;
         void foo(int n) { return a.foo(n); }
         void foo(Range)(Range r) { return a.foo(r); }
         // ... etc ...
     }

 But suppose that I don't a priori know the list of functions 
 (and function arguments) that need to be wrapped.  How could I 
 go about working this out, with a generic programming approach?
For this case I would use alias this, if you want to wrap every method... struct B { private A a; alias a this; }
 More specifically, how could I work this out limited to a 
 specific function of A (say, foo) ... ?
I think that you have to explicitly wrap them, maybe with a template to alleviate the copy/past... But maybe someone else can suggest a better solution! - Paolo Invernizzi
Aug 24 2013
prev sibling next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
Whoops -- must have accidentally hit "Reply" there by accident, instead of 
clicking to send new mail.  Didn't mean to hijack someone else's thread. :-(
Aug 24 2013
prev sibling next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 24/08/13 13:53, Paolo Invernizzi wrote:
 Someone can suggest me a convenient way to declare an 'isNaN' templated
function
 that plays well with the 'standard.math.isNaN'?

 The target is to be able to define isNaN functions for my custom structures,
and
 I want to keep the same name...
Will this do? ////////////////////////////////////// import std.math, std.traits; bool isNaN(T)(T t) { static if (isNumeric!T) { return std.math.isNaN(t); } else { return true; } } unittest { assert(isNaN("NaN")); assert(!isNaN(0)); assert(!isNaN(0.0)); assert(isNaN(real.nan)); } ////////////////////////////////////// Since you were kind enough to answer my accidental response to your mail, I thought I'd try and return the favour ... ;-)
Aug 24 2013
prev sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 24/08/13 14:50, Joseph Rushton Wakeling wrote:
      static if (isNumeric!T)
      {
          return std.math.isNaN(t);
      }
Note that the correct if () condition here depends on how you want your isNaN to behave in certain cases. Using isNumeric will mean isNaN('c') returns true. If you want isNaN to return false when passed a char type, use your if(is(T : real)) instead.
Aug 24 2013