www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3561] New: math.abs signature accepts static arrays, but errors internally.

http://d.puremagic.com/issues/show_bug.cgi?id=3561

           Summary: math.abs signature accepts static arrays, but errors
                    internally.
           Product: D
           Version: 2.036
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: diagnostic, patch
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: sandford jhu.edu


--- Comment #0 from Rob Jacques <sandford jhu.edu> 2009-11-30 13:10:14 PST ---
I ran into this while converting a Vector struct to the new value type static
arrays. Essentially, float[3] x; x.abs; Errors inside of the abs function. The
simple solution is to add !isArray!Num to the list of template constraints.
However, since I feel it's useful, I've also included a patch to add support
for static arrays to the abs function.

/***********************************
 * Calculates the absolute value
 *
 * For complex numbers, abs(z) = sqrt( $(POWER z.re, 2) + $(POWER z.im, 2) )
 * = hypot(z.re, z.im).
 */
pure nothrow Num abs(Num)(Num x)
    if (is(typeof(Num.init >= 0)) && is(typeof(-Num.init)) &&
        !isDynamicArray!Num &&
            !(is(Num* : const(ifloat*)) || is(Num* : const(idouble*))
                    || is(Num* : const(ireal*))))
{
    static if (isFloatingPoint!(Num))
        return fabs(x);
    else static if(isStaticArray!Num) {
        typeof(return) a;
        foreach(i,ref b; a)
            b = abs(x[i]);
        return a;
    } else
        return x>=0 ? x : -x;
}

pure nothrow auto abs(Num)(Num z)
    if (is(Num* : const(cfloat*)) || is(Num* : const(cdouble*))
            || is(Num* : const(creal*)))
{
    return hypot(z.re, z.im);
}

/** ditto */
pure nothrow real abs(Num)(Num y)
    if (is(Num* : const(ifloat*)) || is(Num* : const(idouble*))
            || is(Num* : const(ireal*)))
{
    return fabs(y.im);
}


unittest
{
    assert(isIdentical(abs(-0.0L), 0.0L));
    assert(isNaN(abs(real.nan)));
    assert(abs(-real.infinity) == real.infinity);
    assert(abs(-3.2Li) == 3.2L);
    assert(abs(71.6Li) == 71.6L);
    assert(abs(-56) == 56);
    assert(abs(2321312L)  == 2321312L);
    assert(abs(-1+1i) == sqrt(2.0));
    assert(abs([-1,-2,-3]) == [1,2,3]);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 30 2009