On 19/02/2018 1:24 PM, Simen Kjærås wrote:
On Monday, 19 February 2018 at 12:58:45 UTC, Marc wrote:
I'm pretty sure something could be done with Ada's type range but what we could do using D?

We can easily define a range type in D. The simple example below probably has awful performance and many holes, but outlines the basic idea. It will not have compile-time bounds checks, but can be used as an int when it needs to, and enforces at run-time that the value is within the specified bounds.

import std.format : format;
import std.exception : enforce;

struct Range(T, T min, T max, T defaultValue = 0)
if (defaultValue >= min && defaultValue <= max)
{
     private T payload;

     this(T value)
     {
         this = value;
     }

     T get() { return payload; }
     alias get this;

     Range opBinary(string op)(T value)
     {
         return Range(mixin("payload "~op~" value"));
     }

     ref Range opOpAssing(string op)(T value)
     {
         this = Range(mixin("payload "~op~" value"));
         return this;
     }

    ref Range opAssign(T value, string file = __FILE__, int line = __LINE__)
     {
        enforce(value <= max && value >= min, format("Value needs to be between %s and %s, not %s.", min, max, value), file, line);
         payload = value;
         return this;
     }
}

unittest
{
     Range!(int, 3, 15, 3) a = 4;
     a = 16; // foo.d(38): Value needs to be between 3 and 15, not 16.
     int n = a;
}

It currently does no sensible testing of what operators it allows, and does not support unary operators. Other potential improvements include merging of bounds when the other operand is a range as well (so Range!(int, 3, 6) + Range!(int, 2, 8) returns a Range!(int, 5, 14)). Perhaps a more sensible default value would be min(maxValue, max(0, minValue)).

--
   Simen

https://dlang.org/phobos/std_experimental_checkedint.html#.Checked.min

Reply via email to