1 /**
2 *   Copyright: © 2014 Anton Gushcha
3 *   License: Subject to the terms of the MIT license, as written in the included LICENSE file.
4 *   Authors: NCrashed <ncrashed@gmail.com>
5 */
6 module dcheck.generator;
7 
8 import std.range;
9 import dcheck.maybe;
10 
11 /**
12 *   Transforms delegate into lazy range. Generation is stopped, when
13 *   $(B genfunc) returns $(B Maybe!T.nothing).
14 */
15 auto generator(T)(Maybe!T delegate() genfunc)
16 {
17     struct Sequencer
18     {
19         private Maybe!T currvalue;
20         
21         T front()
22         {
23             assert(!currvalue.isNothing, "Generator range is empty!");
24             return currvalue.get;
25         }
26         
27         bool empty()
28         {
29             return currvalue.isNothing;
30         }
31         
32         void popFront()
33         {
34             currvalue = genfunc();
35         }
36     }
37     static assert(isInputRange!Sequencer);
38     
39     auto s = Sequencer();
40     s.popFront;
41     return s;
42 }
43 /// Example
44 unittest
45 {
46     assert( (() => Maybe!int(1)).generator.take(10).equal(1.repeat.take(10)) );
47     assert( (() => Maybe!int.nothing).generator.empty);
48     assert( (() 
49             {
50                 static size_t i = 0;
51                 return i++ < 10 ? Maybe!int(1) : Maybe!int.nothing;
52             }
53             ).generator.equal(1.repeat.take(10)));
54     
55     class A {}
56     auto a = new A();
57     
58     assert( (() => Maybe!A(a)).generator.take(10).equal(a.repeat.take(10)) );
59     assert( (() => Maybe!A.nothing).generator.empty);
60     assert( (() 
61             {
62                 static size_t i = 0;
63                 return i++ < 10 ? Maybe!A(a) : Maybe!A.nothing;
64             }
65             ).generator.equal(a.repeat.take(10)));
66 }