Skip to content

uecker/noplate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 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)

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

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

	vec_access(v, 1)++;

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

	free(v);




Example 2 (vector of strings)

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

	vec_push(&s, string_init(" Du!"));
	vec_push(&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(&s));

	free(s);




Example 3 (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 4 (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