| #include <assert.h> | |
| #include <stddef.h> | |
| #include <stdio.h> | |
| #define var __auto_type | |
| #define let __auto_type const | |
| static inline void * variant_cast(void * variant_ptr, ptrdiff_t desired_tag) { | |
| ptrdiff_t * variant_tag = (ptrdiff_t *)variant_ptr; | |
| assert(*variant_tag == desired_tag); | |
| return (void *)((char *)variant_ptr + sizeof(ptrdiff_t)); | |
| } | |
| #define tag(x) ((ptrdiff_t)&Tag##x) | |
| #define is(x, T) ((x)->tag == tag(T)) | |
| #define as(x, T) ((struct T *)variant_cast((void *)(x), tag(T))) | |
| struct SomeOne { | |
| int x; | |
| int y; | |
| } TagSomeOne; | |
| struct SomeTwo { | |
| float z; | |
| float w; | |
| } TagSomeTwo; | |
| struct Some { | |
| ptrdiff_t tag; | |
| union { | |
| struct SomeOne _; | |
| struct SomeTwo __; | |
| }; | |
| }; | |
| int main() { | |
| struct Some a = {}; | |
| a.tag = tag(SomeTwo); | |
| printf("Is `a` tagged as SomeTwo: %d\n", is(&a, SomeTwo)); | |
| let b = as(&a, SomeTwo); | |
| b->w = 5.0; | |
| printf("b->w: %f\n", b->w); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment