Compare commits
3 commits
Author | SHA1 | Date | |
---|---|---|---|
9ec67b642e | |||
9a8268c8e2 | |||
f0f6c32267 |
4 changed files with 47 additions and 64 deletions
|
@ -28,7 +28,7 @@ _Zollections_ is a collections library for Zig. It's made to ease memory managem
|
|||
|
||||
## Versions
|
||||
|
||||
Zollections 0.1.0 is made and tested with zig 0.13.0.
|
||||
Zollections 0.1.1 is made and tested with zig 0.13.0.
|
||||
|
||||
## How to use
|
||||
|
||||
|
@ -37,7 +37,7 @@ Zollections 0.1.0 is made and tested with zig 0.13.0.
|
|||
In your project directory:
|
||||
|
||||
```shell
|
||||
$ zig fetch --save https://code.zeptotech.net/zedd/zollections/archive/v0.1.0.tar.gz
|
||||
$ zig fetch --save https://code.zeptotech.net/zedd/zollections/archive/v0.1.1.tar.gz
|
||||
```
|
||||
|
||||
In `build.zig`:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.{
|
||||
.name = "zollections",
|
||||
.version = "0.1.0",
|
||||
.version = "0.1.1",
|
||||
|
||||
.minimum_zig_version = "0.13.0",
|
||||
|
||||
|
@ -11,5 +11,7 @@
|
|||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"src",
|
||||
"README.md",
|
||||
"LICENSE",
|
||||
},
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ const std = @import("std");
|
|||
|
||||
/// Collection of pointers of a certain type.
|
||||
/// A collection manages memory of the contained type.
|
||||
pub fn Collection(comptime T: anytype) type
|
||||
{
|
||||
pub fn Collection(comptime T: anytype) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
|
@ -15,49 +14,38 @@ pub fn Collection(comptime T: anytype) type
|
|||
/// Initialize a new collection of values.
|
||||
/// Values are now owned by the collection and will free them when it is deinitialized.
|
||||
/// The allocator must be the one that manages the slice and its items.
|
||||
pub fn init(allocator: std.mem.Allocator, values: []*T) !*Self
|
||||
{
|
||||
const self = try allocator.create(Self);
|
||||
|
||||
self.* = .{
|
||||
pub fn init(allocator: std.mem.Allocator, values: []*T) Self {
|
||||
return .{
|
||||
.allocator = allocator,
|
||||
// Store given values in items slice.
|
||||
.items = values,
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Free any pointer value.
|
||||
fn freeAnyPointer(self: *Self, pointer: anytype) void
|
||||
{
|
||||
fn freeAnyPointer(self: *Self, pointer: anytype) void {
|
||||
// Get type info of the current pointer.
|
||||
const pointedTypeInfo = @typeInfo(@TypeOf(pointer.*));
|
||||
|
||||
switch (pointedTypeInfo)
|
||||
{
|
||||
.Struct, .Enum, .Union, .Opaque => {
|
||||
// If type is a container with a deinit, run deinit.
|
||||
if (@hasDecl(@TypeOf(pointer.*), "deinit"))
|
||||
{ // The container has a specific deinit, running it.
|
||||
pointer.deinit();
|
||||
//TODO implement something like that.
|
||||
//switch (@TypeOf(pointer.deinit).@"fn".return_type)
|
||||
//{
|
||||
// .ErrorUnion => {
|
||||
// try pointer.deinit();
|
||||
// },
|
||||
// else => {
|
||||
// pointer.deinit();
|
||||
// },
|
||||
//}
|
||||
}
|
||||
},
|
||||
.Pointer => {
|
||||
// It's a simple pointer, freeing its value recursively.
|
||||
self.freeAnyValue(pointer.*);
|
||||
},
|
||||
switch (pointedTypeInfo) {
|
||||
// It's a simple pointer, freeing its value recursively.
|
||||
.Pointer => self.freeAnyValue(pointer.*),
|
||||
else => {
|
||||
// If type is a container with a deinit, run deinit.
|
||||
if (std.meta.hasFn(@TypeOf(pointer.*), "deinit")) {
|
||||
// The container has a specific deinit, running it.
|
||||
pointer.deinit();
|
||||
//TODO implement something like that.
|
||||
//switch (@TypeOf(pointer.deinit).@"fn".return_type)
|
||||
//{
|
||||
// .ErrorUnion => {
|
||||
// try pointer.deinit();
|
||||
// },
|
||||
// else => {
|
||||
// pointer.deinit();
|
||||
// },
|
||||
//}
|
||||
}
|
||||
// Otherwise, we consider it as a simple value, there is nothing to free.
|
||||
},
|
||||
}
|
||||
|
@ -67,39 +55,35 @@ pub fn Collection(comptime T: anytype) type
|
|||
}
|
||||
|
||||
/// Free any value.
|
||||
fn freeAnyValue(self: *Self, value: anytype) void
|
||||
{
|
||||
fn freeAnyValue(self: *Self, value: anytype) void {
|
||||
// Get type info of the current pointer.
|
||||
const typeInfo = @typeInfo(@TypeOf(value));
|
||||
|
||||
switch (typeInfo)
|
||||
{
|
||||
switch (typeInfo) {
|
||||
.Pointer => |pointerInfo| {
|
||||
// Can be a slice or a simple pointer.
|
||||
if (pointerInfo.size == .One)
|
||||
{ // It's a simple pointer, freeing its value recursively.
|
||||
self.freeAnyPointer(value);
|
||||
if (pointerInfo.size == .One) {
|
||||
// It's a simple pointer, freeing its value recursively.
|
||||
self.freeAnyPointer(value);
|
||||
}
|
||||
else {
|
||||
// It's a slice, free every item then free it.
|
||||
for (value) |item| {
|
||||
// Free each item recursively.
|
||||
self.freeAnyValue(item);
|
||||
}
|
||||
else
|
||||
{ // It's a slice, free every item then free it.
|
||||
for (value) |item|
|
||||
{ // For each item, free it recursively.
|
||||
self.freeAnyValue(item);
|
||||
}
|
||||
|
||||
// Free the current pointer.
|
||||
self.allocator.free(value);
|
||||
}
|
||||
},
|
||||
else => {
|
||||
// Otherwise, we consider it as a simple value, nothing to free.
|
||||
// Free the current pointer.
|
||||
self.allocator.free(value);
|
||||
}
|
||||
},
|
||||
// Otherwise, we consider it as a simple value, nothing to free.
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
/// Deinitialize the collection of values and all its values.
|
||||
pub fn deinit(self: *Self) void
|
||||
{
|
||||
pub fn deinit(self: *Self) void {
|
||||
// Deinitialize all items.
|
||||
for (self.items) |item|
|
||||
{ // For each items, try to free it.
|
||||
|
@ -108,9 +92,6 @@ pub fn Collection(comptime T: anytype) type
|
|||
|
||||
// Free items slice.
|
||||
self.allocator.free(self.items);
|
||||
|
||||
// Destroy the current collection.
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ test "simple collection" {
|
|||
slice[2] = try allocator.create(u8);
|
||||
|
||||
// Create a collection with your slice of elements.
|
||||
const collection = try zollections.Collection(u8).init(allocator, slice);
|
||||
var collection = zollections.Collection(u8).init(allocator, slice);
|
||||
// Free your collection: your slice and all your elements will be freed.
|
||||
defer collection.deinit();
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ test "recursive free" {
|
|||
slice[0] = slicePointer;
|
||||
|
||||
// Create a collection with your slice of elements.
|
||||
const collection = try zollections.Collection([]*u8).init(allocator, slice);
|
||||
var collection = zollections.Collection([]*u8).init(allocator, slice);
|
||||
// Free your collection: your slice and all your slices and their elements will be freed.
|
||||
defer collection.deinit();
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ test "custom struct deinit" {
|
|||
slice[2].* = try ExampleStruct.init(16);
|
||||
|
||||
// Create a collection with your slice of elements.
|
||||
const collection = try zollections.Collection(ExampleStruct).init(allocator, slice);
|
||||
var collection = zollections.Collection(ExampleStruct).init(allocator, slice);
|
||||
// Free your collection: your slice and all your elements will be deinitialized and freed.
|
||||
defer collection.deinit();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue