I saw it on the Phobos list and whipped together a first try. Here's the code:

====
import std.conv;

class BoundedOverflowException : Exception {
        this(string msg) {
                super(msg);
        }
}

struct Bounded(T, T min, T max) {
        T _payload;

        static string runCheckCode() { return q{
                asm {
                        jo overflow;
                }
                if(_payload < min) goto overflow;
                if(_payload > max) goto overflow;

                goto ok;

                overflow:
                        throw new BoundedOverflowException("Overflow at 
"~file~":"~to!string(line)~"
(payload: " ~ to!string(_payload) ~ ")");
                ok:
                        ;
                };
        }

        T opUnary(string op, string file = __FILE__, int line = __LINE__)() {
                mixin("_payload " ~ op ~ ";");

                mixin(runCheckCode());
        }

        T opBinary(string op, string file = __FILE__, int line = __LINE__)(T 
rhs) {
                T tmp = void;
                mixin("tmp = _payload " ~ op ~ "rhs;");
                _payload = tmp;

                mixin(runCheckCode());
                return tmp;
        }

        T opOpAssign(string op, string file = __FILE__, int line = __LINE__)(T 
rhs) {
                T tmp = void;
                mixin("tmp = _payload " ~ op ~ "rhs;");
                _payload = tmp;

                mixin(runCheckCode());
                return _payload;
        }

        T opAssign(T rhs, string file = __FILE__, int line = __LINE__) {
                _payload = rhs;

                mixin(runCheckCode());
                return _payload;
        }

        string toString() {
                return to!string(_payload);
        }

        alias _payload this;
}

import std.stdio;

void main() {
        Bounded!(int, int.min, int.max) a;

        a = int.max;

        a += 5; // throws
        writefln("%s", a);

        a += 5;
        writefln("%s", a);

        a += 5;
}
=======

It uses a mixin to do the check, so the jo instruction works so it catches
wrapping overflow too.

I'm sure it is broken with types other than int right now, but it might be a
starting point.

Reply via email to