Final update - fixed foreach, tests and benchmark

This commit is contained in:
Leonardo committed 2019-05-16 13:41:35 -03:00
1 parent 22e84db11a
commit 5f39eb011c
8 files changed
+841 -1197

No files matched your search

+13 -14
View File
@@ -13,7 +13,7 @@
* - Output
*/
#include "macro_collections.h"
#include "timer.h"
#include "util/timer.h"
#include "util/twister.c"
#include <stdio.h>
#include <stdint.h>
@@ -71,7 +71,7 @@ COLLECTION_GENERATE(TREEMAP, PUBLIC, tm, tmap, /* FMOD */, int, int)
COLLECTION_GENERATE(HASHSET, PUBLIC, hs, hset, /* FMOD */, /* K */, int)
COLLECTION_GENERATE(HASHMAP, PUBLIC, hm, hmap, /* FMOD */, int, int)
#define BENCHMARK(NAME, PFX, sname, initfunc, insertbody, removebody, iternext, searchbody) \
#define BENCHMARK(NAME, PFX, sname, initfunc, insertbody, removebody, searchbody) \
void NAME##_io_benchmark(int *array, int *sarray, size_t s) \
{ \
printf("+------------------------------------------------------------ %10s\n", #NAME); \
@@ -119,9 +119,8 @@ COLLECTION_GENERATE(HASHMAP, PUBLIC, hm, hmap, /* FMOD */, int, int)
\
TIMER_START(timer) \
\
for (PFX##_iter_init(&iter, coll); !PFX##_iter_end(&iter);) \
for (PFX##_iter_init(&iter, coll); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
{ \
iternext; \
} \
\
TIMER_STOP(timer) \
@@ -173,16 +172,16 @@ COLLECTION_GENERATE(HASHMAP, PUBLIC, hm, hmap, /* FMOD */, int, int)
printf("+------------------------------------------------------------ %10s\n\n", #NAME); \
}
BENCHMARK(DEQUE, d, deque, d_new(NTOTAL), d_push_back(coll, array[i]), d_pop_back(coll), d_iter_next(&iter, &k, &j), d_contains(coll, sarray[i], intcmp))
BENCHMARK(HASHMAP, hm, hmap, hm_new(NTOTAL, 0.8, intcmp, inthash), hm_insert(coll, array[i], array[i]), hm_remove(coll, array[i], &r), hm_iter_next(&iter, &k, &v, &j), hm_contains(coll, sarray[i]))
BENCHMARK(HASHSET, hs, hset, hs_new(NTOTAL, 0.8, intcmp, inthash), hs_insert(coll, array[i]), hs_remove(coll, array[i]), hs_iter_next(&iter, &v, &j), hs_contains(coll, sarray[i]))
BENCHMARK(HEAP, h, heap, h_new(NTOTAL, MinHeap, intcmp), h_insert(coll, array[i]), h_remove(coll, &r), h_iter_next(&iter, &v, &j), h_contains(coll, sarray[i]))
BENCHMARK(LINKEDLIST, ll, linked, ll_new(), ll_push_back(coll, array[i]), ll_pop_back(coll), ll_iter_next(&iter, &v, &j), ll_contains(coll, sarray[i], intcmp))
BENCHMARK(LIST, l, list, l_new(NTOTAL), l_push_back(coll, array[i]), l_pop_back(coll), l_iter_next(&iter, &v, &j), l_contains(coll, sarray[i], intcmp))
BENCHMARK(QUEUE, q, queue, q_new(NTOTAL), q_enqueue(coll, array[i]), q_dequeue(coll), q_iter_next(&iter, &v, &j), q_contains(coll, sarray[i], intcmp))
BENCHMARK(STACK, s, stack, s_new(NTOTAL), s_push(coll, array[i]), s_pop(coll), s_iter_next(&iter, &v, &j), s_contains(coll, sarray[i], intcmp))
BENCHMARK(TREEMAP, tm, tmap, tm_new(intcmp), tm_insert(coll, array[i], array[i]), tm_remove(coll, array[i], &r), tm_iter_next(&iter, &k, &v, &j), tm_contains(coll, sarray[i]))
BENCHMARK(TREESET, ts, tset, ts_new(intcmp), ts_insert(coll, array[i]), ts_remove(coll, array[i]), ts_iter_next(&iter, &v, &j), ts_contains(coll, sarray[i]))
BENCHMARK(DEQUE, d, deque, d_new(NTOTAL), d_push_back(coll, array[i]), d_pop_back(coll), d_contains(coll, sarray[i], intcmp))
BENCHMARK(HASHMAP, hm, hmap, hm_new(NTOTAL, 0.8, intcmp, inthash), hm_insert(coll, array[i], array[i]), hm_remove(coll, array[i], &r), hm_contains(coll, sarray[i]))
BENCHMARK(HASHSET, hs, hset, hs_new(NTOTAL, 0.8, intcmp, inthash), hs_insert(coll, array[i]), hs_remove(coll, array[i]), hs_contains(coll, sarray[i]))
BENCHMARK(HEAP, h, heap, h_new(NTOTAL, MinHeap, intcmp), h_insert(coll, array[i]), h_remove(coll, &r), h_contains(coll, sarray[i]))
BENCHMARK(LINKEDLIST, ll, linked, ll_new(), ll_push_back(coll, array[i]), ll_pop_back(coll), ll_contains(coll, sarray[i], intcmp))
BENCHMARK(LIST, l, list, l_new(NTOTAL), l_push_back(coll, array[i]), l_pop_back(coll), l_contains(coll, sarray[i], intcmp))
BENCHMARK(QUEUE, q, queue, q_new(NTOTAL), q_enqueue(coll, array[i]), q_dequeue(coll), q_contains(coll, sarray[i], intcmp))
BENCHMARK(STACK, s, stack, s_new(NTOTAL), s_push(coll, array[i]), s_pop(coll), s_contains(coll, sarray[i], intcmp))
BENCHMARK(TREEMAP, tm, tmap, tm_new(intcmp), tm_insert(coll, array[i], array[i]), tm_remove(coll, array[i], &r), tm_contains(coll, sarray[i]))
BENCHMARK(TREESET, ts, tset, ts_new(intcmp), ts_insert(coll, array[i]), ts_remove(coll, array[i]), ts_contains(coll, sarray[i]))
int main(void)
{
File renamed without changes.
+349 -349
View File
@@ -133,355 +133,355 @@
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
\
/* SOURCE ********************************************************************/
#define DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
\
/* Implementation Detail Functions */ \
FMOD bool PFX##_impl_grow(SNAME *_deque_); \
SNAME##_iter PFX##_impl_it_start(SNAME *_deque_); \
SNAME##_iter PFX##_impl_it_end(SNAME *_deque_); \
\
FMOD SNAME *PFX##_new(size_t size) \
{ \
if (size < 1) \
return NULL; \
\
SNAME *_deque_ = malloc(sizeof(SNAME)); \
\
if (!_deque_) \
return NULL; \
\
_deque_->buffer = malloc(sizeof(V) * size); \
\
if (!_deque_->buffer) \
{ \
free(_deque_); \
return NULL; \
} \
\
memset(_deque_->buffer, 0, sizeof(V) * size); \
\
_deque_->capacity = size; \
_deque_->count = 0; \
_deque_->front = 0; \
_deque_->back = 0; \
\
_deque_->it_start = PFX##_impl_it_start; \
_deque_->it_end = PFX##_impl_it_end; \
\
return _deque_; \
} \
\
FMOD void PFX##_clear(SNAME *_deque_) \
{ \
memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \
\
_deque_->count = 0; \
_deque_->front = 0; \
_deque_->back = 0; \
} \
\
FMOD void PFX##_free(SNAME *_deque_) \
{ \
free(_deque_->buffer); \
free(_deque_); \
} \
\
FMOD bool PFX##_push_front(SNAME *_deque_, V element) \
{ \
if (PFX##_full(_deque_)) \
{ \
if (!PFX##_impl_grow(_deque_)) \
return false; \
} \
\
_deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \
\
_deque_->buffer[_deque_->front] = element; \
\
_deque_->count++; \
\
return true; \
} \
\
FMOD bool PFX##_push_back(SNAME *_deque_, V element) \
{ \
if (PFX##_full(_deque_)) \
{ \
if (!PFX##_impl_grow(_deque_)) \
return false; \
} \
\
_deque_->buffer[_deque_->back] = element; \
\
_deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \
\
_deque_->count++; \
\
return true; \
} \
\
FMOD bool PFX##_pop_front(SNAME *_deque_) \
{ \
if (PFX##_empty(_deque_)) \
return false; \
\
_deque_->buffer[_deque_->front] = 0; \
\
_deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \
\
_deque_->count--; \
\
return true; \
} \
\
FMOD bool PFX##_pop_back(SNAME *_deque_) \
{ \
if (PFX##_empty(_deque_)) \
return false; \
\
_deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
\
_deque_->buffer[_deque_->back] = 0; \
\
_deque_->count--; \
\
return true; \
} \
\
FMOD bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition) \
{ \
if (condition) \
return PFX##_push_front(_deque_, element); \
\
return false; \
} \
\
FMOD bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition) \
{ \
if (condition) \
return PFX##_push_back(_deque_, element); \
\
return false; \
} \
\
FMOD bool PFX##_pop_front_if(SNAME *_deque_, bool condition) \
{ \
if (condition) \
return PFX##_pop_front(_deque_); \
\
return false; \
} \
\
FMOD bool PFX##_pop_back_if(SNAME *_deque_, bool condition) \
{ \
if (condition) \
return PFX##_pop_back(_deque_); \
\
return false; \
} \
\
FMOD V PFX##_front(SNAME *_deque_) \
{ \
if (PFX##_empty(_deque_)) \
return 0; \
\
return _deque_->buffer[_deque_->front]; \
} \
\
FMOD V PFX##_back(SNAME *_deque_) \
{ \
if (PFX##_empty(_deque_)) \
return 0; \
\
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \
} \
\
FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \
{ \
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->count, j++) \
{ \
if (comparator(_deque_->buffer[i], element) == 0) \
return true; \
} \
\
return false; \
} \
\
FMOD bool PFX##_empty(SNAME *_deque_) \
{ \
return _deque_->count == 0; \
} \
\
FMOD bool PFX##_full(SNAME *_deque_) \
{ \
return _deque_->count >= _deque_->capacity; \
} \
\
FMOD size_t PFX##_count(SNAME *_deque_) \
{ \
return _deque_->count; \
} \
\
FMOD size_t PFX##_capacity(SNAME *_deque_) \
{ \
return _deque_->capacity; \
} \
\
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
{ \
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
\
if (!iter) \
return NULL; \
\
PFX##_iter_init(iter, target); \
\
return iter; \
} \
\
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
{ \
free(iter); \
} \
\
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
{ \
iter->target = target; \
iter->cursor = target->front; \
iter->index = 0; \
iter->start = true; \
iter->end = PFX##_empty(target); \
} \
\
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
{ \
return PFX##_empty(iter->target) || iter->start; \
} \
\
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
{ \
return PFX##_empty(iter->target) || iter->end; \
} \
\
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
{ \
iter->cursor = iter->target->front; \
iter->index = 0; \
iter->start = true; \
iter->end = PFX##_empty(iter->target); \
} \
\
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
iter->cursor = 0; \
else \
iter->cursor = (iter->target->back == 0) ? iter->target->count - 1 : iter->target->back - 1; \
\
iter->index = iter->target->count - 1; \
iter->start = PFX##_empty(iter->target); \
iter->end = true; \
} \
\
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
{ \
if (iter->end) \
return false; \
\
iter->start = PFX##_empty(iter->target); \
\
if (iter->index == iter->target->count - 1) \
iter->end = true; \
else \
{ \
iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
iter->index++; \
} \
\
return true; \
} \
\
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
{ \
if (iter->start) \
return false; \
\
iter->end = PFX##_empty(iter->target); \
\
if (iter->index == 0) \
iter->start = true; \
else \
{ \
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
iter->index--; \
} \
\
return true; \
} \
\
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
return 0; \
\
return iter->target->buffer[iter->cursor]; \
} \
\
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
return NULL; \
\
return &(iter->target->buffer[iter->cursor]); \
} \
\
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
{ \
return iter->index; \
} \
\
FMOD bool PFX##_impl_grow(SNAME *_deque_) \
{ \
\
size_t new_capacity = _deque_->capacity * 2; \
\
V *new_buffer = malloc(sizeof(V) * new_capacity); \
\
if (!new_buffer) \
return false; \
\
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \
{ \
new_buffer[j] = _deque_->buffer[i]; \
} \
\
free(_deque_->buffer); \
\
_deque_->buffer = new_buffer; \
_deque_->capacity = new_capacity; \
_deque_->front = 0; \
_deque_->back = _deque_->count; \
\
return true; \
} \
\
SNAME##_iter PFX##_impl_it_start(SNAME *_deque_) \
{ \
SNAME##_iter iter; \
\
PFX##_iter_init(&iter, _deque_); \
\
return iter; \
} \
\
SNAME##_iter PFX##_impl_it_end(SNAME *_deque_) \
{ \
SNAME##_iter iter; \
\
PFX##_iter_init(&iter, _deque_); \
PFX##_iter_to_end(&iter); \
\
return iter; \
#define DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
\
/* Implementation Detail Functions */ \
FMOD bool PFX##_impl_grow(SNAME *_deque_); \
SNAME##_iter PFX##_impl_it_start(SNAME *_deque_); \
SNAME##_iter PFX##_impl_it_end(SNAME *_deque_); \
\
FMOD SNAME *PFX##_new(size_t size) \
{ \
if (size < 1) \
return NULL; \
\
SNAME *_deque_ = malloc(sizeof(SNAME)); \
\
if (!_deque_) \
return NULL; \
\
_deque_->buffer = malloc(sizeof(V) * size); \
\
if (!_deque_->buffer) \
{ \
free(_deque_); \
return NULL; \
} \
\
memset(_deque_->buffer, 0, sizeof(V) * size); \
\
_deque_->capacity = size; \
_deque_->count = 0; \
_deque_->front = 0; \
_deque_->back = 0; \
\
_deque_->it_start = PFX##_impl_it_start; \
_deque_->it_end = PFX##_impl_it_end; \
\
return _deque_; \
} \
\
FMOD void PFX##_clear(SNAME *_deque_) \
{ \
memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \
\
_deque_->count = 0; \
_deque_->front = 0; \
_deque_->back = 0; \
} \
\
FMOD void PFX##_free(SNAME *_deque_) \
{ \
free(_deque_->buffer); \
free(_deque_); \
} \
\
FMOD bool PFX##_push_front(SNAME *_deque_, V element) \
{ \
if (PFX##_full(_deque_)) \
{ \
if (!PFX##_impl_grow(_deque_)) \
return false; \
} \
\
_deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \
\
_deque_->buffer[_deque_->front] = element; \
\
_deque_->count++; \
\
return true; \
} \
\
FMOD bool PFX##_push_back(SNAME *_deque_, V element) \
{ \
if (PFX##_full(_deque_)) \
{ \
if (!PFX##_impl_grow(_deque_)) \
return false; \
} \
\
_deque_->buffer[_deque_->back] = element; \
\
_deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \
\
_deque_->count++; \
\
return true; \
} \
\
FMOD bool PFX##_pop_front(SNAME *_deque_) \
{ \
if (PFX##_empty(_deque_)) \
return false; \
\
_deque_->buffer[_deque_->front] = 0; \
\
_deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \
\
_deque_->count--; \
\
return true; \
} \
\
FMOD bool PFX##_pop_back(SNAME *_deque_) \
{ \
if (PFX##_empty(_deque_)) \
return false; \
\
_deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
\
_deque_->buffer[_deque_->back] = 0; \
\
_deque_->count--; \
\
return true; \
} \
\
FMOD bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition) \
{ \
if (condition) \
return PFX##_push_front(_deque_, element); \
\
return false; \
} \
\
FMOD bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition) \
{ \
if (condition) \
return PFX##_push_back(_deque_, element); \
\
return false; \
} \
\
FMOD bool PFX##_pop_front_if(SNAME *_deque_, bool condition) \
{ \
if (condition) \
return PFX##_pop_front(_deque_); \
\
return false; \
} \
\
FMOD bool PFX##_pop_back_if(SNAME *_deque_, bool condition) \
{ \
if (condition) \
return PFX##_pop_back(_deque_); \
\
return false; \
} \
\
FMOD V PFX##_front(SNAME *_deque_) \
{ \
if (PFX##_empty(_deque_)) \
return 0; \
\
return _deque_->buffer[_deque_->front]; \
} \
\
FMOD V PFX##_back(SNAME *_deque_) \
{ \
if (PFX##_empty(_deque_)) \
return 0; \
\
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \
} \
\
FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \
{ \
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->count, j++) \
{ \
if (comparator(_deque_->buffer[i], element) == 0) \
return true; \
} \
\
return false; \
} \
\
FMOD bool PFX##_empty(SNAME *_deque_) \
{ \
return _deque_->count == 0; \
} \
\
FMOD bool PFX##_full(SNAME *_deque_) \
{ \
return _deque_->count >= _deque_->capacity; \
} \
\
FMOD size_t PFX##_count(SNAME *_deque_) \
{ \
return _deque_->count; \
} \
\
FMOD size_t PFX##_capacity(SNAME *_deque_) \
{ \
return _deque_->capacity; \
} \
\
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
{ \
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
\
if (!iter) \
return NULL; \
\
PFX##_iter_init(iter, target); \
\
return iter; \
} \
\
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
{ \
free(iter); \
} \
\
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
{ \
iter->target = target; \
iter->cursor = target->front; \
iter->index = 0; \
iter->start = true; \
iter->end = PFX##_empty(target); \
} \
\
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
{ \
return PFX##_empty(iter->target) || iter->start; \
} \
\
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
{ \
return PFX##_empty(iter->target) || iter->end; \
} \
\
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
{ \
iter->cursor = iter->target->front; \
iter->index = 0; \
iter->start = true; \
iter->end = PFX##_empty(iter->target); \
} \
\
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
iter->cursor = 0; \
else \
iter->cursor = (iter->target->back == 0) ? iter->target->capacity - 1 : iter->target->back - 1; \
\
iter->index = iter->target->count - 1; \
iter->start = PFX##_empty(iter->target); \
iter->end = true; \
} \
\
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
{ \
if (iter->end) \
return false; \
\
iter->start = PFX##_empty(iter->target); \
\
if (iter->index == iter->target->count - 1) \
iter->end = true; \
else \
{ \
iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
iter->index++; \
} \
\
return true; \
} \
\
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
{ \
if (iter->start) \
return false; \
\
iter->end = PFX##_empty(iter->target); \
\
if (iter->index == 0) \
iter->start = true; \
else \
{ \
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
iter->index--; \
} \
\
return true; \
} \
\
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
return 0; \
\
return iter->target->buffer[iter->cursor]; \
} \
\
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
return NULL; \
\
return &(iter->target->buffer[iter->cursor]); \
} \
\
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
{ \
return iter->index; \
} \
\
FMOD bool PFX##_impl_grow(SNAME *_deque_) \
{ \
\
size_t new_capacity = _deque_->capacity * 2; \
\
V *new_buffer = malloc(sizeof(V) * new_capacity); \
\
if (!new_buffer) \
return false; \
\
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \
{ \
new_buffer[j] = _deque_->buffer[i]; \
} \
\
free(_deque_->buffer); \
\
_deque_->buffer = new_buffer; \
_deque_->capacity = new_capacity; \
_deque_->front = 0; \
_deque_->back = _deque_->count; \
\
return true; \
} \
\
SNAME##_iter PFX##_impl_it_start(SNAME *_deque_) \
{ \
SNAME##_iter iter; \
\
PFX##_iter_init(&iter, _deque_); \
\
return iter; \
} \
\
SNAME##_iter PFX##_impl_it_end(SNAME *_deque_) \
{ \
SNAME##_iter iter; \
\
PFX##_iter_init(&iter, _deque_); \
PFX##_iter_to_end(&iter); \
\
return iter; \
}
#endif /* CMC_DEQUE_H */
+15 -56
View File
@@ -11,63 +11,22 @@
#ifndef CMC_FOR_EACH
#define CMC_FOR_EACH
#include <stdlib.h>
#include <stdbool.h>
#define FOR_EACH(PFX, SNAME, V, TARGET, BODY) \
do \
{ \
size_t index; \
V value; \
SNAME##_iter iter; \
PFX##_iter_init(&iter, TARGET); \
while (PFX##_iter_next(&iter, &value, &index)) \
{ \
BODY; \
} \
#define FOR_EACH(PFX, SNAME, TARGET, BODY) \
do \
{ \
for (SNAME##_iter iter = TARGET->it_start(TARGET); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
{ \
BODY; \
} \
} while (0);
#define FOR_EACH_REV(PFX, SNAME, V, TARGET, BODY) \
do \
{ \
size_t index; \
V value; \
SNAME##_iter iter; \
PFX##_iter_init(&iter, TARGET); \
PFX##_iter_toend(&iter); \
while (PFX##_iter_prev(&iter, &value, &index)) \
{ \
BODY; \
} \
#define FOR_EACH_REV(PFX, SNAME, TARGET, BODY) \
do \
{ \
for (SNAME##_iter iter = TARGET->it_end(TARGET); !PFX##_iter_start(&iter); PFX##_iter_prev(&iter)) \
{ \
BODY; \
} \
} while (0);
#define FOR_EACH_MAP(PFX, SNAME, K, V, TARGET, BODY) \
do \
{ \
size_t index; \
K key; \
V value; \
SNAME##_iter iter; \
PFX##_iter_init(&iter, TARGET); \
while (PFX##_iter_next(&iter, &key, &value, &index)) \
{ \
BODY; \
} \
} while (0);
#define FOR_EACH_MAP_REV(PFX, SNAME, K, V, TARGET, BODY) \
do \
{ \
size_t index; \
K key; \
V value; \
SNAME##_iter iter; \
PFX##_iter_init(&iter, TARGET); \
PFX##_iter_toend(&iter); \
while (PFX##_iter_prev(&iter, &key, &value, &index)) \
{ \
BODY; \
} \
} while (0);
#endif /* CMC_FOR_EACH */
#endif /* CMC_FOR_EACH */
+293 -293
View File
@@ -128,299 +128,299 @@
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
\
/* SOURCE ********************************************************************/
#define QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
\
/* Implementation Detail Functions */ \
FMOD bool PFX##_grow(SNAME *_queue_); \
SNAME##_iter PFX##_impl_it_start(SNAME *_queue_); \
SNAME##_iter PFX##_impl_it_end(SNAME *_queue_); \
\
FMOD SNAME *PFX##_new(size_t size) \
{ \
if (size < 1) \
return NULL; \
\
SNAME *_queue_ = malloc(sizeof(SNAME)); \
\
if (!_queue_) \
return NULL; \
\
_queue_->buffer = malloc(sizeof(V) * size); \
\
if (!_queue_->buffer) \
{ \
free(_queue_); \
return NULL; \
} \
\
memset(_queue_->buffer, 0, sizeof(V) * size); \
\
_queue_->capacity = size; \
_queue_->count = 0; \
_queue_->front = 0; \
_queue_->rear = 0; \
\
_queue_->it_start = PFX##_impl_it_start; \
_queue_->it_end = PFX##_impl_it_end; \
\
return _queue_; \
} \
\
FMOD void PFX##_clear(SNAME *_queue_) \
{ \
memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \
\
_queue_->count = 0; \
_queue_->front = 0; \
_queue_->rear = 0; \
} \
\
FMOD void PFX##_free(SNAME *_queue_) \
{ \
free(_queue_->buffer); \
free(_queue_); \
} \
\
FMOD bool PFX##_enqueue(SNAME *_queue_, V element) \
{ \
if (PFX##_full(_queue_)) \
{ \
if (!PFX##_grow(_queue_)) \
return false; \
} \
\
_queue_->buffer[_queue_->rear] = element; \
\
_queue_->rear = (_queue_->rear == _queue_->capacity - 1) ? 0 : _queue_->rear + 1; \
_queue_->count++; \
\
return true; \
} \
\
FMOD bool PFX##_dequeue(SNAME *_queue_) \
{ \
if (PFX##_empty(_queue_)) \
return false; \
\
_queue_->buffer[_queue_->front] = 0; \
\
_queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; \
_queue_->count--; \
\
return true; \
} \
\
FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition) \
{ \
if (condition) \
return PFX##_enqueue(_queue_, element); \
\
return false; \
} \
\
FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition) \
{ \
if (condition) \
return PFX##_dequeue(_queue_); \
\
return false; \
} \
\
FMOD V PFX##_peek(SNAME *_queue_) \
{ \
if (PFX##_empty(_queue_)) \
return 0; \
\
return _queue_->buffer[_queue_->front]; \
} \
\
FMOD bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)) \
{ \
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->count, j++) \
{ \
if (comparator(_queue_->buffer[i], element) == 0) \
return true; \
} \
\
return false; \
} \
\
FMOD bool PFX##_empty(SNAME *_queue_) \
{ \
return _queue_->count == 0; \
} \
\
FMOD bool PFX##_full(SNAME *_queue_) \
{ \
return _queue_->count >= _queue_->capacity; \
} \
\
FMOD size_t PFX##_count(SNAME *_queue_) \
{ \
return _queue_->count; \
} \
\
FMOD size_t PFX##_capacity(SNAME *_queue_) \
{ \
return _queue_->capacity; \
} \
\
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
{ \
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
\
if (!iter) \
return NULL; \
\
PFX##_iter_init(iter, target); \
\
return iter; \
} \
\
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
{ \
free(iter); \
} \
\
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
{ \
iter->target = target; \
iter->cursor = target->front; \
iter->index = 0; \
iter->start = true; \
iter->end = PFX##_empty(target); \
} \
\
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
{ \
return PFX##_empty(iter->target) || iter->start; \
} \
\
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
{ \
return PFX##_empty(iter->target) || iter->end; \
} \
\
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
{ \
iter->cursor = iter->target->front; \
iter->index = 0; \
iter->start = true; \
iter->end = PFX##_empty(iter->target); \
} \
\
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
iter->cursor = 0; \
else \
iter->cursor = (iter->target->rear == 0) ? iter->target->count - 1 : iter->target->rear - 1; \
\
iter->index = iter->target->count - 1; \
iter->start = PFX##_empty(iter->target); \
iter->end = true; \
} \
\
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
{ \
if (iter->end) \
return false; \
\
iter->start = PFX##_empty(iter->target); \
\
if (iter->index == iter->target->count - 1) \
iter->end = true; \
else \
{ \
iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
iter->index++; \
} \
\
return true; \
} \
\
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
{ \
if (iter->start) \
return false; \
\
iter->end = PFX##_empty(iter->target); \
\
if (iter->index == 0) \
iter->start = true; \
else \
{ \
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
iter->index--; \
} \
\
return true; \
} \
\
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
return 0; \
\
return iter->target->buffer[iter->cursor]; \
} \
\
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
return NULL; \
\
return &(iter->target->buffer[iter->cursor]); \
} \
\
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
{ \
return iter->index; \
} \
\
FMOD bool PFX##_grow(SNAME *_queue_) \
{ \
\
size_t new_capacity = _queue_->capacity * 2; \
\
V *new_buffer = malloc(sizeof(V) * new_capacity); \
\
if (!new_buffer) \
return false; \
\
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
{ \
new_buffer[j] = _queue_->buffer[i]; \
} \
\
free(_queue_->buffer); \
\
_queue_->buffer = new_buffer; \
_queue_->capacity = new_capacity; \
_queue_->front = 0; \
_queue_->rear = _queue_->count; \
\
return true; \
} \
\
SNAME##_iter PFX##_impl_it_start(SNAME *_queue_) \
{ \
SNAME##_iter iter; \
\
PFX##_iter_init(&iter, _queue_); \
PFX##_iter_to_start(&iter); \
\
return iter; \
} \
\
SNAME##_iter PFX##_impl_it_end(SNAME *_queue_) \
{ \
SNAME##_iter iter; \
\
PFX##_iter_init(&iter, _queue_); \
PFX##_iter_to_end(&iter); \
\
return iter; \
#define QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
\
/* Implementation Detail Functions */ \
FMOD bool PFX##_grow(SNAME *_queue_); \
SNAME##_iter PFX##_impl_it_start(SNAME *_queue_); \
SNAME##_iter PFX##_impl_it_end(SNAME *_queue_); \
\
FMOD SNAME *PFX##_new(size_t size) \
{ \
if (size < 1) \
return NULL; \
\
SNAME *_queue_ = malloc(sizeof(SNAME)); \
\
if (!_queue_) \
return NULL; \
\
_queue_->buffer = malloc(sizeof(V) * size); \
\
if (!_queue_->buffer) \
{ \
free(_queue_); \
return NULL; \
} \
\
memset(_queue_->buffer, 0, sizeof(V) * size); \
\
_queue_->capacity = size; \
_queue_->count = 0; \
_queue_->front = 0; \
_queue_->rear = 0; \
\
_queue_->it_start = PFX##_impl_it_start; \
_queue_->it_end = PFX##_impl_it_end; \
\
return _queue_; \
} \
\
FMOD void PFX##_clear(SNAME *_queue_) \
{ \
memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \
\
_queue_->count = 0; \
_queue_->front = 0; \
_queue_->rear = 0; \
} \
\
FMOD void PFX##_free(SNAME *_queue_) \
{ \
free(_queue_->buffer); \
free(_queue_); \
} \
\
FMOD bool PFX##_enqueue(SNAME *_queue_, V element) \
{ \
if (PFX##_full(_queue_)) \
{ \
if (!PFX##_grow(_queue_)) \
return false; \
} \
\
_queue_->buffer[_queue_->rear] = element; \
\
_queue_->rear = (_queue_->rear == _queue_->capacity - 1) ? 0 : _queue_->rear + 1; \
_queue_->count++; \
\
return true; \
} \
\
FMOD bool PFX##_dequeue(SNAME *_queue_) \
{ \
if (PFX##_empty(_queue_)) \
return false; \
\
_queue_->buffer[_queue_->front] = 0; \
\
_queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; \
_queue_->count--; \
\
return true; \
} \
\
FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition) \
{ \
if (condition) \
return PFX##_enqueue(_queue_, element); \
\
return false; \
} \
\
FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition) \
{ \
if (condition) \
return PFX##_dequeue(_queue_); \
\
return false; \
} \
\
FMOD V PFX##_peek(SNAME *_queue_) \
{ \
if (PFX##_empty(_queue_)) \
return 0; \
\
return _queue_->buffer[_queue_->front]; \
} \
\
FMOD bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)) \
{ \
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->count, j++) \
{ \
if (comparator(_queue_->buffer[i], element) == 0) \
return true; \
} \
\
return false; \
} \
\
FMOD bool PFX##_empty(SNAME *_queue_) \
{ \
return _queue_->count == 0; \
} \
\
FMOD bool PFX##_full(SNAME *_queue_) \
{ \
return _queue_->count >= _queue_->capacity; \
} \
\
FMOD size_t PFX##_count(SNAME *_queue_) \
{ \
return _queue_->count; \
} \
\
FMOD size_t PFX##_capacity(SNAME *_queue_) \
{ \
return _queue_->capacity; \
} \
\
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
{ \
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
\
if (!iter) \
return NULL; \
\
PFX##_iter_init(iter, target); \
\
return iter; \
} \
\
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
{ \
free(iter); \
} \
\
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
{ \
iter->target = target; \
iter->cursor = target->front; \
iter->index = 0; \
iter->start = true; \
iter->end = PFX##_empty(target); \
} \
\
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
{ \
return PFX##_empty(iter->target) || iter->start; \
} \
\
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
{ \
return PFX##_empty(iter->target) || iter->end; \
} \
\
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
{ \
iter->cursor = iter->target->front; \
iter->index = 0; \
iter->start = true; \
iter->end = PFX##_empty(iter->target); \
} \
\
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
iter->cursor = 0; \
else \
iter->cursor = (iter->target->rear == 0) ? iter->target->capacity - 1 : iter->target->rear - 1; \
\
iter->index = iter->target->count - 1; \
iter->start = PFX##_empty(iter->target); \
iter->end = true; \
} \
\
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
{ \
if (iter->end) \
return false; \
\
iter->start = PFX##_empty(iter->target); \
\
if (iter->index == iter->target->count - 1) \
iter->end = true; \
else \
{ \
iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
iter->index++; \
} \
\
return true; \
} \
\
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
{ \
if (iter->start) \
return false; \
\
iter->end = PFX##_empty(iter->target); \
\
if (iter->index == 0) \
iter->start = true; \
else \
{ \
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
iter->index--; \
} \
\
return true; \
} \
\
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
return 0; \
\
return iter->target->buffer[iter->cursor]; \
} \
\
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
{ \
if (PFX##_empty(iter->target)) \
return NULL; \
\
return &(iter->target->buffer[iter->cursor]); \
} \
\
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
{ \
return iter->index; \
} \
\
FMOD bool PFX##_grow(SNAME *_queue_) \
{ \
\
size_t new_capacity = _queue_->capacity * 2; \
\
V *new_buffer = malloc(sizeof(V) * new_capacity); \
\
if (!new_buffer) \
return false; \
\
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
{ \
new_buffer[j] = _queue_->buffer[i]; \
} \
\
free(_queue_->buffer); \
\
_queue_->buffer = new_buffer; \
_queue_->capacity = new_capacity; \
_queue_->front = 0; \
_queue_->rear = _queue_->count; \
\
return true; \
} \
\
SNAME##_iter PFX##_impl_it_start(SNAME *_queue_) \
{ \
SNAME##_iter iter; \
\
PFX##_iter_init(&iter, _queue_); \
PFX##_iter_to_start(&iter); \
\
return iter; \
} \
\
SNAME##_iter PFX##_impl_it_end(SNAME *_queue_) \
{ \
SNAME##_iter iter; \
\
PFX##_iter_init(&iter, _queue_); \
PFX##_iter_to_end(&iter); \
\
return iter; \
}
#endif /* CMC_QUEUE_H */
+20
View File
@@ -150,24 +150,44 @@ int main(void)
printf("-------------------- CONTAINS --------------------\n");
if (c[0] && !a[0] && !b[0])
printf("%10s PASSED\n", "DEQUE");
else
printf("%10s FAILED\n", "DEQUE");
if (c[1] && !a[1] && !b[1])
printf("%10s PASSED\n", "HASHMAP");
else
printf("%10s FAILED\n", "HASHMAP");
if (c[2] && !a[2] && !b[2])
printf("%10s PASSED\n", "HASHSET");
else
printf("%10s FAILED\n", "HASHSET");
if (c[3] && !a[3] && !b[3])
printf("%10s PASSED\n", "HEAP");
else
printf("%10s FAILED\n", "HEAP");
if (c[4] && !a[4] && !b[4])
printf("%10s PASSED\n", "LINKEDLIST");
else
printf("%10s FAILED\n", "LINKEDLIST");
if (c[5] && !a[5] && !b[5])
printf("%10s PASSED\n", "LIST");
else
printf("%10s FAILED\n", "LIST");
if (c[6] && !a[6] && !b[6])
printf("%10s PASSED\n", "QUEUE");
else
printf("%10s FAILED\n", "QUEUE");
if (c[7] && !a[7] && !b[7])
printf("%10s PASSED\n", "STACK");
else
printf("%10s FAILED\n", "STACK");
if (c[8] && !a[8] && !b[8])
printf("%10s PASSED\n", "TREEMAP");
else
printf("%10s FAILED\n", "TREEMAP");
if (c[9] && !a[9] && !b[9])
printf("%10s PASSED\n", "TREESET");
else
printf("%10s FAILED\n", "TREESET");
l_free(l);
ll_free(ll);
+86 -46
View File
@@ -70,138 +70,178 @@ int main(void)
int sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, sum6 = 0,
sum7 = 0, sum8 = 0, sum9 = 0, sum10 = 0, sum11 = 0;
FOR_EACH(l, list, int, l, {
sum0 += value;
FOR_EACH(d, deque, d, {
sum3 += d_iter_value(&iter);
})
FOR_EACH(s, stack, int, s, {
sum1 += value;
FOR_EACH(hm, hmap, hm, {
sum10 += hm_iter_key(&iter);
sum11 += hm_iter_value(&iter);
})
FOR_EACH(q, queue, int, q, {
sum2 += value;
FOR_EACH(hs, hset, hs, {
sum9 += hs_iter_value(&iter);
})
FOR_EACH(d, deque, int, d, {
sum3 += value;
FOR_EACH(h, heap, h, {
sum5 += h_iter_value(&iter);
})
FOR_EACH(ll, linked, int, ll, {
sum4 += value;
FOR_EACH(ll, linked, ll, {
sum4 += ll_iter_value(&iter);
})
FOR_EACH(h, heap, int, h, {
sum5 += value;
FOR_EACH(l, list, l, {
sum0 += l_iter_value(&iter);
})
FOR_EACH(ts, tset, int, ts, {
sum6 += value;
FOR_EACH(q, queue, q, {
sum2 += q_iter_value(&iter);
})
FOR_EACH_MAP(tm, tmap, int, int, tm, {
sum7 += key;
sum8 += value;
FOR_EACH(s, stack, s, {
sum1 += s_iter_value(&iter);
})
FOR_EACH(hs, hset, int, hs, {
sum9 += value;
FOR_EACH(tm, tmap, tm, {
sum7 += tm_iter_key(&iter);
sum8 += tm_iter_value(&iter);
})
FOR_EACH_MAP(hm, hmap, int, int, hm, {
sum10 += key;
sum11 += value;
FOR_EACH(ts, tset, ts, {
sum6 += ts_iter_value(&iter);
})
printf("\n-------------------- FOR_EACH --------------------\n");
if (sum3 == 50005000)
printf("%10s PASSED\n", "DEQUE");
else
printf("%10s FAILED\n", "DEQUE");
if (sum9 == 50005000)
printf("%10s PASSED\n", "HASHSET");
else
printf("%10s FAILED\n", "HASHSET");
if (sum10 == 50005000 && sum11 == 50005000)
printf("%10s PASSED\n", "HASHMAP");
else
printf("%10s FAILED\n", "HASHMAP");
if (sum5 == 50005000)
printf("%10s PASSED\n", "HEAP");
else
printf("%10s FAILED\n", "HEAP");
if (sum4 == 50005000)
printf("%10s PASSED\n", "LINKEDLIST");
else
printf("%10s FAILED\n", "LINKEDLIST");
if (sum0 == 50005000)
printf("%10s PASSED\n", "LIST");
else
printf("%10s FAILED\n", "LIST");
if (sum2 == 50005000)
printf("%10s PASSED\n", "QUEUE");
else
printf("%10s FAILED\n", "QUEUE");
if (sum1 == 50005000)
printf("%10s PASSED\n", "STACK");
else
printf("%10s FAILED\n", "STACK");
if (sum7 == 50005000 && sum8 == 50005000)
printf("%10s PASSED\n", "TREEMAP");
else
printf("%10s FAILED\n", "TREEMAP");
if (sum6 == 50005000)
printf("%10s PASSED\n", "TREESET");
else
printf("%10s FAILED\n", "TREESET");
printf("\n\n");
sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, sum6 = 0,
sum7 = 0, sum8 = 0, sum9 = 0, sum10 = 0, sum11 = 0;
FOR_EACH_REV(l, list, int, l, {
sum0 += value;
FOR_EACH_REV(d, deque, d, {
sum3 += d_iter_value(&iter);
})
FOR_EACH_REV(s, stack, int, s, {
sum1 += value;
FOR_EACH_REV(hm, hmap, hm, {
sum10 += hm_iter_key(&iter);
sum11 += hm_iter_value(&iter);
})
FOR_EACH_REV(q, queue, int, q, {
sum2 += value;
FOR_EACH_REV(hs, hset, hs, {
sum9 += hs_iter_value(&iter);
})
FOR_EACH_REV(d, deque, int, d, {
sum3 += value;
FOR_EACH_REV(h, heap, h, {
sum5 += h_iter_value(&iter);
})
FOR_EACH_REV(ll, linked, int, ll, {
sum4 += value;
FOR_EACH_REV(ll, linked, ll, {
sum4 += ll_iter_value(&iter);
})
FOR_EACH_REV(h, heap, int, h, {
sum5 += value;
FOR_EACH_REV(l, list, l, {
sum0 += l_iter_value(&iter);
})
FOR_EACH_REV(ts, tset, int, ts, {
sum6 += value;
FOR_EACH_REV(q, queue, q, {
sum2 += q_iter_value(&iter);
})
FOR_EACH_MAP_REV(tm, tmap, int, int, tm, {
sum7 += key;
sum8 += value;
FOR_EACH_REV(s, stack, s, {
sum1 += s_iter_value(&iter);
})
FOR_EACH_REV(hs, hset, int, hs, {
sum9 += value;
FOR_EACH_REV(tm, tmap, tm, {
sum7 += tm_iter_key(&iter);
sum8 += tm_iter_value(&iter);
})
FOR_EACH_MAP_REV(tm, tmap, int, int, tm, {
sum10 += key;
sum11 += value;
FOR_EACH_REV(ts, tset, ts, {
sum6 += ts_iter_value(&iter);
})
printf("-------------------- FOR_EACH_REV --------------------\n");
if (sum3 == 50005000)
printf("%10s PASSED\n", "DEQUE");
if (sum9 == 50005000)
printf("%10s PASSED\n", "HASHSET");
else
printf("%10s FAILED\n", "DEQUE");
if (sum10 == 50005000 && sum11 == 50005000)
printf("%10s PASSED\n", "HASHMAP");
else
printf("%10s FAILED\n", "HASHMAP");
if (sum9 == 50005000)
printf("%10s PASSED\n", "HASHSET");
else
printf("%10s FAILED\n", "HASHSET");
if (sum5 == 50005000)
printf("%10s PASSED\n", "HEAP");
else
printf("%10s FAILED\n", "HEAP");
if (sum4 == 50005000)
printf("%10s PASSED\n", "LINKEDLIST");
else
printf("%10s FAILED\n", "LINKEDLIST");
if (sum0 == 50005000)
printf("%10s PASSED\n", "LIST");
else
printf("%10s FAILED\n", "LIST");
if (sum2 == 50005000)
printf("%10s PASSED\n", "QUEUE");
else
printf("%10s FAILED\n", "QUEUE");
if (sum1 == 50005000)
printf("%10s PASSED\n", "STACK");
else
printf("%10s FAILED\n", "STACK");
if (sum7 == 50005000 && sum8 == 50005000)
printf("%10s PASSED\n", "TREEMAP");
else
printf("%10s FAILED\n", "TREEMAP");
if (sum6 == 50005000)
printf("%10s PASSED\n", "TREESET");
else
printf("%10s FAILED\n", "TREESET");
l_free(l);
ll_free(ll);
+65 -439
View File
@@ -30,451 +30,77 @@ COLLECTION_GENERATE(TREEMAP, PUBLIC, tm, tmap, /* FMOD */, int, double)
COLLECTION_GENERATE(HASHSET, PUBLIC, hs, hset, /* FMOD */, /* K */, int)
COLLECTION_GENERATE(HASHMAP, PUBLIC, hm, hmap, /* FMOD */, int, double)
void deque_iter_test(void)
{
size_t i;
int r, sum = 0;
// Initialize deque and add some elements
deque *d = d_new(10);
for (int i = 0; i < 10; i++)
{
i % 2 == 0 ? d_push_back(d, i) : d_push_front(d, i);
#define ITERATOR_TEST(NAME, PFX, sname, initfunc, insertbody, sumbody, validation1, validation2) \
void NAME##_iterator_test(void) \
{ \
int sum1 = 0; \
double sum2 = 0.0; \
\
sname *coll = initfunc; \
for (int i = 0; i < 10; i++) \
{ \
insertbody; \
} \
\
sname##_iter iter; \
PFX##_iter_init(&iter, coll); \
\
for (int j = 0; j < 4; j++) \
{ \
while (!PFX##_iter_end(&iter)) \
{ \
sumbody; \
PFX##_iter_next(&iter); \
} \
while (!PFX##_iter_start(&iter)) \
{ \
sumbody; \
PFX##_iter_prev(&iter); \
} \
} \
\
for (PFX##_iter_to_start(&iter); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
{ \
sumbody; \
} \
\
for (PFX##_iter_to_end(&iter); !PFX##_iter_start(&iter); PFX##_iter_prev(&iter)) \
{ \
sumbody; \
} \
\
PFX##_free(coll); \
\
if (validation1 && validation2) \
printf("%10s PASSED\n", #NAME); \
else \
printf("%10s FAILED\n", #NAME); \
}
// Initialize iterator
deque_iter iter;
d_iter_init(&iter, d);
// Make the iterator go back and forward
for (int j = 0; j < 4; j++)
{
while (d_iter_next(&iter, &r, &i))
sum += r;
while (d_iter_prev(&iter, &r, &i))
sum += r;
}
for (d_iter_tostart(&iter); !d_iter_end(&iter); /**/)
{
d_iter_next(&iter, &r, &i);
sum += r;
}
for (d_iter_toend(&iter); !d_iter_start(&iter); /**/)
{
d_iter_prev(&iter, &r, &i);
sum += r;
}
d_free(d);
if (sum == 450)
printf("%10s PASSED\n", "DEQUE");
}
void hashmap_iter_test(void)
{
size_t i;
int k, sum = 0;
double dsum = 0.0, v, varr[10] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9};
// Initialize hashmap and add some element
hmap *hm = hm_new(50, 0.9, intcmp, inthash);
for (int i = 0; i < 10; i++)
hm_insert(hm, i, varr[i]);
// Initialize iterator
hmap_iter iter;
hm_iter_init(&iter, hm);
// Make the iterator go back and forward
for (int j = 0; j < 4; j++)
{
while (hm_iter_next(&iter, &k, &v, &i))
{
sum += k;
dsum += v;
}
while (hm_iter_prev(&iter, &k, &v, &i))
{
sum += k;
dsum += v;
}
}
for (hm_iter_tostart(&iter); !hm_iter_end(&iter); /**/)
{
hm_iter_next(&iter, &k, &v, &i);
sum += k;
dsum += v;
}
for (hm_iter_toend(&iter); !hm_iter_start(&iter); /**/)
{
hm_iter_prev(&iter, &k, &v, &i);
{
sum += k;
dsum += v;
}
}
hm_free(hm);
if (sum == 450 && dsum == 45.0)
printf("%10s PASSED\n", "HASHMAP");
}
void hashset_iter_test(void)
{
size_t i;
int r, sum = 0;
// Initialize hash set and add some elements
hset *hs = hs_new(10, 0.9, intcmp, inthash);
for (int i = 0; i < 10; i++)
hs_insert(hs, i);
// Initialize iterator
hset_iter iter;
hs_iter_init(&iter, hs);
// Make the iterator go back and forward
for (int j = 0; j < 4; j++)
{
while (hs_iter_next(&iter, &r, &i))
sum += r;
while (hs_iter_prev(&iter, &r, &i))
sum += r;
}
for (hs_iter_tostart(&iter); !hs_iter_end(&iter); /**/)
{
hs_iter_next(&iter, &r, &i);
sum += r;
}
for (hs_iter_toend(&iter); !hs_iter_start(&iter); /**/)
{
hs_iter_prev(&iter, &r, &i);
sum += r;
}
hs_free(hs);
if (sum == 450)
printf("%10s PASSED\n", "HASHSET");
}
void heap_iter_test(void)
{
size_t i;
int r, sum = 0;
// Initialize heap and add some elements
heap *h = h_new(10, MinHeap, intcmp);
for (int i = 9; i >= 0; i--)
h_insert(h, i);
// Initialize iterator
heap_iter iter;
h_iter_init(&iter, h);
// Make the iterator go back and forward
for (int j = 0; j < 4; j++)
{
while (h_iter_next(&iter, &r, &i))
sum += r;
while (h_iter_prev(&iter, &r, &i))
sum += r;
}
for (h_iter_tostart(&iter); !h_iter_end(&iter); /**/)
{
h_iter_next(&iter, &r, &i);
sum += r;
}
for (h_iter_toend(&iter); !h_iter_start(&iter); /**/)
{
h_iter_prev(&iter, &r, &i);
sum += r;
}
h_free(h);
if (sum == 450)
printf("%10s PASSED\n", "HEAP");
}
void linkedlist_iter_test(void)
{
size_t i;
int r, sum = 0;
// Initialize linked list and add some elements
linked *ll = ll_new();
for (int i = 0; i < 10; i++)
ll_push_back(ll, i);
// Initialize iterator
linked_iter iter;
ll_iter_init(&iter, ll);
// Make the iterator go back and forward
for (int j = 0; j < 4; j++)
{
while (ll_iter_next(&iter, &r, &i))
sum += r;
while (ll_iter_prev(&iter, &r, &i))
sum += r;
}
for (ll_iter_tostart(&iter); !ll_iter_end(&iter); /**/)
{
ll_iter_next(&iter, &r, &i);
sum += r;
}
for (ll_iter_toend(&iter); !ll_iter_start(&iter); /**/)
{
ll_iter_prev(&iter, &r, &i);
sum += r;
}
ll_free(ll);
if (sum == 450)
printf("%10s PASSED\n", "LINKEDLIST");
}
void list_iter_test(void)
{
size_t i;
int r, sum = 0;
// Initialize list and add some elements
list *l = l_new(10);
for (int i = 0; i < 10; i++)
l_push_back(l, i);
// Initialize iterator
list_iter iter;
l_iter_init(&iter, l);
// Make the iterator go back and forward
for (int j = 0; j < 4; j++)
{
while (l_iter_next(&iter, &r, &i))
sum += r;
while (l_iter_prev(&iter, &r, &i))
sum += r;
}
for (l_iter_tostart(&iter); !l_iter_end(&iter); /**/)
{
l_iter_next(&iter, &r, &i);
sum += r;
}
for (l_iter_toend(&iter); !l_iter_start(&iter); /**/)
{
l_iter_prev(&iter, &r, &i);
sum += r;
}
l_free(l);
if (sum == 450)
printf("%10s PASSED\n", "LIST");
}
void queue_iter_test(void)
{
size_t i;
int r, sum = 0;
// Initialize queue and add some elements
queue *q = q_new(10);
for (int i = 0; i < 10; i++)
q_enqueue(q, i);
// Initialize iterator
queue_iter iter;
q_iter_init(&iter, q);
// Make the iterator go back and forward
for (int j = 0; j < 4; j++)
{
while (q_iter_next(&iter, &r, &i))
sum += r;
while (q_iter_prev(&iter, &r, &i))
sum += r;
}
for (q_iter_tostart(&iter); !q_iter_end(&iter); /**/)
{
q_iter_next(&iter, &r, &i);
sum += r;
}
for (q_iter_toend(&iter); !q_iter_start(&iter); /**/)
{
q_iter_prev(&iter, &r, &i);
sum += r;
}
q_free(q);
if (sum == 450)
printf("%10s PASSED\n", "QUEUE");
}
void stack_iter_test(void)
{
size_t i;
int r, sum = 0;
// Initialize stack and add some elements
stack *s = s_new(10);
for (int i = 0; i < 10; i++)
s_push(s, i);
// Initialize iterator
stack_iter iter;
s_iter_init(&iter, s);
// Make the iterator go back and forward
for (int j = 0; j < 4; j++)
{
while (s_iter_next(&iter, &r, &i))
sum += r;
while (s_iter_prev(&iter, &r, &i))
sum += r;
}
for (s_iter_tostart(&iter); !s_iter_end(&iter); /**/)
{
s_iter_next(&iter, &r, &i);
sum += r;
}
for (s_iter_toend(&iter); !s_iter_start(&iter); /**/)
{
s_iter_prev(&iter, &r, &i);
sum += r;
}
s_free(s);
if (sum == 450)
printf("%10s PASSED\n", "STACK");
}
void treemap_iter_test(void)
{
size_t i;
int k, sum = 0;
double dsum = 0, v, varr[10] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9};
// Initialize treemap and add some element
tmap *tm = tm_new(intcmp);
for (int i = 0; i < 10; i++)
tm_insert(tm, i, varr[i]);
// Initialize iterator
tmap_iter iter;
tm_iter_init(&iter, tm);
// Make the iterator go back and forward
for (int j = 0; j < 4; j++)
{
while (tm_iter_next(&iter, &k, &v, &i))
{
sum += k;
dsum += v;
}
while (tm_iter_prev(&iter, &k, &v, &i))
{
sum += k;
dsum += v;
}
}
for (tm_iter_tostart(&iter); !tm_iter_end(&iter); /**/)
{
tm_iter_next(&iter, &k, &v, &i);
sum += k;
dsum += v;
}
for (tm_iter_toend(&iter); !tm_iter_start(&iter); /**/)
{
tm_iter_prev(&iter, &k, &v, &i);
sum += k;
dsum += v;
}
tm_free(tm);
if (sum == 450 && dsum == 45.0)
printf("%10s PASSED\n", "TREEMAP");
}
void treeset_iter_test(void)
{
size_t i;
int r, sum = 0;
// Initialize treeset and add some elements
tset *ts = ts_new(intcmp);
for (int i = 0; i < 10; i++)
ts_insert(ts, i);
// Initialize iterator
tset_iter iter;
ts_iter_init(&iter, ts);
// Make the iterator go back and forward
for (int j = 0; j < 4; j++)
{
while (ts_iter_next(&iter, &r, &i))
sum += r;
while (ts_iter_prev(&iter, &r, &i))
sum += r;
}
for (ts_iter_tostart(&iter); !ts_iter_end(&iter); /**/)
{
ts_iter_next(&iter, &r, &i);
sum += r;
}
for (ts_iter_toend(&iter); !ts_iter_start(&iter); /**/)
{
ts_iter_prev(&iter, &r, &i);
sum += r;
}
ts_free(ts);
if (sum == 450)
printf("%10s PASSED\n", "TREESET");
}
ITERATOR_TEST(DEQUE, d, deque, d_new(20), d_push_front(coll, i), sum1 += d_iter_value(&iter), sum1 == 450, 1)
ITERATOR_TEST(HASHMAP, hm, hmap, hm_new(50, 0.6, intcmp, inthash), hm_insert(coll, i, (double)i / 10.0), sum1 += hm_iter_key(&iter); sum2 += hm_iter_value(&iter), sum1 == 450, sum2 == 45.0)
ITERATOR_TEST(HASHSET, hs, hset, hs_new(50, 0.6, intcmp, inthash), hs_insert(coll, i), sum1 += hs_iter_value(&iter), sum1 == 450, 1)
ITERATOR_TEST(HEAP, h, heap, h_new(20, MaxHeap, intcmp), h_insert(coll, i), sum1 += h_iter_value(&iter), sum1 == 450, 1)
ITERATOR_TEST(LINKEDLIST, ll, linked, ll_new(), ll_push_back(coll, i), sum1 += ll_iter_value(&iter), sum1 == 450, 1)
ITERATOR_TEST(LIST, l, list, l_new(20), l_push_back(coll, i), sum1 += l_iter_value(&iter), sum1 == 450, 1)
ITERATOR_TEST(QUEUE, q, queue, q_new(20), q_enqueue(coll, i), sum1 += q_iter_value(&iter), sum1 == 450, 1)
ITERATOR_TEST(STACK, s, stack, s_new(20), s_push(coll, i), sum1 += s_iter_value(&iter), sum1 == 450, 1)
ITERATOR_TEST(TREEMAP, tm, tmap, tm_new(intcmp), tm_insert(coll, i, (double)i / 10.0), sum1 += tm_iter_key(&iter); sum2 += tm_iter_value(&iter), sum1 == 450, sum2 == 45.0)
ITERATOR_TEST(TREESET, ts, tset, ts_new(intcmp), ts_insert(coll, i), sum1 += ts_iter_value(&iter), sum1 == 450, 1)
int main(void)
{
printf("\n-------------------- ITERATORS --------------------\n");
deque_iter_test();
hashmap_iter_test();
hashset_iter_test();
heap_iter_test();
linkedlist_iter_test();
list_iter_test();
queue_iter_test();
stack_iter_test();
treemap_iter_test();
treeset_iter_test();
DEQUE_iterator_test();
HASHMAP_iterator_test();
HASHSET_iterator_test();
HEAP_iterator_test();
LINKEDLIST_iterator_test();
LIST_iterator_test();
QUEUE_iterator_test();
STACK_iterator_test();
TREEMAP_iterator_test();
TREESET_iterator_test();
return 0;
}