Please rid me of this goto

Walter Bright via Digitalmars-d digitalmars-d at puremagic.com
Thu Jun 23 14:25:45 PDT 2016


On 6/23/2016 10:22 AM, Andrei Alexandrescu wrote:
> https://dpaste.dzfl.pl/e53acb41885a

Paste bin links are ephemeral. The code from the link:

/**
*/
int pow(int lhs, uint rhs, ref bool overflow)
{ return powImpl(lhs, rhs, overflow); }
/// ditto
long pow(long lhs, uint rhs, ref bool overflow)
{ return powImpl(lhs, rhs, overflow); }
/// ditto
uint pow(uint lhs, uint rhs, ref bool overflow)
{ return powImpl(lhs, rhs, overflow); }
/// ditto
ulong pow(ulong lhs, uint rhs, ref bool overflow)
{ return powImpl(lhs, rhs, overflow); }

// Inspiration: http://www.stepanovpapers.com/PAM.pdf
private T powImpl(T)(T b, uint e, ref bool overflow)
{
     import core.checkedint : muls, mulu;
     import std.traits : isUnsigned;
     static if (isUnsigned!T) alias mul = mulu;
     else alias mul = muls;

     if (e <= 1)
     {
         if (e == 1) return b;
         if (b == 0) overflow = true;
         return 1;
     }

     T r = b;
     assert(e > 1);
     --e;
     // Loop invariant: r * (b ^^ e) is the actual result
     outer: for (;;)
     {
         if (e % 2 != 0) goto geeba;
         for (;;)
         {
             b = mul(b, b, overflow);
             e /= 2;
             continue outer;
         geeba:
             r = mul(r, b, overflow);
             if (e == 1) return r;
         }
     }
     assert(0);
}

unittest
{
     import std.stdio;
     bool overflow;
     foreach (uint i; 0 .. 21)
     {
         assert(pow(3u, i, overflow) == 3u ^^ i);
         assert(!overflow);
     }
     assert(pow(3u, 21u, overflow) == 3u ^^ 21);
     assert(overflow);
}

void main(){}




More information about the Digitalmars-d mailing list