1 // Metamethods are methods that all types share for hashing, equality, comparison, and textifying
7 #include "metamethods.h"
13 PUREFUNC public uint64_t generic_hash(const void *obj, const TypeInfo_t *type) {
14 if (type->metamethods.hash) return type->metamethods.hash(obj, type);
16 return siphash24((void *)obj, (size_t)(type->size));
19 PUREFUNC public int32_t generic_compare(const void *x, const void *y, const TypeInfo_t *type) {
22 if (type->metamethods.compare) return type->metamethods.compare(x, y, type);
24 return (int32_t)memcmp((void *)x, (void *)y, (size_t)(type->size));
27 PUREFUNC public bool generic_equal(const void *x, const void *y, const TypeInfo_t *type) {
28 if (x == y) return true;
30 if (type->metamethods.equal) return type->metamethods.equal(x, y, type);
32 return (generic_compare(x, y, type) == 0);
36 Text_t generic_as_text(const void *obj, bool colorize, const TypeInfo_t *type) {
37 if (!type->metamethods.as_text) fail("No text metamethod provided for type!");
39 return type->metamethods.as_text(obj, colorize, type);
43 void _serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) {
44 if (type->metamethods.serialize) return type->metamethods.serialize(obj, out, pointers, type);
46 fwrite(obj, (size_t)type->size, 1, out);
50 List_t generic_serialize(const void *x, const TypeInfo_t *type) {
53 FILE *stream = open_memstream(&buf, &size);
54 Table_t pointers = EMPTY_TABLE;
55 _serialize(x, stream, &pointers, type);
58 .data = GC_MALLOC_ATOMIC(size),
59 .length = (uint64_t)size,
63 memcpy(bytes.data, buf, size);
69 void _deserialize(FILE *input, void *outval, List_t *pointers, const TypeInfo_t *type) {
70 if (type->metamethods.deserialize) {
71 type->metamethods.deserialize(input, outval, pointers, type);
75 if (fread(outval, (size_t)type->size, 1, input) != 1) fail("Not enough data in stream to deserialize");
79 void generic_deserialize(List_t bytes, void *outval, const TypeInfo_t *type) {
80 if (bytes.stride != 1) List$compact(&bytes, 1);
82 FILE *input = fmemopen(bytes.data, (size_t)bytes.length, "r");
83 List_t pointers = EMPTY_LIST;
84 _deserialize(input, outval, &pointers, type);
88 __attribute__((noreturn)) public
89 void cannot_serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) {
90 (void)obj, (void)out, (void)pointers;
91 Text_t typestr = generic_as_text(NULL, false, type);
92 fail("Values of type ", typestr, " cannot be serialized or deserialized!");
95 __attribute__((noreturn)) public
96 void cannot_deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type) {
97 (void)obj, (void)in, (void)pointers;
98 Text_t typestr = generic_as_text(NULL, false, type);
99 fail("Values of type ", typestr, " cannot be serialized or deserialized!");