Skip to content

uecker/noplate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

62 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

noplate library

experimental generic type-safe container data structures for C

Generic types provided are: vector, list, product, sum, and maybe. The generic types are based on structures defined in macros. They take typedef names as arguments and define a generic container with this element type:

vec(int)* vi; // pointer to a vector of ints

There is also support for arrays and strings. Arrays are just regular C arrays but we provide functions such as array_slice that perform bounds checking. A string is a vector of char with null-termination.

All container types preserve information about the type of the elements and also have bounds checking, i.e. out-of-bounds accesses trap at run-time (with UBSan).

Interoperability works by providing access to the underlying elements. For example, vec_access provides access to an lvalue for the underlying element of a vector and vec_array provides access to an array representing the complete vector. This array is a VLA, so accesses are also checked when using UBSan. A string type is defined as vector of char with null termination. The underlying array can be passed as an argument to C functions, because the array decays to a pointer.

(the need to declare the types upfront will go away with C23)

Example 1 (vector of integers)

https://godbolt.org/z/Eos9E5s9o

vec_decl(int);
vec(int)* v = vec_alloc(int);

vec_push(int, &v, 1);
vec_push(int, &v, 3);

vec_access(int, v, 1)++;

vec_access(int, v, 10) = 1;	// run-time error!

free(v);

Example 3 (strings)

https://godbolt.org/z/6oo6131jr

Example 4 (maybe)

https://godbolt.org/z/Evsfhv3no

Example 5 (vector of strings)

typedef string* string_ptr;
vec_decl(string_ptr)
vec(string_ptr)* s = vec_alloc(string_ptr);

vec_push(string_ptr, &s, string_init(" Du!"));
vec_push(string_ptr, &s, string_init("Hallo"));

int cmp2(const string_ptr* a, const string_ptr* b)
{
	return strcmp(string_cstr(*a), string_cstr(*b));
}

vec_sort(s, cmp2);

while (0 < vec_length(s))
	free(vec_pop(string_ptr, &s));

free(s);

Example 6 (array slice)

string* s = string_init("hallo");

auto slice = &array_slice(string_cstr(s), 1, 1 + 3);
(*slice)[0] = 'A';
(*slice)[1] = 'L';
(*slice)[2] = 'L';

Example 7 (byte-level loads and stores)

char buf[sizeof(int)];

poke(int, &buf, 1);

About

generic data structures

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published