On Wednesday, 16 May 2012 at 07:04:09 UTC, Jonathan M Davis wrote:
that assertion would pass, but it doesn't, and it shouldn't. If your range was a reference type (e.g. if it were a class or it was like the ranges in std.stdio which deal with I/O), then using it with foreach would consume it, but that won't happen with a value type range.

Then perhaps I'm missing something. Some time ago (6 months?) I submitted a similar example of this to walter; a little prime walking range-like struct that acts like a range. It may contain an AA, but otherwise basic structure isn't far from his...

Could you explain why mine works and his doesn't? (Extras taken out proving ever number is a prime)

---
import std.stdio;

struct prime_walk {
  int map[int];
  int position = 2;
  int cap = int.max;

  int front() {
    return position;
  }

  void popFront() {
    //where the real work is done.

    if ((position & 1) == 0) {
      position++;
    } else if (position >= cap) {
      throw new Exception("Out of bounds!");
    } else {
      int div = position;
      int p2 = position * 3;

      //current spot IS a prime. So...
      if (p2 < cap)
        map[p2] = div;

      position += 2;

      //identify marked spot, if so we loop again.
      while (position in map) {
        div = map[position];
        map.remove(position);
        p2 = position;
        do
          p2 += div * 2;
        while (p2 in map);

        position += 2;
if (p2 <= cap) //skip out, no need to save larger than needed values.
          map[p2] = div;
      }
    }
  }

  bool empty() {
    return position >= cap;
  }
}

void main() {
  prime_walk pw;
  pw.cap = 100;
  foreach(i; pw)
    writeln(i);
}

Reply via email to