aboutsummaryrefslogtreecommitdiff
path: root/lib/std/bounded_array.zig
diff options
context:
space:
mode:
authorMotiejus Jakštys <motiejus@jakstys.lt>2023-03-17 18:50:25 +0200
committerGitHub <noreply@github.com>2023-03-17 17:50:25 +0100
commite0dd20b02ea026e125b36b3674f20aa20ff043e3 (patch)
treee1536da7724b4822695028de04d02f9c296fb21b /lib/std/bounded_array.zig
parentcfcd6698cd9385938df27a2052c2309229171e4f (diff)
downloadzig-e0dd20b02ea026e125b36b3674f20aa20ff043e3.tar.gz
zig-e0dd20b02ea026e125b36b3674f20aa20ff043e3.zip
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
Diffstat (limited to 'lib/std/bounded_array.zig')
-rw-r--r--lib/std/bounded_array.zig45
1 files changed, 39 insertions, 6 deletions
diff --git a/lib/std/bounded_array.zig b/lib/std/bounded_array.zig
index 5242470631..8a4c2db64b 100644
--- a/lib/std/bounded_array.zig
+++ b/lib/std/bounded_array.zig
@@ -16,9 +16,30 @@ const testing = std.testing;
/// 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 {
+ 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 {
const Self = @This();
- buffer: [buffer_capacity]T = undefined,
+ buffer: [buffer_capacity]T align(alignment) = undefined,
len: usize = 0,
/// 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.
pub fn slice(self: anytype) switch (@TypeOf(&self.buffer)) {
- *[buffer_capacity]T => []T,
- *const [buffer_capacity]T => []const T,
+ *align(alignment) [buffer_capacity]T => []align(alignment) T,
+ *align(alignment) const [buffer_capacity]T => []align(alignment) const T,
else => unreachable,
} {
return self.buffer[0..self.len];
}
/// 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();
}
@@ -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.
/// 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;
try self.resize(self.len + 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.
/// Note that such an operation must be followed up with a
/// call to `resize()`
- pub fn unusedCapacitySlice(self: *Self) []T {
+ pub fn unusedCapacitySlice(self: *Self) []align(alignment) T {
return self.buffer[self.len..];
}
@@ -365,3 +386,15 @@ test "BoundedArray" {
try w.writeAll(s);
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]);
+}