Simplify deinit existence check and improve code format.
This commit is contained in:
parent
f0f6c32267
commit
9a8268c8e2
1 changed files with 38 additions and 50 deletions
|
@ -2,8 +2,7 @@ const std = @import("std");
|
||||||
|
|
||||||
/// Collection of pointers of a certain type.
|
/// Collection of pointers of a certain type.
|
||||||
/// A collection manages memory of the contained 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 {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
|
@ -15,8 +14,7 @@ pub fn Collection(comptime T: anytype) type
|
||||||
/// Initialize a new collection of values.
|
/// Initialize a new collection of values.
|
||||||
/// Values are now owned by the collection and will free them when it is deinitialized.
|
/// 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.
|
/// The allocator must be the one that manages the slice and its items.
|
||||||
pub fn init(allocator: std.mem.Allocator, values: []*T) Self
|
pub fn init(allocator: std.mem.Allocator, values: []*T) Self {
|
||||||
{
|
|
||||||
return .{
|
return .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
// Store given values in items slice.
|
// Store given values in items slice.
|
||||||
|
@ -25,17 +23,17 @@ pub fn Collection(comptime T: anytype) type
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Free any pointer value.
|
/// 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.
|
// Get type info of the current pointer.
|
||||||
const pointedTypeInfo = @typeInfo(@TypeOf(pointer.*));
|
const pointedTypeInfo = @typeInfo(@TypeOf(pointer.*));
|
||||||
|
|
||||||
switch (pointedTypeInfo)
|
switch (pointedTypeInfo) {
|
||||||
{
|
// It's a simple pointer, freeing its value recursively.
|
||||||
.Struct, .Enum, .Union, .Opaque => {
|
.Pointer => self.freeAnyValue(pointer.*),
|
||||||
|
else => {
|
||||||
// If type is a container with a deinit, run deinit.
|
// If type is a container with a deinit, run deinit.
|
||||||
if (@hasDecl(@TypeOf(pointer.*), "deinit"))
|
if (std.meta.hasFn(@TypeOf(pointer.*), "deinit")) {
|
||||||
{ // The container has a specific deinit, running it.
|
// The container has a specific deinit, running it.
|
||||||
pointer.deinit();
|
pointer.deinit();
|
||||||
//TODO implement something like that.
|
//TODO implement something like that.
|
||||||
//switch (@TypeOf(pointer.deinit).@"fn".return_type)
|
//switch (@TypeOf(pointer.deinit).@"fn".return_type)
|
||||||
|
@ -48,12 +46,6 @@ pub fn Collection(comptime T: anytype) type
|
||||||
// },
|
// },
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
.Pointer => {
|
|
||||||
// It's a simple pointer, freeing its value recursively.
|
|
||||||
self.freeAnyValue(pointer.*);
|
|
||||||
},
|
|
||||||
else => {
|
|
||||||
// Otherwise, we consider it as a simple value, there is nothing to free.
|
// Otherwise, we consider it as a simple value, there is nothing to free.
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -63,23 +55,21 @@ pub fn Collection(comptime T: anytype) type
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Free any value.
|
/// Free any value.
|
||||||
fn freeAnyValue(self: *Self, value: anytype) void
|
fn freeAnyValue(self: *Self, value: anytype) void {
|
||||||
{
|
|
||||||
// Get type info of the current pointer.
|
// Get type info of the current pointer.
|
||||||
const typeInfo = @typeInfo(@TypeOf(value));
|
const typeInfo = @typeInfo(@TypeOf(value));
|
||||||
|
|
||||||
switch (typeInfo)
|
switch (typeInfo) {
|
||||||
{
|
|
||||||
.Pointer => |pointerInfo| {
|
.Pointer => |pointerInfo| {
|
||||||
// Can be a slice or a simple pointer.
|
// Can be a slice or a simple pointer.
|
||||||
if (pointerInfo.size == .One)
|
if (pointerInfo.size == .One) {
|
||||||
{ // It's a simple pointer, freeing its value recursively.
|
// It's a simple pointer, freeing its value recursively.
|
||||||
self.freeAnyPointer(value);
|
self.freeAnyPointer(value);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{ // It's a slice, free every item then free it.
|
// It's a slice, free every item then free it.
|
||||||
for (value) |item|
|
for (value) |item| {
|
||||||
{ // For each item, free it recursively.
|
// Free each item recursively.
|
||||||
self.freeAnyValue(item);
|
self.freeAnyValue(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,15 +77,13 @@ pub fn Collection(comptime T: anytype) type
|
||||||
self.allocator.free(value);
|
self.allocator.free(value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
else => {
|
|
||||||
// Otherwise, we consider it as a simple value, nothing to free.
|
// Otherwise, we consider it as a simple value, nothing to free.
|
||||||
},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deinitialize the collection of values and all its values.
|
/// Deinitialize the collection of values and all its values.
|
||||||
pub fn deinit(self: *Self) void
|
pub fn deinit(self: *Self) void {
|
||||||
{
|
|
||||||
// Deinitialize all items.
|
// Deinitialize all items.
|
||||||
for (self.items) |item|
|
for (self.items) |item|
|
||||||
{ // For each items, try to free it.
|
{ // For each items, try to free it.
|
||||||
|
|
Loading…
Reference in a new issue