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!
 

(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!

(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!

(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.

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