diff --git a/Documentation.md b/Documentation.md index b66733c..003dc59 100644 --- a/Documentation.md +++ b/Documentation.md @@ -11,6 +11,10 @@ * [HashSet](#HashSet) * [HashMap](#HashMap) +Others + +* [ForEach](#ForEach) + # [List](#collections_index) A List is a Dynamic Array that store its elements contiguously. It has an internal buffer that is pre-allocated with a greater capacity than necessary in order to foresee new elements being added. The items can be added at both ends of the list and at the middle (with a given index). @@ -2764,3 +2768,78 @@ A HashMap is an associative container that maps a key `K` to a value `V` contain HashMaps are one of the most used data structures as they are very useful as lookup tables. +# [ForEach](#collections_index) + +The ForEach macro is an utility that can be used to simplify iterations through a collections. There are two ForEach macros: + +* `FOR_EACH` - Iterates over a collection forwards, from the start to the end*. +* `FOR_EACH_REV` - Iterates over a collection backwards, from the end to the start*. + +\* Check out the documentation of each collection to know which elements are regarded as the starting point and ending point of an iteration. + +### Parameters + +* `PFX` - The prefix of the functions of the defined collection. +* `SNAME` - The defined name of your collection +* `TARGET` - The target collection to be iterated over. +* `BODY` - The body of your loop where a local variable called `iter` will be available. + +### Example + +```c +#include "hashmap.h" +#include "foreach.h" // The ForEach macros are defined here +#include + +// Int hash function +size_t inthash(int t) +{ + size_t a = t; + a += ~(a << 15); + a ^= (a >> 10); + a += (a << 3); + a ^= (a >> 6); + a += ~(a << 11); + a ^= (a >> 16); + return a; +} + +// Int compare function +int intcmp(int a, int b) +{ + return (a > b) - (a < b); +} + +// Generate all the code for the hashmap +HASHMAP_GENERATE(hm, hashmap, /* FMOD */, int, double) + +int main(void) +{ + // Create a new hashmap with custom hash function + // The comparison function is only required to know if the key looked for was found + hashmap *map = hm_new(1000, 0.6, intcmp, inthash); + + // Add keys mapped to a value + for (int i = 0; i < 5000; i++) + { + hm_insert(map, i, (double)i / 1000.0); + } + + // Iterate over the HashMap without the FOR_EACH macro + for (hashmap_iter iter = map->it_start(map); !hm_iter_end(&iter); hm_iter_next(&iter)) + { + printf("MAP[%4d] = %.3lf\n", hm_iter_key(&iter), hm_iter_value(&iter)); + } + + // Iterate over the HashMap using FOR_EACH macro + FOR_EACH(hm, hashmap, map, { + // Inside, the variable 'iter' will be available and from it you can access + // the key, value or index. + printf("MAP[%4d] = %.3lf\n", hm_iter_key(&iter), hm_iter_value(&iter)); + }) + + hm_free(map); + + return 0; +} +``` diff --git a/TODO b/TODO index 7892051..95f5ddc 100644 --- a/TODO +++ b/TODO @@ -21,25 +21,21 @@ Before 2.0 Get Documentation fixed and completed 1.5 - Simplify PUBLIC and PRIVATE (simply remove them) - Conditional code generation - Add extra content macro (Insert/Remove/Append/Prepend) and let user decide if he wants to include them or not - Separate Implementation Detail into a different MACRO (LIST_GENERATE_DETAIL) - -1.6 + Remove PUBLIC and PRIVATE Iterator move and move_to LinkedList - Insert/Remove/Append/Prepend/Extract + from_array - Creates a collection with all the elements in a specified array to_array - Creates an array with all the elements inside the collection -1.7 +1.6 Add shrink function that shrinks the internal buffer to current count of elements + Add dispose method to each collection in order to automatically free its data 2.0 Add multiset, multimap and new heap implementation 2.1 - Adapt multiset, multimap, treehashmap and new heap implementation to the current standards - Add dispose method to each collection in order to automatically free its data + Adapt multiset, multimap and new heap implementation to the current standards 2.2 Add serialization functions @@ -52,5 +48,6 @@ Before 2.0 2.3 Iterator functions (functions that operate relative to iterators position) like add or remove ranges -Sometime - Add treehashmap +SOMETIME + +Add treehashmap diff --git a/examples/hashmap/foreach.c b/examples/hashmap/foreach.c new file mode 100644 index 0000000..598b54d --- /dev/null +++ b/examples/hashmap/foreach.c @@ -0,0 +1,65 @@ +/** + * iterator.c + * + * Creation Date: 23/05/2019 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + * Foreach macro example + */ +#include "hashmap.h" +#include "foreach.h" +#include + +// Int hash function +size_t inthash(int t) +{ + size_t a = t; + a += ~(a << 15); + a ^= (a >> 10); + a += (a << 3); + a ^= (a >> 6); + a += ~(a << 11); + a ^= (a >> 16); + return a; +} + +// Int compare function +int intcmp(int a, int b) +{ + return (a > b) - (a < b); +} + +// Generate all the code for the hashmap +HASHMAP_GENERATE(hm, hashmap, /* FMOD */, int, double) + +int main(void) +{ + // Create a new hashmap with custom hash function + // The comparison function is only required to know if the key looked for was found + hashmap *map = hm_new(1000, 0.6, intcmp, inthash); + + // Add keys mapped to a value + for (int i = 0; i < 5000; i++) + { + hm_insert(map, i, (double)i / 1000.0); + } + + // Iterate over the HashMap without the FOR_EACH macro + for (hashmap_iter iter = map->it_start(map); !hm_iter_end(&iter); hm_iter_next(&iter)) + { + printf("MAP[%4d] = %.3lf\n", hm_iter_key(&iter), hm_iter_value(&iter)); + } + + // Iterate over the HashMap using FOR_EACH macro + FOR_EACH(hm, hashmap, map, { + // Inside, the variable 'iter' will be available and from it you can access + // the key, value or index. + printf("MAP[%4d] = %.3lf\n", hm_iter_key(&iter), hm_iter_value(&iter)); + }) + + hm_free(map); + + return 0; +}