(zig) extended vector.rs
This commit is contained in:
+79
-19
@@ -1,11 +1,15 @@
|
|||||||
const std = @import("std");
|
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
|
pub fn vector(comptime T: type) type
|
||||||
{
|
{
|
||||||
return struct
|
return struct
|
||||||
{
|
{
|
||||||
const Self: type = @This();
|
const Vector: type = @This();
|
||||||
const VectorType: type = T;
|
const VectorType: type = T;
|
||||||
|
const DEFAULT_SIZE: usize = 16;
|
||||||
|
|
||||||
const VectorError: type = error {
|
const VectorError: type = error {
|
||||||
OutOfBounds,
|
OutOfBounds,
|
||||||
@@ -16,52 +20,73 @@ pub fn vector(comptime T: type) type
|
|||||||
array: []VectorType,
|
array: []VectorType,
|
||||||
length: usize,
|
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 Vector
|
||||||
return Self
|
|
||||||
{
|
{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.array = try allocator.alloc(VectorType, DEFAULT_SIZE),
|
.array = allocator.alloc(VectorType, DEFAULT_SIZE) catch return VectorError.FailedToAllocateMemory,
|
||||||
.length = 0,
|
.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,
|
.allocator = allocator,
|
||||||
.array = try allocator.alloc(VectorType, capacity),
|
.array = allocator.alloc(VectorType, size) catch return VectorError.FailedToAllocateMemory,
|
||||||
.length = 0,
|
.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;
|
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)
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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.array[self.length] = item;
|
||||||
self.length += 1;
|
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;
|
self.length -= 1;
|
||||||
return self.array[self.length];
|
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
|
if (2 != range.len
|
||||||
or range[1] <= range[0]
|
or range[1] <= range[0]
|
||||||
@@ -80,11 +105,46 @@ pub fn vector(comptime T: type) type
|
|||||||
|
|
||||||
// TODO: return array instead of pointer
|
// TODO: return array instead of pointer
|
||||||
@memcpy(slice.ptr, self.array[range[0]..range[1] + 1]);
|
@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;
|
self.length -= slice_length;
|
||||||
|
|
||||||
return slice;
|
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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user