Make Function closures only accept a pointer context
This commit is contained in:
		
							parent
							
								
									d49608f7bb
								
							
						
					
					
						commit
						eb4a758251
					
				| @ -69,7 +69,7 @@ pub const Allocator = union (enum) { | |||||||
| /// Closure that captures a reference to readable resources like block devices, memory buffers, | /// Closure that captures a reference to readable resources like block devices, memory buffers, | ||||||
| /// network sockets, and more. | /// network sockets, and more. | ||||||
| /// | /// | ||||||
| pub const Reader = meta.Function(@sizeOf(usize), []u8, usize); | pub const Reader = meta.Function([]u8, usize); | ||||||
| 
 | 
 | ||||||
| /// | /// | ||||||
| /// Returns a state machine for lazily computing all `Element` components of a given source input | /// Returns a state machine for lazily computing all `Element` components of a given source input | ||||||
| @ -187,7 +187,7 @@ test "Spliterator of string literals" { | |||||||
| /// Closure that captures a reference to writable resources like block devices, memory buffers, | /// Closure that captures a reference to writable resources like block devices, memory buffers, | ||||||
| /// network sockets, and more. | /// network sockets, and more. | ||||||
| /// | /// | ||||||
| pub const Writer = meta.Function(@sizeOf(usize), []const u8, usize); | pub const Writer = meta.Function([]const u8, usize); | ||||||
| 
 | 
 | ||||||
| /// | /// | ||||||
| /// Returns a sliced reference of the raw bytes in `pointer`. | /// Returns a sliced reference of the raw bytes in `pointer`. | ||||||
| @ -383,8 +383,10 @@ test "Data swapping" { | |||||||
| /// sent somewhere for whatever reason. | /// sent somewhere for whatever reason. | ||||||
| /// | /// | ||||||
| pub fn nullWriter() Writer { | pub fn nullWriter() Writer { | ||||||
|     return Writer.capture(@as(usize, 0), struct { |     var dummy: usize = 0; | ||||||
|         fn write(_: usize, buffer: []const u8) usize { | 
 | ||||||
|  |     return Writer.capture(&dummy, struct { | ||||||
|  |         fn write(_: *usize, buffer: []const u8) usize { | ||||||
|             return buffer.len; |             return buffer.len; | ||||||
|         } |         } | ||||||
|     }.write); |     }.write); | ||||||
|  | |||||||
| @ -13,10 +13,10 @@ pub fn FnReturn(comptime Fn: type) type { | |||||||
| /// Returns a single-input single-output closure type where `In` represents the input type, `Out` | /// 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. | /// represents the output type, and `captures_size` represents the size of the closure context. | ||||||
| /// | /// | ||||||
| pub fn Function(comptime captures_size: usize, comptime In: type, comptime Out: type) type { | pub fn Function(comptime In: type, comptime Out: type) type { | ||||||
|     return struct { |     return struct { | ||||||
|         callErased: fn (*anyopaque, In) Out, |         callErased: fn (*anyopaque, In) Out, | ||||||
|         context: [captures_size]u8, |         context: *anyopaque, | ||||||
| 
 | 
 | ||||||
|         /// |         /// | ||||||
|         /// Function type. |         /// Function type. | ||||||
| @ -27,37 +27,36 @@ pub fn Function(comptime captures_size: usize, comptime In: type, comptime Out: | |||||||
|         /// Invokes `self` with `input`, producing a result according to the current context data. |         /// Invokes `self` with `input`, producing a result according to the current context data. | ||||||
|         /// |         /// | ||||||
|         pub fn call(self: *Self, input: In) Out { |         pub fn call(self: *Self, input: In) Out { | ||||||
|             return self.callErased(&self.context, input); |             return self.callErased(self.context, input); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /// |         /// | ||||||
|         /// Creates a new [Self] by capturing the `captures` value as the context and `invoke` as |         /// Creates a new [Self] by capturing the `context` value as the capture context and | ||||||
|         /// the as the behavior executed when [call] or [callErased] is called. |         /// `invoke` as the behavior executed when [call] or [callErased] is called. | ||||||
|         /// |         /// | ||||||
|         /// The newly created [Self] is returned. |         /// The newly created [Self] is returned. | ||||||
|         /// |         /// | ||||||
|         pub fn capture(captures: anytype, comptime invoke: fn (@TypeOf(captures), In) Out) Self { |         pub fn capture(context: anytype, comptime invoke: fn (@TypeOf(context), In) Out) Self { | ||||||
|             const Captures = @TypeOf(captures); |             const Context = @TypeOf(context); | ||||||
| 
 | 
 | ||||||
|             if (@sizeOf(Captures) > captures_size) |             switch (@typeInfo(Context)) { | ||||||
|                 @compileError("`captures` exceeds the size limit of the capture context"); |                 .Pointer => |info| if (info.size == .Slice) | ||||||
|  |                     @compileError("`context` cannot be a slice"), | ||||||
| 
 | 
 | ||||||
|             const captures_align = @alignOf(Captures); |                 else => @compileError("`context` must be a pointer"), | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             var function = Self{ |             var function = Self{ | ||||||
|                 .context = undefined, |                 .context = @ptrCast(*anyopaque, context), | ||||||
| 
 | 
 | ||||||
|                 .callErased = struct { |                 .callErased = struct { | ||||||
|                     fn callErased(erased: *anyopaque, input: In) Out { |                     fn callErased(erased: *anyopaque, input: In) Out { | ||||||
|                         return invoke(if (Captures == void) {} else @ptrCast(*Captures, |                         return invoke(@ptrCast(*Context, @alignCast( | ||||||
|                             @alignCast(@alignOf(Captures), erased)).*, input); |                             @alignOf(Context), erased)).*, input); | ||||||
|                     } |                     } | ||||||
|                 }.callErased, |                 }.callErased, | ||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|             if (Captures != void) |  | ||||||
|                 @ptrCast(*Captures, @alignCast(captures_align, &function.context)).* = captures; |  | ||||||
| 
 |  | ||||||
|             return function; |             return function; | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user