mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 16:45:27 +00:00
add BoundedArrayAligned (#14580)
This is useful for creating byte buffers of actually-different-things. Copied the argument order from `Allocator.alignedAlloc` I noted that `ArrayListAligned` is going out of it's way to not set the alignment at comptime when it is not specified. However, I was not able to do that the same way here, and good people on IRC, @ifreund in particular (thanks!) assured me that [N]T align(@alignOf(T)) is equivalent to [N]T
This commit is contained in:
parent
cfcd6698cd
commit
e0dd20b02e
@ -16,9 +16,30 @@ const testing = std.testing;
|
|||||||
/// var a_clone = a; // creates a copy - the structure doesn't use any internal pointers
|
/// var a_clone = a; // creates a copy - the structure doesn't use any internal pointers
|
||||||
/// ```
|
/// ```
|
||||||
pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
|
pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
|
||||||
|
return BoundedArrayAligned(T, @alignOf(T), buffer_capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A structure with an array, length and alignment, that can be used as a
|
||||||
|
/// slice.
|
||||||
|
///
|
||||||
|
/// Useful to pass around small explicitly-aligned arrays whose exact size is
|
||||||
|
/// only known at runtime, but whose maximum size is known at comptime, without
|
||||||
|
/// requiring an `Allocator`.
|
||||||
|
/// ```zig
|
||||||
|
// var a = try BoundedArrayAligned(u8, 16, 2).init(0);
|
||||||
|
// try a.append(255);
|
||||||
|
// try a.append(255);
|
||||||
|
// const b = @ptrCast(*const [1]u16, a.constSlice().ptr);
|
||||||
|
// try testing.expectEqual(@as(u16, 65535), b[0]);
|
||||||
|
/// ```
|
||||||
|
pub fn BoundedArrayAligned(
|
||||||
|
comptime T: type,
|
||||||
|
comptime alignment: u29,
|
||||||
|
comptime buffer_capacity: usize,
|
||||||
|
) type {
|
||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
buffer: [buffer_capacity]T = undefined,
|
buffer: [buffer_capacity]T align(alignment) = undefined,
|
||||||
len: usize = 0,
|
len: usize = 0,
|
||||||
|
|
||||||
/// Set the actual length of the slice.
|
/// Set the actual length of the slice.
|
||||||
@ -30,15 +51,15 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
|
|||||||
|
|
||||||
/// View the internal array as a slice whose size was previously set.
|
/// View the internal array as a slice whose size was previously set.
|
||||||
pub fn slice(self: anytype) switch (@TypeOf(&self.buffer)) {
|
pub fn slice(self: anytype) switch (@TypeOf(&self.buffer)) {
|
||||||
*[buffer_capacity]T => []T,
|
*align(alignment) [buffer_capacity]T => []align(alignment) T,
|
||||||
*const [buffer_capacity]T => []const T,
|
*align(alignment) const [buffer_capacity]T => []align(alignment) const T,
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
} {
|
} {
|
||||||
return self.buffer[0..self.len];
|
return self.buffer[0..self.len];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// View the internal array as a constant slice whose size was previously set.
|
/// View the internal array as a constant slice whose size was previously set.
|
||||||
pub fn constSlice(self: *const Self) []const T {
|
pub fn constSlice(self: *const Self) []align(alignment) const T {
|
||||||
return self.slice();
|
return self.slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +115,7 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
|
|||||||
|
|
||||||
/// Resize the slice, adding `n` new elements, which have `undefined` values.
|
/// Resize the slice, adding `n` new elements, which have `undefined` values.
|
||||||
/// The return value is a slice pointing to the uninitialized elements.
|
/// The return value is a slice pointing to the uninitialized elements.
|
||||||
pub fn addManyAsArray(self: *Self, comptime n: usize) error{Overflow}!*[n]T {
|
pub fn addManyAsArray(self: *Self, comptime n: usize) error{Overflow}!*align(alignment) [n]T {
|
||||||
const prev_len = self.len;
|
const prev_len = self.len;
|
||||||
try self.resize(self.len + n);
|
try self.resize(self.len + n);
|
||||||
return self.slice()[prev_len..][0..n];
|
return self.slice()[prev_len..][0..n];
|
||||||
@ -118,7 +139,7 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
|
|||||||
/// This can be useful for writing directly into it.
|
/// This can be useful for writing directly into it.
|
||||||
/// Note that such an operation must be followed up with a
|
/// Note that such an operation must be followed up with a
|
||||||
/// call to `resize()`
|
/// call to `resize()`
|
||||||
pub fn unusedCapacitySlice(self: *Self) []T {
|
pub fn unusedCapacitySlice(self: *Self) []align(alignment) T {
|
||||||
return self.buffer[self.len..];
|
return self.buffer[self.len..];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,3 +386,15 @@ test "BoundedArray" {
|
|||||||
try w.writeAll(s);
|
try w.writeAll(s);
|
||||||
try testing.expectEqualStrings(s, a.constSlice());
|
try testing.expectEqualStrings(s, a.constSlice());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "BoundedArrayAligned" {
|
||||||
|
var a = try BoundedArrayAligned(u8, 16, 4).init(0);
|
||||||
|
try a.append(0);
|
||||||
|
try a.append(0);
|
||||||
|
try a.append(255);
|
||||||
|
try a.append(255);
|
||||||
|
|
||||||
|
const b = @ptrCast(*const [2]u16, a.constSlice().ptr);
|
||||||
|
try testing.expectEqual(@as(u16, 0), b[0]);
|
||||||
|
try testing.expectEqual(@as(u16, 65535), b[1]);
|
||||||
|
}
|
||||||
|
@ -9,6 +9,7 @@ pub const AutoArrayHashMapUnmanaged = array_hash_map.AutoArrayHashMapUnmanaged;
|
|||||||
pub const AutoHashMap = hash_map.AutoHashMap;
|
pub const AutoHashMap = hash_map.AutoHashMap;
|
||||||
pub const AutoHashMapUnmanaged = hash_map.AutoHashMapUnmanaged;
|
pub const AutoHashMapUnmanaged = hash_map.AutoHashMapUnmanaged;
|
||||||
pub const BoundedArray = @import("bounded_array.zig").BoundedArray;
|
pub const BoundedArray = @import("bounded_array.zig").BoundedArray;
|
||||||
|
pub const BoundedArrayAligned = @import("bounded_array.zig").BoundedArrayAligned;
|
||||||
pub const Build = @import("Build.zig");
|
pub const Build = @import("Build.zig");
|
||||||
pub const BufMap = @import("buf_map.zig").BufMap;
|
pub const BufMap = @import("buf_map.zig").BufMap;
|
||||||
pub const BufSet = @import("buf_set.zig").BufSet;
|
pub const BufSet = @import("buf_set.zig").BufSet;
|
||||||
|
Loading…
Reference in New Issue
Block a user