Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Ticket #1376 (new enhancement)

Opened 15 years ago

Last modified 14 years ago

template functions to handle numerical types

Reported by: fawzi Assigned to: Don Clugston
Priority: major Milestone: 1.0
Component: Tango Version: 0.99.7 Dominik
Keywords: Cc:

Description

In

http://github.com/fawzi/rtest/tree/master/blip/TemplateFu.d

I use some functions that handle numerical types and I think could be useful in general, and might be useful to have in math somewhere. I used them in the random number generator.

/// is T is a real floating point number
template isReal(T){
    const isReal=is(T==float)||is(T==double)||is(T==real);
}
/// if T is a complex number
template isComplex(T){
    const isComplex=is(T==cfloat)||is(T==creal)||is(T==cdouble);
}

/// if T is a purely imaginary number
template isImaginary(T){
    const isImaginary=is(T==ifloat)|| is(T==idouble)|| is(T==ireal);
}

/// complex type for the given type
template complexType(T){
    static if(is(T==float)||is(T==ifloat)||is(T==cfloat)){
        alias cfloat complexType;
    } else static if(is(T==double)|| is(T==idouble)|| is(T==cdouble)){
        alias cdouble complexType;
    } else static if(is(T==real)|| is(T==ireal)|| is(T==creal)){
        alias creal complexType;
    } else static assert(0,"unsupported type in complexType "~T.stringof);
}

/// real type for the given type
template realType(T){
    static if(is(T==float)|| is(T==ifloat)|| is(T==cfloat)){
        alias float realType;
    } else static if(is(T==double)|| is(T==idouble)|| is(T==cdouble)){
        alias double realType;
    } else static if(is(T==real)|| is(T==ireal)|| is(T==creal)){
        alias real realType;
    } else static assert(0,"unsupported type in realType "~T.stringof);
}

/// if the type is a normal number
template isNumber(T){
    const isNumber=is(T==int)||is(T==uint)||is(T==long)||is(T==ulong)
        ||is(T==float)||is(T==ifloat)||is(T==cfloat)
        ||is(T==double)||is(T==idouble)||is(T==cdouble)
        ||is(T==real)||is(T==ireal)||is(T==creal);
}

/// type with maximum precision
template maxPrecT(T){
    static if (isComplex!(T)){
        alias creal maxPrecT;
    } else static if (isImaginary!(T)){
        alias ireal maxPrecT;
    } else {
        alias real maxPrecT;
    }
}

/// compile time integer to string
char [] ctfe_i2a(int i){
    char[] digit="0123456789";
    char[] res="".dup;
    if (i==0){
        return "0".dup;
    }
    bool neg=false;
    if (i<0){
        neg=true;
        i=-i;
    }
    while (i>0) {
        res=digit[i%10]~res;
        i/=10;
    }
    if (neg)
        return '-'~res;
    else
        return res;
}

/// compile time integer power
T ctfe_powI(T)(T x,int p){
    T xx=cast(T)1;
    if (p<0){
        p=-p;
        x=1/x;
    }
    for (int i=0;i<p;++i)
        xx*=x;
    return xx;
}

Change History

11/28/08 10:27:14 changed by Cyborg16

I've used compile-time int-to-string functions before, so it'd be nice to see one in tango. I tried writing a template-version for fun, but templates proved their stupidity:

tp_int2Str.d(14): pragma msg string expected for message, not '"-" ~ ['1','5']'

I'm sure I've got around that before, but anyway, it was a somewhat pointless exercise.

There is std.metastrings in phobos which presumably has a little more functionality and is entirely template based (athough the only advantage of templates is that they won't increase the executable size).

11/28/08 11:27:39 changed by Don Clugston

Here's my old basic CTFE itoa function. It has the advantage that it deals with multiple types.

// Convert from integral type to string.
char [] itoa(T)(T x)
{
    char [] s="";
    static if (is(T==byte)||is(T==short)||is(T==int)||is(T==long)) {
        if (x<0) {
            return "-" ~ itoa(-x);
        }
    }
    do {
        s = cast(char)('0' + (x%10)) ~ s;
        x/=10;
    } while (x>0);
    return s;
}

Cyborg -- std.metastrings was created before CTFE existed. It's mostly based on code which I wrote. CTFE is much more generally useful (since you can't use a template itoa from inside CTFE, but you can use CTFE from inside a template). The ONLY advantage templates have is that they aren't affected by the CTFE memory allocation bug.

I'm not sure that any of this stuff actually belongs in math, though (except pow).

11/28/08 15:28:40 changed by fawzi

I think you are right, larsivi just made me realize that some of these functions are in core.Traits, so it makes sense to add the others also there.

I will put them there.

i2a though I am not sure belongs there, and as you say pow, for sure not...

11/28/08 15:32:10 changed by fawzi

added to r4134 (I forgot the refs)

02/25/09 11:32:06 changed by larsivi

Does this mean that only pow and itoa are left of the original ticket?

03/29/09 13:16:04 changed by larsivi

  • milestone changed from 0.99.8 to 0.99.9.

02/01/10 20:13:58 changed by Don Clugston

  • milestone changed from 0.99.9 to 1.0.