Thread overview
Checking for Callabilty of either f(x) or x.f
Aug 01, 2014
Nordlöw
Aug 01, 2014
Nordlöw
Aug 01, 2014
Nordlöw
Aug 01, 2014
H. S. Teoh
Aug 01, 2014
Nordlöw
Aug 01, 2014
anonymous
Aug 02, 2014
Nordlöw
August 01, 2014
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?
August 01, 2014
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
August 01, 2014
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?
August 01, 2014
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.
August 01, 2014
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. :)
August 01, 2014
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
August 02, 2014
On Friday, 1 August 2014 at 22:27:01 UTC, anonymous wrote:
> change the name to "isCallableWith" here

Doh!

Thx