This repository provides a "generic datastructures in C" proof-of-concept. Wheel heavily relies on the C preprocessor and resolves at compile time, allowing for generics with (near) zero overhead.
Note that this library is still in a very early stage and should not be trusted. Expect ridiculous bugs and errors!
One of the provided datastructures is optional
, which either contains a value or doesn't. The definition in <wheel/optional/impl.h>
is as followed.
typedef struct optional {
bool present;
LIBWHEEL_TYPE value;
} optional;
Here, the type LIBWHEEL_TYPE
is a generic. We can instantiate it to a string, in essence a char*
in the C language. When your application uses Wheel, you may define the header file string.h
as shown below.
#ifndef STRING_H
#define STRING_H
#define LIBWHEEL_TYPE char*
#define LIBWHEEL_ALIAS string
#include <wheel.h>
#endif // STRING_H
If you are unfamiliar with the #ifndef STRING_H
convention, this simply makes sure this specific header file isn't send to the compiler more than once. It is not in any way specific to the library itself.
We define LIBWHEEL_TYPE
, which is what the preprocessor will fill in for every instance of LIBWHEEL_TYPE
in <wheel/optional/impl.h>
. Here, we want it to be char*
.
The name of a struct cannot contain asterisks, so a type definition like struct optional_char*
would be invalid. This means will also have to pass a second argument which will dictate the suffix given to every function and struct, since those still have to be unique. This is where LIBWHEEL_ALIAS
comes in, here mapped to string
. The resulting type will be optional_string
.
Since you most likely will use these macros multiple times in your program, we remove their definition using #undef
at the bottom of string.h
.
Now, the optional type in string.h
will take the following form at compile time.
#ifndef STRING_H
#define STRING_H
typedef struct optional_string {
bool present;
char* value;
} optional_string;
optional_string optional_empty_string() {
optional_string result;
result.present = false;
return result;
}
// etc
#endif // STRING_H
Creating a generic data structure and its procedures is now as simple as defining some macros and including the <wheel.h>
header!