1 module nxt.sample_fibers; 2 3 import core.thread: Fiber; 4 5 void fibonacciSeriesRef(ref int current) 6 { 7 current = 0; // Note: 'current' is the parameter 8 int next = 1; 9 while (true) 10 { 11 Fiber.yield(); 12 /* Next call() will continue from this point */ 13 const nextNext = current + next; 14 current = next; 15 next = nextNext; 16 } 17 } 18 19 unittest 20 { 21 int current; 22 Fiber fiber = new Fiber(() => fibonacciSeriesRef(current)); 23 import std.stdio; 24 foreach (_; 0 .. 10) 25 { 26 fiber.call(); // return 27 write(current, ", "); 28 } 29 writeln; 30 } 31 32 import std.stdio; 33 34 import std.concurrency: yield; 35 36 void fibonacciSeries() 37 { 38 int current = 0; // <-- Not a parameter anymore 39 int next = 1; 40 while (true) 41 { 42 current.yield; // return 43 const nextNext = current + next; 44 current = next; 45 next = nextNext; 46 } 47 } 48 49 unittest 50 { 51 import std.concurrency: yield, Generator; 52 auto series = new Generator!int(&fibonacciSeries); 53 import std.range: take; 54 writefln("%(%s, %)", series.take(10)); 55 } 56 57 struct Yields { string type; } 58 59 @Yields("int") // <-- better to specify type here than in caller 60 void fibonacciSeries2() 61 { 62 int current = 0; 63 int next = 1; 64 while (true) 65 { 66 current.yield; // return 67 const nextNext = current + next; 68 current = next; 69 next = nextNext; 70 } 71 } 72 73 auto generator(alias func)() 74 { 75 import std.format: format; 76 foreach (attr; __traits(getAttributes, func)) 77 { 78 import std.traits: isInstanceOf; 79 static if (is (typeof(attr) == Yields)) 80 { 81 mixin (format("alias YieldedType = %s;", attr.type)); 82 import std.concurrency: Generator; 83 return new Generator!YieldedType(&func); 84 } 85 } 86 assert(0, format("%s does not have a Yields attribute", 87 func.stringof)); 88 } 89 90 unittest 91 { 92 import std.stdio; 93 import std.range: take; 94 auto series = generator!fibonacciSeries2; // <-- THIS TIME, NO 'int' 95 writefln("%(%s, %)", series.take(10)); 96 }