> Pi types in C.
I took a quick look at what these are. Couldn't they implemented with macros like (this builds a type "Utf8String" which "depends" on the value of the "ENCODING" parameter to figure out what set of functions to call for the guts of the functions that handle the type, e.g. RawStringUtf8Length):
enum Encoding { Ascii, Utf8, Utf16 };
#define TYPENAME Utf8String
#define ENCODING Utf8
#define CHARTYPE char
#include "stringdef.ph"
Then in stringdef.ph (ph=parametric header, just came up with it):
typedef struct { size_t len; CHARTYPE* text; } TYPENAME;
#define MAKEFUNC(name) TYPENAME##name
#define RAWSTRINGFUNC(name) RawString##ENCODING
void MAKEFUNC(Create)(TYPENAME* str);
void MAKEFUNC(Destroy)(TYPENAME* str);
void MAKEFUNC(CreateFrom)(TYPENAME* str, const CHARTYPE* text);
/* this goes in a single C file, single header library style */
#ifdef IMPLEMENTATION
void MAKEFUNC(Create)(TYPENAME* str) { ... }
void MAKEFUNC(Destroy)(TYPENAME* str) { ... }
void MAKEFUNC(CreateFrom)(TYPENAME* str, const CHARTYPE* text) {
str->len = RAWSTRINGFUNC(Length)(text);
str->text = RAWSTRINGFUNC(Duplicate)(text);
}
#endif
#undef MAKEFUNC
/* cleanup input parameters so includers wont need to do it */
#undef CHARTYPE
#undef ENCODING
#undef TYPENAME
Then you can use the above simply like
Utf8String u8s;
Utf8StringCreateFrom(&u8s, "foo...");
It isn't exactly pretty, but seems to do the work. The ENCODING parameter is only conceptually an Encoding enum, but this can be enforced with some dummy (unused) code that does use of the ENCODING value as Encoding (and if extra strength is needed, as enums are weakly typed, instead of native enums, you could define macros that create stronger "enums" out of structs).