Added cmc prefixes to enums used by heap and hashtables and fixed return type on treeset and hashset
This commit is contained in:
1 parent
0c883b0a74
commit
354cd538f8
13 files changed
+172
-164
No files matched your search
@@ -174,7 +174,7 @@ COLLECTION_GENERATE(HASHMAP, hm, hmap, /* FMOD */, int, int)
|
||||
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(HEAP, h, heap, h_new(NTOTAL, cmc_min_heap, 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))
|
||||
|
||||
@@ -19,7 +19,7 @@ HEAP_GENERATE(h, heap, static, int)
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
heap *h = h_new(32, MaxHeap, intcmp);
|
||||
heap *h = h_new(32, cmc_max_heap, intcmp);
|
||||
|
||||
for (int i = 1; i < 101; i++)
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@ HEAP_GENERATE(h, heap, /* FMOD */, int)
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
// Create a new max heap with an initial capacity of 100
|
||||
heap *my_heap = h_new(100, MaxHeap, intcmp);
|
||||
heap *my_heap = h_new(100, cmc_max_heap, intcmp);
|
||||
|
||||
// Add elements to the heap
|
||||
for (int i = 0; i < 20; i++)
|
||||
|
||||
@@ -218,7 +218,7 @@ int main(int argc, char const *argv[])
|
||||
}
|
||||
|
||||
/* Sorting using a Heap */
|
||||
Heap *sort = hp_new(hm_count(result), MaxHeap, cmp_wcpair);
|
||||
Heap *sort = hp_new(hm_count(result), cmc_max_heap, cmp_wcpair);
|
||||
|
||||
/* Add key-value pairs to Heap for sorting */
|
||||
for (HashMap_iter iter = result->it_start(result);
|
||||
|
||||
+21
-19
@@ -8,9 +8,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************************************************* HASHMAP */
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* A HashMap is an implementation of a Map with unique keys, where every key is
|
||||
* mapped to a value. The keys are not sorted. It is implemented as a hashtable
|
||||
* with robin hood hashing.
|
||||
*/
|
||||
|
||||
#ifndef CMC_HASHMAP_H
|
||||
#define CMC_HASHMAP_H
|
||||
@@ -22,12 +24,12 @@
|
||||
#ifndef CMC_HASH_TABLE_SETUP
|
||||
#define CMC_HASH_TABLE_SETUP
|
||||
|
||||
typedef enum EntryState_e
|
||||
typedef enum cmc_entry_state_e
|
||||
{
|
||||
ES_DELETED = -1,
|
||||
ES_EMPTY = 0,
|
||||
ES_FILLED = 1
|
||||
} EntryState;
|
||||
CMC_ES_DELETED = -1,
|
||||
CMC_ES_EMPTY = 0,
|
||||
CMC_ES_FILLED = 1
|
||||
} cmc_entry_state;
|
||||
|
||||
static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
3067, 6143, 12289, 24571, 49157,
|
||||
@@ -118,7 +120,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
size_t dist; \
|
||||
\
|
||||
/* The sate of this node (DELETED, EMPTY, FILLED) */ \
|
||||
enum EntryState_e state; \
|
||||
enum cmc_entry_state_e state; \
|
||||
\
|
||||
} SNAME##_entry, *SNAME##_entry_ptr; \
|
||||
\
|
||||
@@ -284,12 +286,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
if (PFX##_impl_get_entry(_map_, key) != NULL) \
|
||||
return false; \
|
||||
\
|
||||
if (target->state == ES_EMPTY || target->state == ES_DELETED) \
|
||||
if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
|
||||
{ \
|
||||
target->key = key; \
|
||||
target->value = value; \
|
||||
target->dist = original_pos - pos; \
|
||||
target->state = ES_FILLED; \
|
||||
target->state = CMC_ES_FILLED; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
@@ -298,12 +300,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
pos++; \
|
||||
target = &(_map_->buffer[pos % _map_->capacity]); \
|
||||
\
|
||||
if (target->state == ES_EMPTY || target->state == ES_DELETED) \
|
||||
if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
|
||||
{ \
|
||||
target->key = key; \
|
||||
target->value = value; \
|
||||
target->dist = pos - original_pos; \
|
||||
target->state = ES_FILLED; \
|
||||
target->state = CMC_ES_FILLED; \
|
||||
\
|
||||
break; \
|
||||
} \
|
||||
@@ -341,7 +343,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
result->key = PFX##_impl_default_key(); \
|
||||
result->value = PFX##_impl_default_value(); \
|
||||
result->dist = 0; \
|
||||
result->state = ES_DELETED; \
|
||||
result->state = CMC_ES_DELETED; \
|
||||
\
|
||||
_map_->count--; \
|
||||
\
|
||||
@@ -489,7 +491,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
{ \
|
||||
for (size_t i = 0; i < target->capacity; i++) \
|
||||
{ \
|
||||
if (target->buffer[i].state == ES_FILLED) \
|
||||
if (target->buffer[i].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter->first = i; \
|
||||
break; \
|
||||
@@ -500,7 +502,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
for (size_t i = target->capacity; i > 0; i--) \
|
||||
{ \
|
||||
if (target->buffer[i - 1].state == ES_FILLED) \
|
||||
if (target->buffer[i - 1].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter->last = i - 1; \
|
||||
break; \
|
||||
@@ -556,7 +558,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
iter->cursor++; \
|
||||
scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (scan->state == ES_FILLED) \
|
||||
if (scan->state == CMC_ES_FILLED) \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
@@ -586,7 +588,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
iter->cursor--; \
|
||||
scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (scan->state == ES_FILLED) \
|
||||
if (scan->state == CMC_ES_FILLED) \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
@@ -667,7 +669,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
SNAME##_entry *target = &(_map_->buffer[pos]); \
|
||||
\
|
||||
while (target->state == ES_FILLED || target->state == ES_DELETED) \
|
||||
while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \
|
||||
{ \
|
||||
if (_map_->cmp(target->key, key) == 0) \
|
||||
return target; \
|
||||
|
||||
+24
-23
@@ -8,9 +8,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************************************************* HASHSET */
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* A HashSet is an implementation of a Set with unique keys. The keys are not
|
||||
* sorted. It is implemented as a hashtable with robin hood hashing.
|
||||
*/
|
||||
|
||||
#ifndef CMC_HASHSET_H
|
||||
#define CMC_HASHSET_H
|
||||
@@ -22,12 +23,12 @@
|
||||
#ifndef CMC_HASH_TABLE_SETUP
|
||||
#define CMC_HASH_TABLE_SETUP
|
||||
|
||||
typedef enum EntryState_e
|
||||
typedef enum cmc_entry_state_e
|
||||
{
|
||||
ES_DELETED = -1,
|
||||
ES_EMPTY = 0,
|
||||
ES_FILLED = 1
|
||||
} EntryState;
|
||||
CMC_ES_DELETED = -1,
|
||||
CMC_ES_EMPTY = 0,
|
||||
CMC_ES_FILLED = 1
|
||||
} cmc_entry_state;
|
||||
|
||||
static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
3067, 6143, 12289, 24571, 49157,
|
||||
@@ -114,7 +115,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
size_t dist; \
|
||||
\
|
||||
/* The sate of this node (DELETED, EMPTY, FILLED) */ \
|
||||
enum EntryState_e state; \
|
||||
enum cmc_entry_state_e state; \
|
||||
\
|
||||
} SNAME##_entry, *SNAME##_entry_ptr; \
|
||||
\
|
||||
@@ -277,11 +278,11 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
if (PFX##_impl_get_entry(_set_, element) != NULL) \
|
||||
return false; \
|
||||
\
|
||||
if (target->state == ES_EMPTY || target->state == ES_DELETED) \
|
||||
if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
|
||||
{ \
|
||||
target->value = element; \
|
||||
target->dist = pos - original_pos; \
|
||||
target->state = ES_FILLED; \
|
||||
target->state = CMC_ES_FILLED; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
@@ -290,11 +291,11 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
pos++; \
|
||||
target = &(_set_->buffer[pos % _set_->capacity]); \
|
||||
\
|
||||
if (target->state == ES_EMPTY || target->state == ES_DELETED) \
|
||||
if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
|
||||
{ \
|
||||
target->value = element; \
|
||||
target->dist = pos - original_pos; \
|
||||
target->state = ES_FILLED; \
|
||||
target->state = CMC_ES_FILLED; \
|
||||
\
|
||||
break; \
|
||||
} \
|
||||
@@ -326,7 +327,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
result->value = PFX##_impl_default_value(); \
|
||||
result->dist = 0; \
|
||||
result->state = ES_DELETED; \
|
||||
result->state = CMC_ES_DELETED; \
|
||||
\
|
||||
_set_->count--; \
|
||||
\
|
||||
@@ -416,7 +417,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return false; \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter1, iter2; \
|
||||
PFX##_iter_init(&iter1, _set1_); \
|
||||
@@ -440,7 +441,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return false; \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \
|
||||
SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
|
||||
@@ -464,7 +465,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return false; \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
@@ -487,7 +488,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return false; \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(&iter1, _set1_); \
|
||||
PFX##_iter_init(&iter2, _set2_); \
|
||||
@@ -644,7 +645,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
{ \
|
||||
for (size_t i = 0; i < target->capacity; i++) \
|
||||
{ \
|
||||
if (target->buffer[i].state == ES_FILLED) \
|
||||
if (target->buffer[i].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter->first = i; \
|
||||
break; \
|
||||
@@ -655,7 +656,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
for (size_t i = target->capacity; i > 0; i--) \
|
||||
{ \
|
||||
if (target->buffer[i - 1].state == ES_FILLED) \
|
||||
if (target->buffer[i - 1].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter->last = i - 1; \
|
||||
break; \
|
||||
@@ -708,7 +709,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
iter->cursor++; \
|
||||
scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (scan->state == ES_FILLED) \
|
||||
if (scan->state == CMC_ES_FILLED) \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
@@ -736,7 +737,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
iter->cursor--; \
|
||||
scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (scan->state == ES_FILLED) \
|
||||
if (scan->state == CMC_ES_FILLED) \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
@@ -800,7 +801,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
SNAME##_entry *target = &(_set_->buffer[pos]); \
|
||||
\
|
||||
while (target->state == ES_FILLED || target->state == ES_DELETED) \
|
||||
while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \
|
||||
{ \
|
||||
if (_set_->cmp(target->value, element) == 0) \
|
||||
return target; \
|
||||
|
||||
+100
-100
@@ -19,11 +19,11 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef enum HeapOrder
|
||||
typedef enum cmc_heap_order_e
|
||||
{
|
||||
MaxHeap = 1,
|
||||
MinHeap = -1
|
||||
} HeapOrder;
|
||||
cmc_max_heap = 1,
|
||||
cmc_min_heap = -1
|
||||
} cmc_heap_order;
|
||||
|
||||
#define HEAP_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
HEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
@@ -36,100 +36,100 @@ typedef enum HeapOrder
|
||||
HEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define HEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Heap Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Dynamic array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements in the heap */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Heap order (MaxHeap or MinHeap) */ \
|
||||
enum HeapOrder HO; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the heap */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the heap */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Heap Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target heap */ \
|
||||
struct SNAME##_s *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* If the iterator has reached the start of the iteration */ \
|
||||
bool start; \
|
||||
\
|
||||
/* If the iterator has reached the end of the iteration */ \
|
||||
bool end; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, HeapOrder HO, int (*compare)(V, V)); \
|
||||
FMOD void PFX##_clear(SNAME *_heap_); \
|
||||
FMOD void PFX##_free(SNAME *_heap_); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_remove(SNAME *_heap_, V *result); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_peek(SNAME *_heap_); \
|
||||
FMOD V *PFX##_peek_ref(SNAME *_heap_); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_empty(SNAME *_heap_); \
|
||||
FMOD bool PFX##_full(SNAME *_heap_); \
|
||||
FMOD size_t PFX##_count(SNAME *_heap_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_heap_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
/* Iterator Access */ \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
#define HEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Heap Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Dynamic array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements in the heap */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Heap order (MaxHeap or MinHeap) */ \
|
||||
enum cmc_heap_order_e HO; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the heap */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the heap */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Heap Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target heap */ \
|
||||
struct SNAME##_s *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* If the iterator has reached the start of the iteration */ \
|
||||
bool start; \
|
||||
\
|
||||
/* If the iterator has reached the end of the iteration */ \
|
||||
bool end; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)); \
|
||||
FMOD void PFX##_clear(SNAME *_heap_); \
|
||||
FMOD void PFX##_free(SNAME *_heap_); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_remove(SNAME *_heap_, V *result); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_peek(SNAME *_heap_); \
|
||||
FMOD V *PFX##_peek_ref(SNAME *_heap_); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_empty(SNAME *_heap_); \
|
||||
FMOD bool PFX##_full(SNAME *_heap_); \
|
||||
FMOD size_t PFX##_count(SNAME *_heap_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_heap_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
/* Iterator Access */ \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define HEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
@@ -140,12 +140,12 @@ typedef enum HeapOrder
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_heap_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_heap_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity, HeapOrder HO, int (*compare)(V, V)) \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
if (HO != MinHeap && HO != MaxHeap) \
|
||||
if (HO != cmc_min_heap && HO != cmc_max_heap) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_heap_ = malloc(sizeof(SNAME)); \
|
||||
|
||||
+7
-5
@@ -8,9 +8,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************************************************* TREEMAP */
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* A TreeMap is an implementation of a Map that keeps its keys sorted. Like a
|
||||
* Map, it has only unique keys. This implementation uses a balanced binary
|
||||
* tree called AVL Tree that uses the height of nodes to keep its keys balanced.
|
||||
*/
|
||||
|
||||
#ifndef CMC_TREEMAP_H
|
||||
#define CMC_TREEMAP_H
|
||||
@@ -44,10 +46,10 @@
|
||||
/* Key comparison function */ \
|
||||
int (*cmp)(K, K); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the hashmap */ \
|
||||
/* Function that returns an iterator to the start of the treemap */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the hashmap */ \
|
||||
/* Function that returns an iterator to the end of the treemap */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
|
||||
+12
-9
@@ -8,9 +8,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************************************************* TREESET */
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* A TreeSet is an implementation of a Set that keeps its elements sorted. Like
|
||||
* a Set it has only unique keys. This implementation uses a balanced binary
|
||||
* tree called AVL Tree that uses the height of nodes to keep its keys balanced.
|
||||
*/
|
||||
|
||||
#ifndef CMC_TREESET_H
|
||||
#define CMC_TREESET_H
|
||||
@@ -44,10 +46,10 @@
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the hashset */ \
|
||||
/* Function that returns an iterator to the start of the treeset */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the hashset */ \
|
||||
/* Function that returns an iterator to the end of the treeset */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
@@ -95,6 +97,7 @@
|
||||
\
|
||||
/* If the iterator has reached the end of the iteration */ \
|
||||
bool end; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
@@ -504,7 +507,7 @@
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return false; \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter1, iter2; \
|
||||
PFX##_iter_init(&iter1, _set1_); \
|
||||
@@ -528,7 +531,7 @@
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return false; \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \
|
||||
SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
|
||||
@@ -552,7 +555,7 @@
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return false; \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
@@ -573,7 +576,7 @@
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return false; \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter1, iter2; \
|
||||
PFX##_iter_init(&iter1, _set1_); \
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* A node-based Queue using a Singly Linked List
|
||||
*
|
||||
* enqueue : is equivalent to a push_back from a LinkedList
|
||||
* dequeue : is equivalent to a pop_peek from a LinkedList
|
||||
* dequeue : is equivalent to a pop_front from a LinkedList
|
||||
*
|
||||
* This Queue has a one-way iterator
|
||||
*/
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ int main(void)
|
||||
queue *q = q_new(1000);
|
||||
deque *d = d_new(1000);
|
||||
linked *ll = ll_new();
|
||||
heap *h = h_new(1000, MaxHeap, intcmp);
|
||||
heap *h = h_new(1000, cmc_max_heap, intcmp);
|
||||
tset *ts = ts_new(intcmp);
|
||||
tmap *tm = tm_new(intcmp);
|
||||
hset *hs = hs_new(1000, 0.9, intcmp, inthash);
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ int main(void)
|
||||
queue *q = q_new(1000);
|
||||
deque *d = d_new(1000);
|
||||
linked *ll = ll_new();
|
||||
heap *h = h_new(1000, MaxHeap, intcmp);
|
||||
heap *h = h_new(1000, cmc_max_heap, intcmp);
|
||||
tset *ts = ts_new(intcmp);
|
||||
tmap *tm = tm_new(intcmp);
|
||||
hset *hs = hs_new(1000, 0.9, intcmp, inthash);
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ COLLECTION_GENERATE(HASHMAP, hm, hmap, /* FMOD */, int, double)
|
||||
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(HEAP, h, heap, h_new(20, cmc_max_heap, 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)
|
||||
|
||||
Reference in new issue
Block a user