Advertisement
Guest User

generator.d

a guest
Jul 4th, 2013
258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 1.75 KB | None | 0 0
  1. import core.thread;
  2.  
  3. import std.stdio;
  4. import std.range;
  5. import std.algorithm;
  6. import std.array;
  7.  
  8. class Gen(E) {
  9. private:
  10.     Fiber fiber;
  11.     E frontCopy;
  12.     bool dataHeld = false;
  13.  
  14. public:
  15.     @trusted this(void delegate(void delegate(E)) run) {
  16.         this.fiber = new Fiber(() {
  17.             run((E value) {
  18.                 frontCopy = value;
  19.                 dataHeld = true;
  20.  
  21.                 Fiber.yield();
  22.             });
  23.         });
  24.     }
  25.  
  26.     @trusted bool empty() {
  27.         if (dataHeld) {
  28.             // We are holding data we haven't popped yet.
  29.             return false;
  30.         }
  31.  
  32.         if (fiber.state == Fiber.State.TERM) {
  33.             // We hit the end of the fiber.
  34.             return true;
  35.         }
  36.  
  37.         // Call the fibre to ask for more data.
  38.         fiber.call();
  39.  
  40.         // Check if this caused us to hit the end.
  41.         return !dataHeld;
  42.     }
  43.  
  44.  
  45.     @trusted E front() {
  46.         if (empty) {
  47.             throw new Error("front called at end of iteration!");
  48.         }
  49.  
  50.         return frontCopy;
  51.     }
  52.  
  53.     @trusted void popFront() {
  54.         if (empty) {
  55.             throw new Error("popFront called at end of iteration!");
  56.         }
  57.  
  58.         dataHeld = false;
  59.     }
  60. }
  61.  
  62. Gen!E generate(E)(void delegate(void delegate(E)) run) {
  63.     return new Gen!E(run);
  64. }
  65.  
  66. void main(string[] argv) {
  67.     Gen!int generateInts() {
  68.         return generate!int((yield) {
  69.             yield(3);
  70.             yield(4);
  71.             yield(7);
  72.         });
  73.     }
  74.  
  75.     // Prints 3, 4, 7
  76.     foreach(x; generateInts()) {
  77.         writeln(x);
  78.     }
  79.  
  80.     // true
  81.     writeln(isInputRange!(typeof(generateInts())));
  82.  
  83.     auto arr = generateInts().map!(x => x * 2).array;
  84.  
  85.     // [6, 8, 14]
  86.     writeln(arr);
  87. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement