On Thursday, 20 January 2022 at 16:33:20 UTC, Ali Çehreli wrote:

So if we add the 1.0 value after 0.9000000357627869 to be *inclusive*, then that last step would not be 0.3 anymore. (Thinking about it, step would mess up things for integral types as well; so, it must be checked during construction.)

The other obvious issue in the output is that a floating point iota cannot be bidirectional because the element values would be different.

The test that did not pass now passes. There is the issue of T.min being excluded from the property list for the double type. I tried to solve it, how is it?

Salih

```d
auto inclusiveRange(T)(T f, T l, T s = cast(T)0)
in(!isBoolean!T) {
  static assert(!isBoolean!T, "\n
      Cannot be used with bool type\n");
  if(!s) s++;
  return InclusiveRange!T(f, l, s);
}

struct InclusiveRange(T) {
  private:
    T first, last;
    bool empty_;

  public:
    T step;

  this(U)(in U first, in U last, in U step)
  in (first <= last, format!"\n
      Invalid range:[%s,%s]."(first, last))
  {
    this.first = first;
    this.last = last;
    this.step = step;
    this.empty_ = false;
  }

  bool opBinaryRight(string op:"in")(T rhs) {
    foreach(r; this) {
      if(r == rhs) return true;
    }
    return false;
  }

  auto save() inout { return this; }
  bool empty() inout { return empty_; }
  T front() inout { return first; }
  T back() inout { return last; }

  void popFront() {
    if(!empty) {
      if(last >= first + step) {
        first += step;
      } else {
        empty_ = true;
        if(T.max <= first + step) {
          first += step;
        }
      }
    }
  }

  void popBack() {
    if(!empty) {
      if(first <= last-step) {
        last -= step;
      } else {
        empty_ = true;
        if(!T.max >= last - step) {
          last -= step;
        }
      }
    }
  }

  size_t length() inout {
    auto len = 1 + (last - first) / step;
    return cast(size_t)len;
  }
}

import std.algorithm, std.math;
import std.range, std.traits;
import std.stdio, std.format, std.conv;

void main() {
  // Pi Number Test
  auto GregorySeries = inclusiveRange!double(1, 0x1.0p+27, 2);
  double piNumber = 0;
  foreach(e, n; GregorySeries.enumerate) {
    if(e & 1) piNumber -= 1/n;
    else piNumber += 1/n;
  }
  writefln!"%.21f (constant)"(PI);
  writefln!"%.21f (calculated)"(piNumber * 4);

} unittest {
  // Should not be possible to have an empty range

  auto r = inclusiveRange(ubyte.min, ubyte.max);
  static assert(is(ElementType!(typeof(r)) == ubyte));

  assert(r.sum == (ubyte.max * (ubyte.max + 1)) / 2);
}
```


Reply via email to