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 }