1 /**
2     Returns a slice of a range
3 */
4 module ddash.range.slicing;
5 
6 ///
7 unittest {
8     auto arr = [1, 2, 3, 4, 5];
9 
10     assert(arr.slice(1).equal([2, 3, 4, 5]));
11     assert(arr.slice(0, 0).empty);
12     assert(arr.slice(1, 3).equal([2, 3]));
13     assert(arr.slice(0, -2).equal([1, 2, 3]));
14 
15     assert(arr.initial.equal([1, 2, 3, 4]));
16 
17     assert(arr.tail.equal([2, 3, 4, 5]));
18 }
19 
20 import ddash.common;
21 
22 /**
23     Returns a slice of range from start up to, but not including, end
24 
25     If end is not provided the whole rest of the range is implied. And if
26     end is a negative number then it's translated to `range.length - abs(end)`.`
27 
28     Params:
29         range = the input range to slice
30         start = at which index to start the slice
31         end = which index to end the slice
32 
33     Returns:
34         A range
35 
36     Since:
37         0.0.1
38 */
39 auto slice(Range)(Range range, size_t start, int end) {
40     import std.range: drop, take, takeNone, walkLength;
41     if (!end) {
42         return range.takeNone;
43     }
44     size_t absoluteEnd = end;
45     if (end < 0) {
46         absoluteEnd = range.walkLength + end;
47     }
48     return range.drop(start).take(absoluteEnd - start);
49 }
50 
51 /// Ditto
52 auto slice(Range)(Range range, size_t start) {
53     import std.range: drop;
54     return range.drop(start);
55 }
56 
57 /**
58     Gets all but the first element of a range
59 
60     Params:
61         range = an input range
62 
63     Returns:
64         A range
65 
66     Since:
67         0.0.1
68 */
69 alias tail = (range) => from!"std.range".drop(range, 1);
70 
71 ///
72 unittest {
73     assert((int[]).init.tail.empty);
74     assert([1, 2, 3, 4].tail.equal([2, 3, 4]));
75 }
76 
77 /**
78     Gets all but the last element of a range
79 
80     Params:
81         range = an input range
82 
83     Returns:
84         A range
85 
86     Since:
87         0.0.1
88 */
89 alias initial = (range) => from!"std.range".dropBack(range, 1);
90 
91 ///
92 unittest {
93     assert((int[]).init.initial.empty);
94     assert([1, 2, 3, 4].initial.equal([1, 2, 3]));
95 }