Skip to content

Instantly share code, notes, and snippets.

@andrewrk
Created January 31, 2022 02:04
Show Gist options
  • Save andrewrk/4737124161d8bafd8c9bba6a341656c0 to your computer and use it in GitHub Desktop.
Save andrewrk/4737124161d8bafd8c9bba6a341656c0 to your computer and use it in GitHub Desktop.
use case for ArrayHashMap(void, void)
map: std.AutoHashMapUnmanaged(void, void),
items: std.MultiArrayList(Item),
extra: std.ArrayListUnmanaged(u32),
strings: std.ArrayListUnmanaged(u8),
const InternArena = @This();
const std = @import("std");
const Allocator = std.mem.Allocator;
const KeyAdapter = struct {
intern_arena: *const InternArena,
pub fn eql(ctx: @This(), a: Key, map_index: u32) bool {
return ctx.intern_arena.indexToKey(map_index).eql(a);
}
pub fn hash(ctx: @This(), a: Key) u32 {
_ = ctx;
return a.hash();
}
};
pub const Key = union(enum) {
int_type: struct {
signedness: std.builtin.Signedness,
bits: u16,
},
ptr_type: struct {
elem_type: Index,
sentinel: Index,
alignment: u16,
size: std.builtin.TypeInfo.Pointer.Size,
is_const: bool,
is_volatile: bool,
is_allowzero: bool,
address_space: std.builtin.AddressSpace,
},
array_type: struct {
len: u64,
child: Index,
sentinel: Index,
},
vector_type: struct {
len: u32,
child: Index,
},
optional_type: struct {
payload_type: Index,
},
error_union_type: struct {
error_set_type: Index,
payload_type: Index,
},
simple: Simple,
};
pub const Item = struct {
tag: Tag,
/// The doc comments on the respective Tag explain how to interpret this.
data: u32,
};
/// Represents an index into `map`. It represents the canonical index
/// of a `Value` within this `InternArena`. The values are typed.
/// Two values which have the same type can be equality compared simply
/// by checking if their indexes are equal, provided they are both in
/// the same `InternArena`.
pub const Index = u32;
pub const Tag = enum(u8) {
/// An integer type.
/// data is number of bits
type_int_signed,
/// An integer type.
/// data is number of bits
type_int_unsigned,
/// A type or value that can be represented with only an enum tag.
/// data is Simple enum value
simple,
/// An unsigned integer value that can be represented by u32.
/// data is integer value
int_u32,
/// An unsigned integer value that can be represented by i32.
/// data is integer value bitcasted to u32.
int_i32,
/// A positive integer value that does not fit in 32 bits.
/// data is a extra index to BigInt.
int_big_positive,
/// A negative integer value that does not fit in 32 bits.
/// data is a extra index to BigInt.
int_big_negative,
/// A float value that can be represented by f32.
/// data is float value bitcasted to u32.
float_f32,
/// A float value that can be represented by f64.
/// data is payload index to Float64.
float_f64,
/// A float value that can be represented by f128.
/// data is payload index to Float128.
float_f128,
};
pub const Simple = enum(u32) {
f16,
f32,
f64,
f80,
f128,
usize,
isize,
c_short,
c_ushort,
c_int,
c_uint,
c_long,
c_ulong,
c_longlong,
c_ulonglong,
c_longdouble,
anyopaque,
bool,
void,
type,
anyerror,
comptime_int,
comptime_float,
noreturn,
@"anyframe",
null_type,
undefined_type,
enum_literal_type,
undefined,
void_value,
null,
bool_true,
bool_false,
};
pub fn get(ia: *InternArena, gpa: Allocator, key: Key) Allocator.Error!Index {
const adapter: KeyAdapter = .{ .intern_arena = ia };
const gop = try ia.map.getOrPutAdapted(gpa, key, adapter);
if (gop.found_existing) {
return @intCast(Index, gop.index);
}
// intern the new item...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment