Files
datum/README.md

123 lines
3.3 KiB
Markdown
Raw Normal View History

2025-11-06 16:36:00 +01:00
<div align="center">
<h1>Datum</h1>
<h6><i>Collection of dynamic and generic data structures.</i></h6>
[![](https://github.com/ceticamarco/datum/actions/workflows/datum.yml/badge.svg)](https://github.com/ceticamarco/datum/actions/workflows/datum.yml)
</div>
2025-11-06 12:16:27 +01:00
Datum is a collection of dynamic and generic data structures implemented from scratch in C with no external dependencies beyond
the standard library. It currently features:
2025-11-10 10:49:23 +01:00
- [**Vector**](/docs/vector.md): a growable, contiguous array of homogenous generic data types;
- [**Map**](/docs/map.md): an associative array that handles generic heterogenous data types;
2025-11-06 12:16:27 +01:00
## Usage
At its simplest, you can use this library as follows:
2025-11-06 16:36:00 +01:00
### `Vector`'s usage
2025-11-06 12:16:27 +01:00
```c
#include <stdio.h>
#include "src/vector.h"
/*
2025-11-06 16:36:00 +01:00
* Compile with: gcc main.c src/vector.c
* Output: First element: 5
2025-11-10 10:49:23 +01:00
* Head of vector: 6, size is now: 1
2025-11-06 16:36:00 +01:00
*/
2025-11-06 12:16:27 +01:00
int main(void) {
// Create an integer vector of initial capacity equal to 5
vector_t *vec = vector_new(5, sizeof(int)).value.vector;
// Add two numbers
int val = 5;
vector_push(vec, &val);
2025-11-06 16:36:00 +01:00
// Equivalent as above
vector_push(vec, &(int){6});
2025-11-06 12:16:27 +01:00
// Print 1st element
const int first = *(int*)vector_get(vec, 0).value.element;
printf("First element: %d\n", first);
// Pop second element using LIFO policy
const int head = *(int*)vector_pop(vec).value.element;
2025-11-10 10:49:23 +01:00
printf("Head of vector: %d, size is now: %zu\n", head, vector_size(vec));
2025-11-06 12:16:27 +01:00
// Remove vector from memory
vector_destroy(vec);
return 0;
}
```
2025-11-06 16:36:00 +01:00
### `Map`'s usage
2025-11-06 12:16:27 +01:00
```c
#include <stdio.h>
#include "src/map.h"
typedef struct {
char name[256];
char surname[256];
short age;
} Person;
/*
2025-11-06 16:36:00 +01:00
* Compile with: gcc main.c src/map.c
* Output: Name: Bob, Surname: Smith, Age: 34
*/
2025-11-06 12:16:27 +01:00
int main(void) {
// Create a new map
map_t *map = map_new().value.map;
// Add a key to the map
2025-11-06 16:36:00 +01:00
const Person bob = { .name = "Bob", .surname = "Smith", .age = 34 };
2025-11-06 12:16:27 +01:00
map_add(map, "bob", (void*)&bob);
// Retrieve 'Bob' and check if it exists
map_result_t bob_res = map_get(map, "bob");
if (bob_res.status == MAP_ERR_NOT_FOUND) {
puts("This key does not exist.");
} else {
2025-11-06 16:36:00 +01:00
const Person *ret = (const Person*)bob_res.value.element;
printf("Name: %s, Surname: %s, Age: %d\n",
ret->name,
ret->surname,
ret->age
);
2025-11-06 12:16:27 +01:00
}
// Remove map from memory
map_destroy(map);
return 0;
}
```
For a more exhaustive example, refer to the `usage.c` file. There, you will find a program with proper error management
and a sample usage for every available method. To run it, first issue the following command:
```sh
$ make clean all
```
This will compile the library as well as the `usage.c` file and the unit tests. After that, you can run it by typing `./usage`.
2025-11-10 10:49:23 +01:00
## Documentation
For additional details about this library (internal design, memory
2025-11-11 13:54:12 +01:00
management, data ownership, etc.) go to the [docs folder](/docs).
2025-11-06 12:16:27 +01:00
## Unit tests
Datum provides some unit tests for both the `Vector` and the `Map` data types. To run them, you can issue the following commands:
```sh
$ make clean all
$ ./test_vector
$ ./test_map
```
## License
This library is released under the GPLv3 license. You can find a copy of the license with this repository or by visiting
2025-11-06 16:36:00 +01:00
[the following link](https://choosealicense.com/licenses/gpl-3.0/).