relptr.h (1997B)
1 #ifndef RELPTR_H 2 #define RELPTR_H 3 4 #include <stddef.h> 5 #include <stdint.h> 6 7 /* relative pointers allow pointers that can be copied around in memory whilst 8 * still remaning valid. they allow this by forcing the user to specify a "base" 9 * against which the pointer is calculated, as opposed to using the default 10 * base of 0 (when using traditional, absolute pointers). 11 */ 12 13 /* we would like our relative pointers to keep using 0 as a "null" value, for 14 * ergonomics reasons. this makes initialisation of a data structure using 15 * relative pointers identical to the same structure using absolute pointers. 16 */ 17 #define RELPTR_NULL (0) 18 19 /* in a naive implementation of relative pointers: `(uintptr_t) base + offset`, 20 * using a RELPTR_NULL of 0 would result in a "null" pointer that points to 21 * itself. this might be undesirable, as we might want to represent recursive 22 * data structures that do indeed point to themselves. so, we "mask" our 23 * relative pointer before and after conversion from an absolute pointer, to 24 * set the "null value" to some unlikely to be used value. 25 */ 26 #define _RELPTR_MASK(ty_relptr) ((ty_relptr) 1 << ((sizeof(ty_relptr) * 8) - 1)) 27 28 /* we need to convert between a pointer offset and a relative pointer. 29 */ 30 #define _RELPTR_ENC(ty_relptr, ptroff) \ 31 ((ty_relptr) ((ptroff) ^ _RELPTR_MASK(ty_relptr))) 32 33 #define _RELPTR_DEC(ty_relptr, relptr) \ 34 ((ty_relptr) ((relptr) ^ _RELPTR_MASK(ty_relptr))) 35 36 /* these are our main helper macros, that convert between a base and an absolute 37 * pointer to a relative pointer, and between a base and a relative pointer back 38 * to an absolute pointer. 39 */ 40 #define RELPTR_ABS2REL(ty_relptr, base, absptr) \ 41 ((absptr) \ 42 ? _RELPTR_ENC(ty_relptr, (char *) absptr - (char *) base) \ 43 : RELPTR_NULL) 44 45 #define RELPTR_REL2ABS(ty_absptr, ty_relptr, base, relptr) \ 46 (((relptr)) \ 47 ? ((ty_absptr) ((char *) base + _RELPTR_DEC(ty_relptr, relptr))) \ 48 : NULL) 49 50 #endif /* RELPTR_H */