www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Checking for Callabilty of either f(x) or x.f

reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
I'm currently developing a pretty printing system in D with 
backend support for text, html, mathml, latex, etc.

To make it loosely decoupled in compile-time if currently make 
use __traits in  the following way.

     static if (__traits(hasMember, arg, "toHTML"))
     {
         if (viz.form == VizForm.HTML)
         {
             return viz.ppRaw(arg.toHTML);
         }
     }
     else static if (__traits(hasMember, arg, "toMathML")) // 
TODO: Change to __traits(compiles, auto x = arg.toMathML()) or 
*callable*
     {
         if (viz.form == VizForm.HTML)
         {
             // TODO: Check for MathML support on backend
             return viz.ppRaw(arg.toMathML);
         }
     }
     else static if (__traits(hasMember, arg, "toLaTeX"))
     {
         if (viz.form == VizForm.LaTeX)
         {
             return viz.ppRaw(arg.toLaTeX);
         }
     }

A more flexible solution is to not require toX to be a member 
function of type specific (system) types to printed.

What is the preffered (fast) way to check at compile-time if an 
instance x of a type T can be used *either* as

     f(x)

or

     x.f?
Aug 01 2014
next sibling parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Friday, 1 August 2014 at 14:20:55 UTC, Nordlöw wrote:
 I'm currently developing a pretty printing system in D with 
 backend support for text, html, mathml, latex, etc.
See also: https://github.com/nordlow/justd/blob/master/pprint.d
Aug 01 2014
prev sibling next sibling parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Friday, 1 August 2014 at 14:20:55 UTC, Nordlöw wrote:
 A more flexible solution is to not require toX to be a member 
 function of type specific (system) types to printed.
My suggestions is something like __traits(compiles, auto x = arg.toMathML()) Is this my best option? The snippet __traits(compiles is quite fast right?
Aug 01 2014
prev sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Fri, Aug 01, 2014 at 02:20:53PM +0000, "Nordlöw" via Digitalmars-d-learn
wrote:
[...]
 What is the preffered (fast) way to check at compile-time if an
 instance x of a type T can be used *either* as
 
     f(x)
 
 or
 
     x.f?
if (is(typeof(f(x))) || is(typeof(x.f))) Basically, is(X) checks if X has a valid type (which include void if f doesn't return anything), and typeof(Y) returns the type of Y if it exists, otherwise it is an error and has no type. So if f(x) doesn't compile, then typeof(f(x)) has no type, and so is(typeof(f(x))) will be false. Ditto for x.f. T -- All men are mortal. Socrates is mortal. Therefore all men are Socrates.
Aug 01 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Friday, 1 August 2014 at 17:17:57 UTC, H. S. Teoh via 
Digitalmars-d-learn wrote:
 	if (is(typeof(f(x))) || is(typeof(x.f)))
Here's my try: template isCallableWith(alias fun, T) { enum bool isCallable = is(typeof(fun(T.init))) || is(typeof(T.init.fun)); } unittest { auto sqr(T)(T x) { return x*x; } auto xf = isCallableWith!(sqr, int); } but errs as traits_ex.d(182,15): Error: cannot infer type from template instance isCallableWith!(sqr, int) Could someone, please, explain how to f and x should be passed in a template here? A complete implementation of, say isCallableWith, would be nice. :)
Aug 01 2014
parent reply "anonymous" <anonymous example.com> writes:
On Friday, 1 August 2014 at 22:04:38 UTC, Nordlöw wrote:
 template isCallableWith(alias fun, T)
 {
     enum bool isCallable = is(typeof(fun(T.init))) ||
change the name to "isCallableWith" here
Aug 01 2014
parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Friday, 1 August 2014 at 22:27:01 UTC, anonymous wrote:
 change the name to "isCallableWith" here
Doh! Thx
Aug 02 2014