November 22, 2012
I am trying to make a templated class to accept any numeric type:

class example(Type) if (isNumeric(Type))
{
    Type k = to!Type(1);
    ....
}

however I always get a compiler erro stating I cannot make that conversion. How do I fix it?
November 22, 2012
On Thursday, 22 November 2012 at 15:47:11 UTC, Frederik Vagner wrote:
> I am trying to make a templated class to accept any numeric type:
>
> class example(Type) if (isNumeric(Type))
> {
>     Type k = to!Type(1);
>     ....
> }
>
> however I always get a compiler erro stating I cannot make that conversion. How do I fix it?

// phobos
import std.stdio, std.conv, std.traits;
class Example(T) if (isNumeric!T)
{
    T k = to!T(1);
}

void main()
{
    auto x = new Example!double();
    writeln(x.k);
}
November 23, 2012
On Thursday, 22 November 2012 at 16:09:46 UTC, Joshua Niehus wrote:
> On Thursday, 22 November 2012 at 15:47:11 UTC, Frederik Vagner wrote:
>> I am trying to make a templated class to accept any numeric type:
>>
>> class example(Type) if (isNumeric(Type))
>> {
>>    Type k = to!Type(1);
>>    ....
>> }
>>
>> however I always get a compiler erro stating I cannot make that conversion. How do I fix it?
>
> // phobos
> import std.stdio, std.conv, std.traits;
> class Example(T) if (isNumeric!T)
> {
>     T k = to!T(1);
> }
>
> void main()
> {
>     auto x = new Example!double();
>     writeln(x.k);
> }

Now do it for complex number please ^^
November 23, 2012
On Friday, 23 November 2012 at 12:39:59 UTC, Frederik Vagner wrote:
> Now do it for complex number please ^^

touche!

import std.stdio, std.conv, std.traits, std.complex;

template isComplexNumeric(T)
{
    static if(is(NumericTypeOf!T)) {
        enum bool isComplexNumeric = is(NumericTypeOf!T);
    }
    else static if (is(T == Complex!double))
    {
        enum bool isComplexNumeric = is(Complex!double);
    }
    // fillin real and float here... (e.g. is(Complex!real); etc...
}

class Example(T) if (isComplexNumeric!T)
{
    T k = to!T(1);
}

void main()
{
    auto x = new Example!(Complex!double)();
    writeln(x.k);
    auto y = new Example!double();
    writeln(y.k);
    auto z = new Example!string(); // fail
    writeln(z.k);
}

A bit messy, but im sure there is some room for cleanup somewhere...


November 23, 2012
On Friday, 23 November 2012 at 16:11:25 UTC, Joshua Niehus wrote:
> A bit messy, but im sure there is some room for cleanup somewhere...

Errata... (what i get for copy/pasting)

import std.stdio, std.conv, std.traits, std.complex;
template isComplexNumeric(T)
{
    static if(isNumeric!T) {
        enum bool isComplexNumeric = true;
    }
    else static if (is(T == Complex!double))
    {
        enum bool isComplexNumeric = true;
    }
    else {
        enum bool isComplexNumeric = false;
    }
}

class Example(T) if (isComplexNumeric!T)
{
    T k = to!T(1);
}

void main()
{
    auto x = new Example!(Complex!double)();
    writeln(x.k);
    auto y = new Example!double();
    writeln(y.k);
    auto z = new Example!string();
    writeln(z.k);
}

i did have to reference Philippe Sigaud's excellent book on Templates several times:
https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/dtemplates.pdf

November 23, 2012
meh, couldn't resist:

import std.stdio, std.conv, std.traits, std.complex;
template isComplex(T)
{
    static if (is(T == Complex!double))
    {
        enum bool isComplex = true;
    }
    else static if (is(T == Complex!float))
    {
        enum bool isComplex = true;
    }
    else static if (is(T == Complex!real))
    {
        enum bool isComplex = true;
    }
    else {
        enum bool isComplex = false;
    }
}

template isComplexOrNumeric(T)
{
    enum bool isComplexOrNumeric = (isComplex!T || isNumeric!T);
}

class Example(T) if (isComplexOrNumeric!T)
{
    T k = to!T(1);
}

November 23, 2012
On 11/23/12 18:06, Joshua Niehus wrote:
> meh, couldn't resist:
> 
> import std.stdio, std.conv, std.traits, std.complex;
> template isComplex(T)
> {
>     static if (is(T == Complex!double))
>     {
>         enum bool isComplex = true;
>     }
>     else static if (is(T == Complex!float))
>     {
>         enum bool isComplex = true;
>     }
>     else static if (is(T == Complex!real))
>     {
>         enum bool isComplex = true;
>     }
>     else {
>         enum bool isComplex = false;
>     }
> }

   template isComplex(T) {
      static if (is(T _ == Complex!CT, CT))
         enum isComplex = true;
      else
         enum isComplex = false;
   }

artur
November 23, 2012
On Friday, 23 November 2012 at 18:45:53 UTC, Artur Skawina wrote:
>    template isComplex(T) {
>       static if (is(T _ == Complex!CT, CT))
>          enum isComplex = true;
>       else
>          enum isComplex = false;
>    }
>
> artur

oh wow didnt know u could do that. much nicer.

November 24, 2012
Joshua:

> oh wow didnt know u could do that. much nicer.
>

It's an is() expression (you cited my tutorial, there is an appendix on
it). It recently became even more powerful, so the tutorial is not accurate
any more.

A few months ago, you couldn't do

is(Type _ == Template!Args, Args...)

with Args being whatever number of args are needed. Only fixed numbers were possible:

is(Type _ == Template!(T), T)
is(Type _ == Template!(T,U), T,U)
and so on...

Now, testing for a Tuple is easy:

is(Type _ == Tuple!Args, Args...)



What's even nicer with an is() expr is that the introspection info is accessible when used inside a static if. So with Artur's code, CT can be seen inside the true branch of the static if.

template ComplexType(T)
if (isComplex!T) // Using the previously defined isComplex
{
    // we know it's a Complex!CT, for some CT
    static if (is(T _ == Complex!CT, CT)
        alias CT ComplexType;
    else
        static assert(false, "This should not happen!");
}

void main()
{
    Complex!double c;
    writeln(ComplexType!(typeof(c)).stringof);
}


November 24, 2012
On 11/24/12 08:27, Philippe Sigaud wrote:
> What's even nicer with an is() expr is that the introspection info is accessible when used inside a static if. So with Artur's code, CT can be seen inside the true branch of the static if.

Actually, static-ifs do not create a scope, so 'CT' leaks and is accessible after it's defined, not just inside the static-if branch:

   void main() {
      Complex!double c;
      static if (is(typeof(c) _ == Complex!CT, CT))
         {}
      writeln(CT.stringof);
   }

It has to work like that, as otherwise it would be impossible (well, harder) to conditionally compile /declarations/.


Unfortunately the is-expressions don't handle aliases properly, at least with my old compiler here. So this does not work:

   template isTempInst(alias TEMPL, T) {
      static if (is(T _ == TEMPL!CT, CT))
         enum isTempInst = true;
      else
         enum isTempInst = false;
   }

artur
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home