| ... | ... | @@ -3015,6 +3015,55 @@ test "reverse" { |
| 3015 | 3015 | try testing.expect(eql(i32, &arr, &[_]i32{ 4, 2, 1, 3, 5 })); |
| 3016 | 3016 | } |
| 3017 | 3017 | |
| 3018 | fn ReverseIterator(comptime T: type) type { |
| 3019 | const info: struct { Child: type, Pointer: type } = blk: { |
| 3020 | switch (@typeInfo(T)) { |
| 3021 | .Pointer => |info| switch (info.size) { |
| 3022 | .Slice => break :blk .{ |
| 3023 | .Child = info.child, |
| 3024 | .Pointer = @Type(.{ .Pointer = .{ |
| 3025 | .size = .Many, |
| 3026 | .is_const = info.is_const, |
| 3027 | .is_volatile = info.is_volatile, |
| 3028 | .alignment = info.alignment, |
| 3029 | .address_space = info.address_space, |
| 3030 | .child = info.child, |
| 3031 | .is_allowzero = info.is_allowzero, |
| 3032 | .sentinel = info.sentinel, |
| 3033 | } }), |
| 3034 | }, |
| 3035 | else => {}, |
| 3036 | }, |
| 3037 | else => {}, |
| 3038 | } |
| 3039 | @compileError("reverse iterator expects slice, found " ++ @typeName(T)); |
| 3040 | }; |
| 3041 | return struct { |
| 3042 | ptr: info.Pointer, |
| 3043 | index: usize, |
| 3044 | pub fn next(self: *@This()) ?info.Child { |
| 3045 | if (self.index == 0) return null; |
| 3046 | self.index -= 1; |
| 3047 | return self.ptr[self.index]; |
| 3048 | } |
| 3049 | }; |
| 3050 | } |
| 3051 | |
| 3052 | /// Iterate over a slice in reverse. |
| 3053 | pub fn reverseIterator(slice: anytype) ReverseIterator(@TypeOf(slice)) { |
| 3054 | return .{ .ptr = slice.ptr, .index = slice.len }; |
| 3055 | } |
| 3056 | |
| 3057 | test "reverseIterator" { |
| 3058 | const slice: []const i32 = &[_]i32{ 5, 3, 1, 2 }; |
| 3059 | var it = reverseIterator(slice); |
| 3060 | try testing.expectEqual(@as(?i32, 2), it.next()); |
| 3061 | try testing.expectEqual(@as(?i32, 1), it.next()); |
| 3062 | try testing.expectEqual(@as(?i32, 3), it.next()); |
| 3063 | try testing.expectEqual(@as(?i32, 5), it.next()); |
| 3064 | try testing.expectEqual(@as(?i32, null), it.next()); |
| 3065 | } |
| 3066 | |
| 3018 | 3067 | /// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1) |
| 3019 | 3068 | /// Assumes 0 <= amount <= items.len |
| 3020 | 3069 | pub fn rotate(comptime T: type, items: []T, amount: usize) void { |