Datum

Collection of dynamic and generic data structures.
[![](https://github.com/ceticamarco/datum/actions/workflows/datum.yml/badge.svg)](https://github.com/ceticamarco/datum/actions/workflows/datum.yml)
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: - [**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; - [**BigInt**](/docs/bigint.md): a data type for arbitrary large integers. ## Usage At its simplest, you can use this library as follows: ### `Vector` usage ```c #include #include "src/vector.h" /* * Compile with: gcc main.c src/vector.c * Output: First element: 5 * Head of vector: 6, size is now: 1 */ 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); // Equivalent as above vector_push(vec, &(int){6}); // 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; printf("Head of vector: %d, size is now: %zu\n", head, vector_size(vec)); // Remove vector from memory vector_destroy(vec); return 0; } ``` ### `Map` usage ```c #include #include "src/map.h" typedef struct { char name[256]; char surname[256]; short age; } Person; /* * Compile with: gcc main.c src/map.c * Output: Name: Bob, Surname: Smith, Age: 34 */ int main(void) { // Create a new map map_t *map = map_new().value.map; // Add a key to the map const Person bob = { .name = "Bob", .surname = "Smith", .age = 34 }; 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 { const Person *ret = (const Person*)bob_res.value.element; printf("Name: %s, Surname: %s, Age: %d\n", ret->name, ret->surname, ret->age ); } // Remove map from memory map_destroy(map); return 0; } ``` ### `BigInt` usage ```c #include #include "src/bigint.h" /* * Compile with: gcc main.c src/bigint.c * Output: 20000! = 1819206320230345134827641... * Time: real 0m5.482s user 0m5.453s sys 0m0.017 */ int main(void) { const int n = 20000; bigint_t *fact = bigint_from_int(1).value.number; for (int idx = 2; idx<=n; idx++) { bigint_t *big_idx = bigint_from_int(idx).value.number; bigint_t *partial_fact = bigint_prod(fact, big_idx).value.number; bigint_destroy(fact); bigint_destroy(big_idx); fact = partial_fact; } printf("%d! = ", n); bigint_print(fact); printf("\n"); bigint_destroy(fact); 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`. ## Documentation For additional details about this library (internal design, memory management, data ownership, etc.) go to the [docs folder](/docs). ## 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 [the following link](https://choosealicense.com/licenses/gpl-3.0/).