1 // Written in the D programming language. 2 3 /** This module contains asForwardRange(). 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/_asforwardrange.d) 13 */ 14 module sargon.array.asforwardrange; 15 16 import sargon.array.asinputrange; 17 18 /** 19 * Turn an array into a ForwardRange, useful for unittesting. 20 * 21 * Params: 22 * a = is an array of elements of type E 23 * 24 * Returns: 25 * a ForwardRange 26 */ 27 auto ref asForwardRange(E)(E[] a) 28 { 29 static struct asForwardRangeImpl 30 { 31 this(E[] a) 32 { 33 this.a = a; 34 } 35 36 @property bool empty() 37 { 38 hasData = (a.length != 0); 39 return !hasData; 40 } 41 42 @property ref E front() 43 { 44 assert(hasData); 45 return a[0]; 46 } 47 48 void popFront() 49 { 50 a = a[1 .. $]; 51 hasData = false; 52 } 53 54 @property asForwardRangeImpl save() 55 { 56 return this; 57 } 58 59 private: 60 E[] a; 61 bool hasData; 62 } 63 return asForwardRangeImpl(a); 64 } 65 66 /// 67 unittest 68 { 69 import std.range; 70 71 static assert(isForwardRange!(typeof(asForwardRange("hello")))); 72 73 void testrange(string f, string result) 74 { 75 char[50] s; 76 int i; 77 foreach (c; f.asForwardRange()) 78 { 79 s[i++] = c; 80 } 81 assert(s[0 .. i] == result); 82 } 83 testrange("file", "file"); 84 85 { // various boundary conditions 86 auto r = "foo".asForwardRange; 87 auto s = r.save; 88 assert(!r.empty); 89 assert(!r.empty); 90 r.popFront(); 91 r.popFront(); 92 r.popFront(); 93 assert(r.empty); 94 95 assert(!s.empty); 96 assert(!s.empty); 97 s.popFront(); 98 s.popFront(); 99 s.popFront(); 100 assert(s.empty); 101 } 102 } 103 104 private import std.range; 105 106 /*************************************** 107 * Takes an ForwardRange as input and verifies 108 * that it can be iterated following protocol. 109 * 110 * Params: 111 * r = is a ForwardRange 112 */ 113 114 void testForwardRange(R)(R r) if (isForwardRange!R) 115 { 116 auto rsave = r.save; 117 testInputRange(rsave); 118 119 static if (isInfinite!R) 120 { 121 foreach (i; 0 .. 10) 122 { 123 while (!r.empty) 124 { 125 auto e = r.front; 126 auto e2 = r.front; 127 assert(e == e2); 128 r.popFront(); 129 } 130 } 131 } 132 else 133 { 134 while (!r.empty) 135 { 136 auto e = r.front; 137 auto e2 = r.front; 138 assert(e == e2); 139 r.popFront(); 140 } 141 } 142 } 143 144 /// 145 unittest 146 { 147 testForwardRange(asForwardRange("betty")); 148 }