mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
std.mem.reverseIterator: accept pointer to array
This commit is contained in:
parent
9cb2919d50
commit
0bbc1ec206
@ -2989,32 +2989,35 @@ test "reverse" {
|
||||
}
|
||||
|
||||
fn ReverseIterator(comptime T: type) type {
|
||||
const info: struct { Child: type, Pointer: type } = blk: {
|
||||
const Pointer = blk: {
|
||||
switch (@typeInfo(T)) {
|
||||
.Pointer => |info| switch (info.size) {
|
||||
.Slice => break :blk .{
|
||||
.Child = info.child,
|
||||
.Pointer = @Type(.{ .Pointer = .{
|
||||
.size = .Many,
|
||||
.is_const = info.is_const,
|
||||
.is_volatile = info.is_volatile,
|
||||
.alignment = info.alignment,
|
||||
.address_space = info.address_space,
|
||||
.child = info.child,
|
||||
.is_allowzero = info.is_allowzero,
|
||||
.sentinel = info.sentinel,
|
||||
} }),
|
||||
.Pointer => |ptr_info| switch (ptr_info.size) {
|
||||
.One => switch (@typeInfo(ptr_info.child)) {
|
||||
.Array => |array_info| {
|
||||
var new_ptr_info = ptr_info;
|
||||
new_ptr_info.size = .Many;
|
||||
new_ptr_info.child = array_info.child;
|
||||
new_ptr_info.sentinel = array_info.sentinel;
|
||||
break :blk @Type(.{ .Pointer = new_ptr_info });
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
.Slice => {
|
||||
var new_ptr_info = ptr_info;
|
||||
new_ptr_info.size = .Many;
|
||||
break :blk @Type(.{ .Pointer = new_ptr_info });
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
@compileError("reverse iterator expects slice, found " ++ @typeName(T));
|
||||
@compileError("expected slice or pointer to array, found '" ++ @typeName(T) ++ "'");
|
||||
};
|
||||
const Element = std.meta.Elem(Pointer);
|
||||
return struct {
|
||||
ptr: info.Pointer,
|
||||
ptr: Pointer,
|
||||
index: usize,
|
||||
pub fn next(self: *@This()) ?info.Child {
|
||||
pub fn next(self: *@This()) ?Element {
|
||||
if (self.index == 0) return null;
|
||||
self.index -= 1;
|
||||
return self.ptr[self.index];
|
||||
@ -3022,19 +3025,41 @@ fn ReverseIterator(comptime T: type) type {
|
||||
};
|
||||
}
|
||||
|
||||
/// Iterate over a slice in reverse.
|
||||
/// Iterates over a slice in reverse.
|
||||
pub fn reverseIterator(slice: anytype) ReverseIterator(@TypeOf(slice)) {
|
||||
return .{ .ptr = slice.ptr, .index = slice.len };
|
||||
const T = @TypeOf(slice);
|
||||
if (comptime trait.isPtrTo(.Array)(T)) {
|
||||
return .{ .ptr = slice, .index = slice.len };
|
||||
} else {
|
||||
comptime assert(trait.isSlice(T));
|
||||
return .{ .ptr = slice.ptr, .index = slice.len };
|
||||
}
|
||||
}
|
||||
|
||||
test "reverseIterator" {
|
||||
const slice: []const i32 = &[_]i32{ 5, 3, 1, 2 };
|
||||
var it = reverseIterator(slice);
|
||||
try testing.expectEqual(@as(?i32, 2), it.next());
|
||||
try testing.expectEqual(@as(?i32, 1), it.next());
|
||||
try testing.expectEqual(@as(?i32, 3), it.next());
|
||||
try testing.expectEqual(@as(?i32, 5), it.next());
|
||||
try testing.expectEqual(@as(?i32, null), it.next());
|
||||
{
|
||||
var it = reverseIterator("abc");
|
||||
try testing.expectEqual(@as(?u8, 'c'), it.next());
|
||||
try testing.expectEqual(@as(?u8, 'b'), it.next());
|
||||
try testing.expectEqual(@as(?u8, 'a'), it.next());
|
||||
try testing.expectEqual(@as(?u8, null), it.next());
|
||||
}
|
||||
{
|
||||
var array = [2]i32{ 3, 7 };
|
||||
const slice: []const i32 = &array;
|
||||
var it = reverseIterator(slice);
|
||||
try testing.expectEqual(@as(?i32, 7), it.next());
|
||||
try testing.expectEqual(@as(?i32, 3), it.next());
|
||||
try testing.expectEqual(@as(?i32, null), it.next());
|
||||
}
|
||||
{
|
||||
var array = [2]i32{ 3, 7 };
|
||||
const ptr_to_array: *const [2]i32 = &array;
|
||||
var it = reverseIterator(ptr_to_array);
|
||||
try testing.expectEqual(@as(?i32, 7), it.next());
|
||||
try testing.expectEqual(@as(?i32, 3), it.next());
|
||||
try testing.expectEqual(@as(?i32, null), it.next());
|
||||
}
|
||||
}
|
||||
|
||||
/// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user