View mode: basic / threaded / horizontal-split · Log in · Help
November 22, 2012
Converting a number to complex
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
Re: Converting a number to complex
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
Re: Converting a number to complex
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
Re: Converting a number to complex
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
Re: Converting a number to complex
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
Re: Converting a number to complex
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
Re: Converting a number to complex
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
Re: Converting a number to complex
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
Re: Converting a number to complex
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
Re: Converting a number to complex
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