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…
	
	Add table
		
		Reference in a new issue