(zig) extended vector.rs

This commit is contained in:
scbj
2025-10-06 17:42:53 +02:00
committed by zegonix
parent 42f5119f42
commit 5900789ce4
+79 -19
View File
@@ -1,11 +1,15 @@
const std = @import("std");
/// return empty instance of `Vector`
/// use `new()` or `new_with_capacity()` to
/// get an initialised instance of `Vector`
pub fn vector(comptime T: type) type
{
return struct
{
const Self: type = @This();
const Vector: type = @This();
const VectorType: type = T;
const DEFAULT_SIZE: usize = 16;
const VectorError: type = error {
OutOfBounds,
@@ -16,52 +20,73 @@ pub fn vector(comptime T: type) type
array: []VectorType,
length: usize,
pub fn new(allocator: std.mem.Allocator) !Self
/// create new vector with the default capacity
///
/// returns initialised instance of `Vector`
pub fn new(allocator: std.mem.Allocator) !Vector
{
const DEFAULT_SIZE: usize = 16;
return Self
return Vector
{
.allocator = allocator,
.array = try allocator.alloc(VectorType, DEFAULT_SIZE),
.array = allocator.alloc(VectorType, DEFAULT_SIZE) catch return VectorError.FailedToAllocateMemory,
.length = 0,
};
}
pub fn new_with_capacity(allocator: std.mem.Allocator, capacity: usize) !Self
/// create new vector with the given capacity
///
/// returns initialised instance of `Vector`
pub fn new_with_capacity(allocator: std.mem.Allocator, size: usize) VectorError!Vector
{
return Self
return Vector
{
.allocator = allocator,
.array = try allocator.alloc(VectorType, capacity),
.array = allocator.alloc(VectorType, size) catch return VectorError.FailedToAllocateMemory,
.length = 0,
};
}
pub fn len(self: *Self) usize
/// get the vectors length
///
/// **note:** length != capacity
/// length = number of items in the vector
/// capacity = maximum number of items the vector can hold
pub fn len(self: *Vector) usize
{
return self.length;
}
pub fn push(self: *Self, item: VectorType) !void
/// get the vectors capacity
///
/// **note:** length != capacity
/// length = number of items in the vector
/// capacity = maximum number of items the vector can hold
pub fn capacity(self: *Vector) usize
{
if (self.length >= self.array.len)
{
const new_buffer: []VectorType = try self.allocator.alloc(VectorType, 2 * self.array.len);
@memcpy(new_buffer, self.array);
self.allocator.free(self.array);
self.array = new_buffer;
return self.array.len;
}
/// add one item at the end of the vector
pub fn push(self: *Vector, item: VectorType) VectorError!void
{
if (self.length >= self.array.len) try self.double_capacity();
self.array[self.length] = item;
self.length += 1;
}
pub fn pop(self: *Self) VectorType
/// remove and return last item of the vector
pub fn pop(self: *Vector) VectorType
{
self.length -= 1;
return self.array[self.length];
}
pub fn drain(self: *Self, range: [2]usize) VectorError![]VectorType
/// remove and return a range of elements
///
/// range[0] has to be less than range[1]
/// the range bounds are **both** included
pub fn drain(self: *Vector, range: [2]usize) VectorError![]VectorType
{
if (2 != range.len
or range[1] <= range[0]
@@ -80,11 +105,46 @@ pub fn vector(comptime T: type) type
// TODO: return array instead of pointer
@memcpy(slice.ptr, self.array[range[0]..range[1] + 1]);
@memmove(self.array.ptr + range[0], self.array[range[1]..self.length]);
@memmove(self.array.ptr + range[0], self.array[range[1] + 1..self.length]);
self.length -= slice_length;
return slice;
}
/// add slice of `VectorType` to the end of the vector
pub fn extend(self: *Vector, slice: []VectorType) VectorError!void
{
if (slice.len == 0) return;
if (slice.len > self.capacity()) {
try self.increase_capacity(slice.len + self.capacity());
}
else if (slice.len > self.capacity() - self.length)
{
try self.double_capacity();
}
@memcpy(self.array.ptr + self.length, slice);
}
/// double the vectors capacity
fn double_capacity(self: *Vector) VectorError!void
{
try self.increase_capacity(2 * self.capacity());
}
/// increase the vectors capacity to given size
fn increase_capacity(self: *Vector, size: usize) VectorError!void
{
const new_buffer: []VectorType = self.allocator.alloc(VectorType, size)
catch
{
return VectorError.FailedToAllocateMemory;
};
@memcpy(new_buffer, self.array);
self.allocator.free(self.array);
self.array = new_buffer;
}
};
}