1 module tagion.basic.range; 2 import std.range; 3 4 @safe: 5 /** 6 * Tries to do a front but it is empty it return T.init 7 * Returns: 8 * If the range is not empty the first element is return 9 * else the .init value of the range element type is return 10 * The first element is returned 11 */ 12 T doFront(Range, T = ElementType!Range)(Range r, T default_value = T.init) if (isInputRange!Range) { 13 if (r.empty || r is Range.init) { 14 return default_value; 15 } 16 return r.front; 17 } 18 19 /// 20 unittest { 21 { 22 int[] a; 23 static assert(isInputRange!(typeof(a))); 24 assert(a.doFront is int.init); 25 } 26 { 27 const a = [1, 2, 3]; 28 assert(a.doFront is a[0]); 29 } 30 31 } 32 33 /** 34 * Returns the first element in the range r and pops then next 35 * Params: 36 * r =range 37 * Returns: r.front 38 */ 39 T eatOne(Range, T = ElementType!Range)(ref Range r, T default_value = T.init) if (isInputRange!Range) { 40 41 if (r.empty) { 42 return default_value; 43 } 44 scope (exit) { 45 if (!r.empty) { 46 r.popFront; 47 } 48 } 49 return r.front; 50 } 51 52 //// 53 unittest { 54 const(int)[] a = [1, 2, 3]; 55 assert(eatOne(a) == 1); 56 assert(eatOne(a) == 2); 57 assert(eatOne(a) == 3); 58 assert(a.empty); 59 assert(eatOne(a, -1) == -1); 60 assert(eatOne(a) == int.init); 61 }