authorgravatar for johnnymarler@gmail.comJonathan Marler <johnnymarler@gmail.com> 2022-12-02 12:04:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-13 15:13:25-05:00
log5d3adc568c7f0d4720bbd283337404c3cad86479
tree5f148aa02cef15813df0df186a2d39dbad81de57
parent02b4ea71e3a30d9076cd0c145777c792f2e4245b

add std.mem.reverseIterator


1 files changed, 49 insertions(+), 0 deletions(-)

lib/std/mem.zig+49
......@@ -3015,6 +3015,55 @@ test "reverse" {
30153015 try testing.expect(eql(i32, &arr, &[_]i32{ 4, 2, 1, 3, 5 }));
30163016}
30173017
3018fn 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.
3053pub fn reverseIterator(slice: anytype) ReverseIterator(@TypeOf(slice)) {
3054 return .{ .ptr = slice.ptr, .index = slice.len };
3055}
3056
3057test "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
30183067/// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)
30193068/// Assumes 0 <= amount <= items.len
30203069pub fn rotate(comptime T: type, items: []T, amount: usize) void {