On Monday, 8 February 2016 at 03:09:53 UTC, Enjoys Math wrote:
was wondering if there's a D
native way of doing it.

That is the D native way of doing it, but you could clean up a lot of the boilerplate with some more templates. Also, || tests for exclusion, as in whether something is NOT in the range [a,b] (it's either above or below).

Also not sure why you have EPS=1 for integers. 1 ∈ [1,1] but 1-1 is outside of [1,1].

template EPS(T) {
        static if (is(T == double)) {
                T EPS = 0.000_000_001;
        }
        static if (is(T == float)) {
                T EPS = 0.000_001;
        }
        static if (is(T == int)) {
                T EPS = 0;
        }
}

struct DerpRange(T) {
        T low;
        T hi;
}
// because the constructor Range(1,2) can't POSSIBLY be deduced
// to be Range!(int)(1,2)
DerpRange!T Range(T) (T low, T hi) {
        return DerpRange!T(low, hi);
}


bool in_range(T) (T what, DerpRange!T range) {
        return
                what - EPS!T >= range.low &&
                what + EPS!T <= range.hi;
}

bool in_range(T) (T what, T low, T hi) {
        return in_range(what,DerpRange!T(low,hi));
}

void main() {
        import std.stdio: writeln;

        void check(bool success) {
                if(success) {
                        writeln("yay!");
                } else {
                        throw new Exception("fail...");
                }
        }
        check(!in_range(3,4,5));
        check(in_range(3,3,5));
        check(in_range(3,2,5));
        check(in_range(3,2,3));
        check(!in_range(3,2,2));
        check(in_range(3,Range(0,99)));
        auto r = Range(0,99);
        check(in_range(42,r));

        for(int i=0;i<10;++i) {
                import std.random: uniform;
                int what = uniform!"[]"(0,99);
                check(in_range(what,r));
                check(in_range(what,0,99));
                check(in_range(what,Range(0,99)));
        }
}

Reply via email to