On Tue, Feb 16, 2010 at 11:26:37AM -0600, Ellery Newcomer wrote:
> OT: has anyone written a wrapper for int/long/etc that throws exceptions 
> on overflow/underflow? Maybe such a thing should exist in the standard 
> library?

Something along these lines should work (pasted at bottom of message).

I'd like it a lot more if it could just be opBinary!(string)() -- the struct
would be tiny.

Suckily, assigning an it to it when declaring it doesn't work. I think there's
a way around this, but I don't know.

The opPow's are commented out since my dmd is too old, so I couldn't test it.


========

import std.stdio;

struct NoOverflow(T) {
        T _payload;
        alias _payload this;

        T opAdd(T a) {
                T tmp = _payload + a;
                asm { jo overflow; }
                return tmp;
                overflow:
                        throw new Exception("Overflow");
        }

        T opSub(T a) {
                T tmp = _payload - a;
                asm { jo overflow; }
                return tmp;
                overflow:
                        throw new Exception("Overflow");
        }

        T opMul(T a) {
                T tmp = _payload * a;
                asm { jo overflow; }
                return tmp;
                overflow:
                        throw new Exception("Overflow");
        }

        T opDiv(T a) {
                T tmp = _payload / a;
                asm { jo overflow; }
                return tmp;
                overflow:
                        throw new Exception("Overflow");
        }

        /+
        T opPow(T a) {
                T tmp = _payload ^^ a;
                asm { jo overflow; }
                return tmp;
                overflow:
                        throw new Exception("Overflow");
        }
        +/

        T opAddAssign(T a) {
                _payload += a;
                asm { jo overflow; }
                return this;
                overflow:
                        throw new Exception("Overflow");
        }

        T opSubAssign(T a) {
                _payload -= a;
                asm { jo overflow; }
                return this;
                overflow:
                        throw new Exception("Overflow");
        }

        T opMulAssign(T a) {
                _payload *= a;
                asm { jo overflow; }
                return this;
                overflow:
                        throw new Exception("Overflow");
        }

        T opDivAssign(T a) {
                _payload /= a;
                asm { jo overflow; }
                return this;
                overflow:
                        throw new Exception("Overflow");
        }

        T opPowAssign(T a) {
                //_payload ^^= a;
                asm { jo overflow; }
                return this;
                overflow:
                        throw new Exception("Overflow");
        }

        T opPostInc() {
                _payload++;
                asm { jo overflow; }
                return this;
                overflow:
                        throw new Exception("Overflow");
        }

        T opPostDec() {
                _payload--;
                asm { jo overflow; }
                return this;
                overflow:
                        throw new Exception("Overflow");
        }
}

void main() {
        alias NoOverflow!(int) oint;

        oint a;
        a = int.max;
        a--;
        writefln("%d", a);
        a++;
        writefln("%d", a);
        a++; // should throw
        writefln("%d", a);
}

=======


-- 
Adam D. Ruppe
http://arsdnet.net

Reply via email to