1 // Written in the D programming language.
2 
3 /** This module contains asInputRange().
4 
5     Authors:
6         $(WEB digitalmars.com, Walter Bright)
7     Copyright:
8         Copyright (c) 2014-, the authors. All rights reserved.
9     License:
10         $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0)
11     Source:
12         $(SARGONSRC src/sargon/_array/_asinputrange.d)
13 */
14 module sargon.array.asinputrange;
15 
16 /**
17  * Turn an array into an InputRange, useful for unittesting.
18  *
19  * Params:
20  *      a = is an array of elements of type E
21  *
22  * Returns:
23  *      an InputRange
24  */
25 auto ref asInputRange(E)(E[] a)
26 {
27     static struct asInputRangeImpl
28     {
29         this(E[] a)
30         {
31             this.a = a;
32         }
33 
34         @property bool empty()
35         {
36             hasData = (a.length != 0);
37             return !hasData;
38         }
39 
40         @property ref E front()
41         {
42             assert(hasData);
43             return a[0];
44         }
45 
46         void popFront()
47         {
48             a = a[1 .. $];
49             hasData = false;
50         }
51 
52       private:
53         E[] a;
54         bool hasData;
55     }
56     return asInputRangeImpl(a);
57 }
58 
59 ///
60 unittest
61 {
62     import std.range;
63 
64     static assert(isInputRange!(typeof(asInputRange("hello"))));
65 
66     void testrange(string f, string result)
67     {
68         char[50] s;
69         int i;
70         foreach (c; f.asInputRange())
71         {
72             s[i++] = c;
73         }
74         assert(s[0 .. i] == result);
75     }
76     testrange("file", "file");
77 
78     {   // various boundary conditions
79         auto r = "foo".asInputRange;
80         assert(!r.empty);
81         assert(!r.empty);
82         r.popFront();
83         r.popFront();
84         r.popFront();
85         assert(r.empty);
86     }
87 }
88 
89 private import std.range;
90 
91 /***************************************
92  * Takes an InputRange as input and verifies
93  * that it can be iterated following protocol.
94  *
95  * Params:
96  *      r = is an InputRange
97  */
98 
99 void testInputRange(R)(R r) if (isInputRange!R)
100 {
101     static if (isInfinite!R)
102     {
103         foreach (i; 0 .. 10)
104         {
105             while (!r.empty)
106             {
107                 auto e = r.front;
108                 auto e2 = r.front;
109                 assert(e == e2);
110                 r.popFront();
111             }
112         }
113     }
114     else
115     {
116         while (!r.empty)
117         {
118             auto e = r.front;
119             auto e2 = r.front;
120             assert(e == e2);
121             r.popFront();
122         }
123     }
124 }
125 
126 ///
127 unittest
128 {
129     testInputRange(asInputRange("betty"));
130 }