diff --git a/benchmarks/benchmark.c b/benchmarks/benchmark.c index 32c8fac..1fcd345 100644 --- a/benchmarks/benchmark.c +++ b/benchmarks/benchmark.c @@ -13,7 +13,7 @@ * - Output */ #include "macro_collections.h" -#include "timer.h" +#include "util/timer.h" #include "util/twister.c" #include #include @@ -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) { diff --git a/benchmarks/timer.h b/benchmarks/util/timer.h similarity index 100% rename from benchmarks/timer.h rename to benchmarks/util/timer.h diff --git a/src/deque.h b/src/deque.h index f769988..4b4384e 100644 --- a/src/deque.h +++ b/src/deque.h @@ -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 */ diff --git a/src/foreach.h b/src/foreach.h index 42d9285..0f582b9 100644 --- a/src/foreach.h +++ b/src/foreach.h @@ -11,63 +11,22 @@ #ifndef CMC_FOR_EACH #define CMC_FOR_EACH -#include -#include - -#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 */ \ No newline at end of file +#endif /* CMC_FOR_EACH */ diff --git a/src/queue.h b/src/queue.h index ba68358..d5a300b 100644 --- a/src/queue.h +++ b/src/queue.h @@ -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 */ diff --git a/tests/contains.c b/tests/contains.c index 7d1cb44..54b49f8 100644 --- a/tests/contains.c +++ b/tests/contains.c @@ -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); diff --git a/tests/foreach.c b/tests/foreach.c index 4c11540..5a7b93b 100644 --- a/tests/foreach.c +++ b/tests/foreach.c @@ -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); diff --git a/tests/iterators.c b/tests/iterators.c index aab3b40..4173107 100644 --- a/tests/iterators.c +++ b/tests/iterators.c @@ -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; }