www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Checking if a function exists

reply Michiel <nomail please.com> writes:
I'm not quite sure how to do this, but I'm sure one of you does. I need
something like:

static if ( functionExists(char[] .toString(T)) ) { ... }

static if ( functionExists(char[] T.toString()) ) { ... }

What is the real way to do this static check?

Thanks!

-- 
Michiel
Feb 21 2007
next sibling parent reply david <tazz gmx.at> writes:
Look in d.D.learn, there's a recent topic named
  -> "Testing if a function is defined in a module"
I guess that will help you.

David

Michiel schrieb:
 I'm not quite sure how to do this, but I'm sure one of you does. I need
 something like:
 
 static if ( functionExists(char[] .toString(T)) ) { ... }
 
 static if ( functionExists(char[] T.toString()) ) { ... }
 
 What is the real way to do this static check?
 
 Thanks!
 
Feb 21 2007
parent Michiel <nomail please.com> writes:
david wrote:

 Look in d.D.learn, there's a recent topic named
  -> "Testing if a function is defined in a module"
 I guess that will help you.
See other reply. Thanks! -- Michiel
Feb 21 2007
prev sibling next sibling parent reply Max Samukha <samukha voliacable.com> writes:
On Wed, 21 Feb 2007 21:25:20 +0100, Michiel <nomail please.com> wrote:

I'm not quite sure how to do this, but I'm sure one of you does. I need
something like:

static if ( functionExists(char[] .toString(T)) ) { ... }

static if ( functionExists(char[] T.toString()) ) { ... }

What is the real way to do this static check?

Thanks!
The way that I can think of is static if (is(typeof(&T.toString) == char[] function())) There might be others
Feb 21 2007
parent Michiel <nomail please.com> writes:
Max Samukha wrote:

 static if ( functionExists(char[] T.toString()) ) { ... }
The way that I can think of is static if (is(typeof(&T.toString) == char[] function()))
Thanks! That part works great. The only thing missing now is the toString(T) part. -- Michiel
Feb 21 2007
prev sibling parent reply Tyler Knott <tywebmail mailcity.com> writes:
Michiel wrote:
 I'm not quite sure how to do this, but I'm sure one of you does. I need
 something like:
 
 static if ( functionExists(char[] .toString(T)) ) { ... }
 
 static if ( functionExists(char[] T.toString()) ) { ... }
 
 What is the real way to do this static check?
 
 Thanks!
 
Check out this (http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.le rn&article_id=6577) thread in digitalmars.D.learn. It answers your question exactly. For non-static member functions of classes you'll need to test against a reference to that class (although it doesn't need to be initialized). To get the return and parameter types you can use the templates in std.traits (note: those templates (and DMD itself) will only reveal the first overload of a function; there is no way to get the parameter list for others).
Feb 21 2007
parent reply Michiel <nomail please.com> writes:
Tyler Knott wrote:

 I'm not quite sure how to do this, but I'm sure one of you does. I need
 something like:

 static if ( functionExists(char[] .toString(T)) ) { ... }

 static if ( functionExists(char[] T.toString()) ) { ... }

 What is the real way to do this static check?

 Thanks!
Check out this (http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=6577) thread in digitalmars.D.learn. It answers your question exactly.
Well, not exactly. They only check for the function name, while I also need to check out the parameter. And if I really want to do it right, also the return type. But I suppose a function named toString will probably return char[], so that's less important.
 For
 non-static member functions of classes you'll need to test against a
 reference to that class (although it doesn't need to be initialized). 
 To get the return and parameter types you can use the templates in
 std.traits (note: those templates (and DMD itself) will only reveal the
 first overload of a function; there is no way to get the parameter list
 for others).
That's too bad. Because std.string.toString is exactly the function I want to check for (among other, self-defined toString functions). And there are 20 such functions, all with a different parameter type. I don't really need the whole list of parameters anyway. I only want to know if a function with a parameter type I specify exists or not. -- Michiel
Feb 21 2007
parent reply Tyler Knott <tywebmail mailcity.com> writes:
Michiel wrote:
 Tyler Knott wrote:
 
 I'm not quite sure how to do this, but I'm sure one of you does. I need
 something like:

 static if ( functionExists(char[] .toString(T)) ) { ... }

 static if ( functionExists(char[] T.toString()) ) { ... }

 What is the real way to do this static check?

 Thanks!
Check out this (http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=6577) thread in digitalmars.D.learn. It answers your question exactly.
Well, not exactly. They only check for the function name, while I also need to check out the parameter. And if I really want to do it right, also the return type. But I suppose a function named toString will probably return char[], so that's less important.
 For
 non-static member functions of classes you'll need to test against a
 reference to that class (although it doesn't need to be initialized). 
 To get the return and parameter types you can use the templates in
 std.traits (note: those templates (and DMD itself) will only reveal the
 first overload of a function; there is no way to get the parameter list
 for others).
That's too bad. Because std.string.toString is exactly the function I want to check for (among other, self-defined toString functions). And there are 20 such functions, all with a different parameter type. I don't really need the whole list of parameters anyway. I only want to know if a function with a parameter type I specify exists or not.
Hmm... I've only ever tried to get backwards (from knowing the function name to knowing all the overloads). It seems that it's possible to find out if there's an overload for a specific parameter list: import std.string; class x{} class y{} extern char[] toString(x y); void main() { static if(is(typeof(toString(cast(x)null)))) pragma(msg, "This works."); //Note: you need to use the fully qualified name of toString if there's another toString in the local scope, //even if it uses a different overload which fits the type better. static if(is(typeof(std.string.toString(cast(uint)5)))) pragma(msg, "This too."); static if(is(typeof(toString(cast(y)null)))) pragma(msg, "Not this."); }
Feb 21 2007
parent reply Tyler Knott <tywebmail mailcity.com> writes:
For all types you can use T.init as the dummy value to the function (I just
remembered its existence).
Feb 21 2007
next sibling parent reply Max Samukha <samukha voliacable.com> writes:
On Wed, 21 Feb 2007 15:32:52 -0600, Tyler Knott
<tywebmail mailcity.com> wrote:

For all types you can use T.init as the dummy value to the function (I just
remembered its existence).
This works for module scope functions: static if (is(typeof(&.toString) == char[] function(T))) // '.' is the module scope operator or use fully qualified name. Trickier ways might exist.
Feb 21 2007
parent reply Michiel <nomail please.com> writes:
Max Samukha wrote:

 For all types you can use T.init as the dummy value to the function (I just
remembered its existence).
This works for module scope functions: static if (is(typeof(&.toString) == char[] function(T))) // '.' is the module scope operator or use fully qualified name. Trickier ways might exist.
That doesn't work if there are multiple overloads of the same function, like with toString. I just tested it. Tyler's method worked, though. Thanks! -- Michiel
Feb 21 2007
parent Max Samukha <samukha voliacable.com> writes:
On Wed, 21 Feb 2007 23:08:16 +0100, Michiel <nomail please.com> wrote:

Max Samukha wrote:

 For all types you can use T.init as the dummy value to the function (I just
remembered its existence).
This works for module scope functions: static if (is(typeof(&.toString) == char[] function(T))) // '.' is the module scope operator or use fully qualified name. Trickier ways might exist.
That doesn't work if there are multiple overloads of the same function, like with toString. I just tested it. Tyler's method worked, though. Thanks!
Yes, my mistake
Feb 21 2007
prev sibling parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Tyler Knott wrote:
 For all types you can use T.init as the dummy value to the function (I 
 just remembered its existence).
Doesn't work for static arrays IIRC, since typeof(T[N].init) == T (for constant integer N)...
Feb 21 2007