Jump to page: 1 2
Thread overview
Converting a number to complex
Nov 22, 2012
Frederik Vagner
Nov 22, 2012
Joshua Niehus
Nov 23, 2012
Frederik Vagner
Nov 23, 2012
Joshua Niehus
Nov 23, 2012
Joshua Niehus
Nov 23, 2012
Joshua Niehus
Nov 23, 2012
Artur Skawina
Nov 23, 2012
Joshua Niehus
Nov 24, 2012
Philippe Sigaud
Nov 25, 2012
Joshua Niehus
Nov 24, 2012
Artur Skawina
Nov 24, 2012
Philippe Sigaud
Nov 24, 2012
Artur Skawina
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