| ... | @@ -3015,6 +3015,55 @@ test "reverse" { | ... | @@ -3015,6 +3015,55 @@ test "reverse" { |
| 3015 | try testing.expect(eql(i32, &arr, &[_]i32{ 4, 2, 1, 3, 5 })); | 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 | /// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1) | 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 | /// Assumes 0 <= amount <= items.len | 3068 | /// Assumes 0 <= amount <= items.len |
| 3020 | pub fn rotate(comptime T: type, items: []T, amount: usize) void { | 3069 | pub fn rotate(comptime T: type, items: []T, amount: usize) void { |