zig/src/TypedValue.zig
2021-11-30 23:32:47 +00:00

45 lines
1.3 KiB
Zig

const std = @import("std");
const Type = @import("type.zig").Type;
const Value = @import("value.zig").Value;
const Allocator = std.mem.Allocator;
const TypedValue = @This();
ty: Type,
val: Value,
/// Memory management for TypedValue. The main purpose of this type
/// is to be small and have a deinit() function to free associated resources.
pub const Managed = struct {
/// If the tag value is less than Tag.no_payload_count, then no pointer
/// dereference is needed.
typed_value: TypedValue,
/// If this is `null` then there is no memory management needed.
arena: ?*std.heap.ArenaAllocator.State = null,
pub fn deinit(self: *Managed, allocator: Allocator) void {
if (self.arena) |a| a.promote(allocator).deinit();
self.* = undefined;
}
};
/// Assumes arena allocation. Does a recursive copy.
pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {
return TypedValue{
.ty = try self.ty.copy(arena),
.val = try self.val.copy(arena),
};
}
pub fn eql(a: TypedValue, b: TypedValue) bool {
if (!a.ty.eql(b.ty)) return false;
return a.val.eql(b.val, a.ty);
}
pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash) void {
return tv.val.hash(tv.ty, hasher);
}
pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {
return tv.val.enumToInt(tv.ty, buffer);
}