Add additional closures and uses
This commit is contained in:
		
							parent
							
								
									f5fd24fb76
								
							
						
					
					
						commit
						da7d9cfcc0
					
				| @ -2,6 +2,11 @@ const meta = @import("./meta.zig"); | ||||
| const stack = @import("./stack.zig"); | ||||
| const std = @import("std"); | ||||
| 
 | ||||
| /// | ||||
| /// Closure for allocating, reallocating, and deallocating dynamic memory resources through itself. | ||||
| /// | ||||
| pub const Allocator = meta.BiFunction(56, ?[]u8, usize, AllocationError![]u8); | ||||
| 
 | ||||
| /// | ||||
| /// File-system agnostic abstraction for manipulating a file. | ||||
| /// | ||||
| @ -186,16 +191,24 @@ pub const Writer = meta.Function(@sizeOf(usize), []const u8, usize); | ||||
| /// Returns `true` if `this` is the same length and contains the same data as `that`, otherwise | ||||
| /// `false`. | ||||
| /// | ||||
| pub fn equalsBytes(this: []const u8, that: []const u8) bool { | ||||
|     return std.mem.eql(u8, this, that); | ||||
| pub fn equals(comptime Element: type, this: []const Element, that: []const Element) bool { | ||||
|     if (this.len != that.len) return false; | ||||
| 
 | ||||
|     { | ||||
|         var i = std.mem.zeroes(usize); | ||||
| 
 | ||||
|         while (i < this.len) : (i += 1) if (this[i] != that[i]) return false; | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| test "Equivalence of bytes" { | ||||
|     const bytes_sequence = &.{69, 42, 0}; | ||||
|     const testing = std.testing; | ||||
| 
 | ||||
|     try testing.expect(equalsBytes(bytes_sequence, bytes_sequence)); | ||||
|     try testing.expect(!equalsBytes(bytes_sequence, &.{69, 42})); | ||||
|     try testing.expect(equals(u8, bytes_sequence, bytes_sequence)); | ||||
|     try testing.expect(!equals(u8, bytes_sequence, &.{69, 42})); | ||||
| } | ||||
| 
 | ||||
| /// | ||||
|  | ||||
| @ -11,6 +11,63 @@ pub fn FnReturn(comptime Fn: type) type { | ||||
|     return type_info.Fn.return_type orelse void; | ||||
| } | ||||
| 
 | ||||
| /// | ||||
| /// Returns a double-input single-output closure type where `A` represents the first input type, `B` | ||||
| /// represents the second, and `Out` represents the output type, and `captures_size` represents the | ||||
| /// size of the closure context. | ||||
| /// | ||||
| pub fn BiFunction(comptime captures_size: usize, comptime A: type, | ||||
|     comptime B: type, comptime Out: type) type { | ||||
| 
 | ||||
|     return struct { | ||||
|         applyErased: fn (*anyopaque, A, B) Out, | ||||
|         context: [captures_size]u8, | ||||
| 
 | ||||
|         /// | ||||
|         /// Function type. | ||||
|         /// | ||||
|         const Self = @This(); | ||||
| 
 | ||||
|         /// | ||||
|         /// Applies `a` and `b` to `self`, producing a result according to the current context data. | ||||
|         /// | ||||
|         pub fn apply(self: *Self, a: A, b: B) Out { | ||||
|             return self.applyErased(&self.context, a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// | ||||
|         /// Creates a new [Self] by capturing the `captures` value as the context and `call` as the | ||||
|         /// as the behavior executed when [apply] or [applyErased] is called. | ||||
|         /// | ||||
|         /// The newly created [Self] is returned. | ||||
|         /// | ||||
|         pub fn capture(captures: anytype, comptime call: fn (@TypeOf(captures), A, B) Out) Self { | ||||
|             const Captures = @TypeOf(captures); | ||||
| 
 | ||||
|             if (@sizeOf(Captures) > captures_size) | ||||
|                 @compileError("`captures` must be smaller than or equal to " ++ | ||||
|                     std.fmt.comptimePrint("{d}", .{captures_size}) ++ " bytes"); | ||||
| 
 | ||||
|             const captures_align = @alignOf(Captures); | ||||
| 
 | ||||
|             var function = Self{ | ||||
|                 .context = undefined, | ||||
| 
 | ||||
|                 .applyErased = struct { | ||||
|                     fn do(erased: *anyopaque, a: A, b: B) Out { | ||||
|                         return call(@ptrCast(*Captures, @alignCast( | ||||
|                             captures_align, erased)).*, a, b); | ||||
|                     } | ||||
|                 }.do, | ||||
|             }; | ||||
| 
 | ||||
|             @ptrCast(*Captures, @alignCast(captures_align, &function.context)).* = captures; | ||||
| 
 | ||||
|             return function; | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| /// | ||||
| /// Returns a single-input single-output closure type where `In` represents the input type, `Out` | ||||
| /// represents the output type, and `captures_size` represents the size of the closure context. | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user