Compare commits

...

2 Commits

Author SHA1 Message Date
kayomn d578bb422e Change Allocator to use interface style
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2022-10-24 13:59:37 +01:00
kayomn 989de70461 Fix closure types not working with void captures 2022-10-24 13:58:27 +01:00
3 changed files with 41 additions and 34 deletions

View File

@ -3,9 +3,9 @@ const stack = @import("./stack.zig");
const std = @import("std"); 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); ///
pub const Allocator = std.mem.Allocator;
/// ///
/// File-system agnostic abstraction for manipulating a file. /// File-system agnostic abstraction for manipulating a file.
@ -203,7 +203,7 @@ pub fn equals(comptime Element: type, this: []const Element, that: []const Eleme
return true; return true;
} }
test "Equivalence of bytes" { test "Memory buffers equal" {
const bytes_sequence = &.{69, 42, 0}; const bytes_sequence = &.{69, 42, 0};
const testing = std.testing; const testing = std.testing;
@ -255,11 +255,3 @@ test "Null writing" {
try testing.expectEqual(nullWriter().apply(sequence), sequence.len); try testing.expectEqual(nullWriter().apply(sequence), sequence.len);
} }
} }
///
/// Applies the singular `byte` to `writer`, returning `true` if it was successfully written,
/// otherwise `false`.
///
pub fn writeByte(writer: *Writer, byte: u8) bool {
return (writer.apply(std.mem.asBytes(&byte)) != 0);
}

View File

@ -48,20 +48,20 @@ pub fn BiFunction(comptime captures_size: usize, comptime A: type,
@compileError("`captures` must be smaller than or equal to " ++ @compileError("`captures` must be smaller than or equal to " ++
std.fmt.comptimePrint("{d}", .{captures_size}) ++ " bytes"); std.fmt.comptimePrint("{d}", .{captures_size}) ++ " bytes");
const captures_align = @alignOf(Captures);
var function = Self{ var function = Self{
.context = undefined, .context = undefined,
.applyErased = struct { .applyErased = struct {
fn do(erased: *anyopaque, a: A, b: B) Out { fn applyErased(erased: *anyopaque, a: A, b: B) Out {
return call(@ptrCast(*Captures, @alignCast( return call(if (Captures == void) {} else @ptrCast(*Captures,
captures_align, erased)).*, a, b); @alignCast(@alignOf(Captures), erased)).*, a, b);
} }
}.do, }.applyErased,
}; };
@ptrCast(*Captures, @alignCast(captures_align, &function.context)).* = captures; if (captures != {}) {
@ptrCast(*Captures, @alignCast(@alignOf(Captures), &function.context)).* = captures;
}
return function; return function;
} }
@ -108,11 +108,11 @@ pub fn Function(comptime captures_size: usize, comptime In: type, comptime Out:
.context = undefined, .context = undefined,
.applyErased = struct { .applyErased = struct {
fn do(erased: *anyopaque, input: In) Out { fn applyErased(erased: *anyopaque, input: In) Out {
return call(@ptrCast(*Captures, @alignCast( return call(if (Captures == void) {} else @ptrCast(*Captures,
captures_align, erased)).*, input); @alignCast(@alignOf(Captures), erased)).*, input);
} }
}.do, }.applyErased,
}; };
@ptrCast(*Captures, @alignCast(captures_align, &function.context)).* = captures; @ptrCast(*Captures, @alignCast(captures_align, &function.context)).* = captures;

View File

@ -1,4 +1,4 @@
const std = @import("std"); const io = @import("./io.zig");
/// ///
/// Returns a hash-backed table type of `Value`s indexed by `Key` and using `key_context` as the key /// Returns a hash-backed table type of `Value`s indexed by `Key` and using `key_context` as the key
@ -7,7 +7,7 @@ const std = @import("std");
pub fn Hashed(comptime Key: type, comptime Value: type, pub fn Hashed(comptime Key: type, comptime Value: type,
comptime key_context: KeyContext(Key)) type { comptime key_context: KeyContext(Key)) type {
const Allocator = std.mem.Allocator; const Allocator = io.Allocator;
return struct { return struct {
allocator: Allocator, allocator: Allocator,
@ -44,11 +44,13 @@ pub fn Hashed(comptime Key: type, comptime Value: type,
/// ///
/// Initializes a [Self] using `allocator` as the memory allocation strategy. /// Initializes a [Self] using `allocator` as the memory allocation strategy.
/// ///
/// Returns a new [Self] value or an [Allocator.Error] if initializing failed. /// Returns a new [Self] value or an [io.Allocator.Error] if initializing failed.
/// ///
pub fn init(allocator: Allocator) Allocator.Error!Self { pub fn init(allocator: Allocator) Allocator.Error!Self {
const initial_capacity = 4;
return Self{ return Self{
.buckets = try allocator.alloc(Bucket, 4), .buckets = try allocator.alloc(Bucket, initial_capacity),
.filled = 0, .filled = 0,
.allocator = allocator, .allocator = allocator,
.load_limit = 0.75, .load_limit = 0.75,
@ -158,7 +160,7 @@ pub fn Hashed(comptime Key: type, comptime Value: type,
/// [InsertError.KeyExists] occurs when an insertion was attempted on a table with a matching key /// [InsertError.KeyExists] occurs when an insertion was attempted on a table with a matching key
/// already present. /// already present.
/// ///
pub const InsertError = std.mem.Allocator.Error || error { pub const InsertError = io.Allocator.Error || error {
KeyExists, KeyExists,
}; };
@ -173,14 +175,27 @@ pub fn KeyContext(comptime Key: type) type {
}; };
} }
test "Hashed table manipulation with bytes context" { ///
const testing = std.testing; /// A [KeyContext] for dealing with string literal (i.e. []const u8) values.
const io = @import("./io.zig"); ///
/// **Note** that, while lightweight, this context should only be considered safe to use with string
/// literals or variables pointing to string literals - as the [KeyContext] does not take ownership
/// of its keys beyond copying the reference.
///
pub const string_literal_context = KeyContext([]const u8){
.hash = io.hashBytes,
var table = try Hashed([]const u8, u32, .{ .equals = struct {
.equals = io.equalsBytes, fn stringsEqual(this: []const u8, that: []const u8) bool {
.hash = io.hashBytes, return io.equals(u8, this, that);
}).init(testing.allocator); }
}.stringsEqual,
};
test "Hash table manipulation with string literal context" {
const testing = @import("std").testing;
var table = try Hashed([]const u8, u32, string_literal_context).init(testing.allocator);
defer table.deinit(); defer table.deinit();