Fixing some things, tests resumed
This commit is contained in:
1 parent
aec7efd4c3
commit
2b8f778c59
26 files changed
+2652
-1953
No files matched your search
+2
-2
@@ -53,11 +53,11 @@ for data in collections:
|
||||
|
||||
file.write(
|
||||
f'''
|
||||
#include {data['h']}
|
||||
#include "macro_collections.h"
|
||||
|
||||
{UNIQUE_FLAG}
|
||||
|
||||
CMC_{data['LIB']}_{data['COLLECTION']}_CORE(({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])}))
|
||||
C_MACRO_COLLECTIONS_ALL({data['LIB']}, {data['COLLECTION']}, ({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])}))
|
||||
|
||||
{UNIQUE_FLAG}
|
||||
''')
|
||||
|
||||
+5
-5
@@ -453,8 +453,8 @@
|
||||
{ \
|
||||
if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \
|
||||
{ \
|
||||
max_key = _map_->buffer[first].key; \
|
||||
max_val = _map_->buffer[first].value; \
|
||||
max_key = _map_->buffer[i].key; \
|
||||
max_val = _map_->buffer[i].value; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
@@ -495,10 +495,10 @@
|
||||
{ \
|
||||
if (_map_->buffer[i].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) > 0) \
|
||||
if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) \
|
||||
{ \
|
||||
min_key = _map_->buffer[first].key; \
|
||||
min_val = _map_->buffer[first].value; \
|
||||
min_key = _map_->buffer[i].key; \
|
||||
min_val = _map_->buffer[i].value; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
|
||||
+10
-1
@@ -16,6 +16,15 @@
|
||||
/**
|
||||
* All the EXT parts of CMC BitSet.
|
||||
*/
|
||||
#define CMC_EXT_CMC_BITSET_PARTS
|
||||
#define CMC_EXT_CMC_BITSET_PARTS PLACEHOLDER
|
||||
|
||||
#define CMC_EXT_CMC_BITSET_PLACEHOLDER(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_BITSET_PLACEHOLDER_HEADER(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_BITSET_PLACEHOLDER_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_BITSET_PLACEHOLDER_HEADER_(PFX, SNAME, V)
|
||||
#define CMC_EXT_CMC_BITSET_PLACEHOLDER_SOURCE_(PFX, SNAME, V)
|
||||
|
||||
#endif /* CMC_EXT_CMC_BITSET_H */
|
||||
@@ -136,12 +136,6 @@ CMC_UNUSED static void cmc_test_log(const char *unit_name, const char *current_t
|
||||
BODY; \
|
||||
\
|
||||
cmc_timer_stop(timer); \
|
||||
\
|
||||
unittest_abort: \
|
||||
if (tinfo.aborted) \
|
||||
{ \
|
||||
cmc_test_log(unit_name, current_test, true, false); \
|
||||
} \
|
||||
\
|
||||
tinfo.assert_total = cmc_assert_total - tinfo.assert_total; \
|
||||
tinfo.assert_failed = cmc_assert_failed - tinfo.assert_failed; \
|
||||
@@ -225,13 +219,4 @@ CMC_UNUSED static void cmc_test_log(const char *unit_name, const char *current_t
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define CMC_TEST_ABORT() \
|
||||
do \
|
||||
{ \
|
||||
tinfo.aborted = true; \
|
||||
tinfo.total -= 1; \
|
||||
goto unittest_abort; \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#endif /* CMC_UTL_TEST_H */
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
CC = gcc
|
||||
CFLAGS = -std=c11 -Wall -Wextra
|
||||
CFLAGS += -Wno-unused -Wno-missing-braces
|
||||
CFLAGS += -Wno-missing-braces
|
||||
DBFLAGS = -g3
|
||||
CVFLAGS = --coverage -O0
|
||||
INCLUDE = ../../src/
|
||||
|
||||
+38
-25
@@ -14,7 +14,7 @@ struct bitset
|
||||
struct bitset_iter
|
||||
{
|
||||
struct bitset *target;
|
||||
cmc_bitset_word cursor;
|
||||
size_t cursor;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
@@ -70,15 +70,17 @@ struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct
|
||||
_bitset_->capacity = capacity;
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
_bitset_->alloc = alloc;
|
||||
_bitset_->callbacks = callbacks;
|
||||
(_bitset_)->callbacks = callbacks;
|
||||
return _bitset_;
|
||||
}
|
||||
struct bitset bs_init(size_t n_bits)
|
||||
{
|
||||
return bs_init_custom(n_bits, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *__attribute__((__unused__)) (callbacks))
|
||||
{
|
||||
;
|
||||
struct bitset _bitset_ = { 0 };
|
||||
if (n_bits < 1)
|
||||
return _bitset_;
|
||||
@@ -91,7 +93,7 @@ struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct
|
||||
_bitset_.capacity = capacity;
|
||||
_bitset_.flag = CMC_FLAG_OK;
|
||||
_bitset_.alloc = alloc;
|
||||
_bitset_.callbacks = callbacks;
|
||||
(&_bitset_)->callbacks = callbacks;
|
||||
return _bitset_;
|
||||
}
|
||||
void bs_free(struct bitset *_bitset_)
|
||||
@@ -105,11 +107,12 @@ void bs_release(struct bitset _bitset_)
|
||||
}
|
||||
void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_bitset_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_bitset_->alloc = alloc;
|
||||
_bitset_->callbacks = callbacks;
|
||||
(_bitset_)->callbacks = callbacks;
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool bs_set(struct bitset *_bitset_, size_t bit_index)
|
||||
@@ -120,8 +123,9 @@ _Bool bs_set(struct bitset *_bitset_, size_t bit_index)
|
||||
size_t i = bs_bit_to_index(bit_index);
|
||||
_bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits);
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->create)
|
||||
_bitset_->callbacks->create();
|
||||
if ((_bitset_)->callbacks && (_bitset_)->callbacks->create)
|
||||
(_bitset_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to)
|
||||
@@ -153,8 +157,9 @@ _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to)
|
||||
_bitset_->buffer[end_index] |= end_mask;
|
||||
}
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->create)
|
||||
_bitset_->callbacks->create();
|
||||
if ((_bitset_)->callbacks && (_bitset_)->callbacks->create)
|
||||
(_bitset_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool bs_clear(struct bitset *_bitset_, size_t bit_index)
|
||||
@@ -165,8 +170,9 @@ _Bool bs_clear(struct bitset *_bitset_, size_t bit_index)
|
||||
size_t i = bs_bit_to_index(bit_index);
|
||||
_bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits));
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->delete)
|
||||
_bitset_->callbacks->delete ();
|
||||
if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete)
|
||||
(_bitset_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to)
|
||||
@@ -198,8 +204,9 @@ _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to)
|
||||
_bitset_->buffer[end_index] &= ~end_mask;
|
||||
}
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->delete)
|
||||
_bitset_->callbacks->delete ();
|
||||
if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete)
|
||||
(_bitset_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool bs_flip(struct bitset *_bitset_, size_t bit_index)
|
||||
@@ -210,8 +217,9 @@ _Bool bs_flip(struct bitset *_bitset_, size_t bit_index)
|
||||
size_t i = bs_bit_to_index(bit_index);
|
||||
_bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits);
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->update)
|
||||
_bitset_->callbacks->update();
|
||||
if ((_bitset_)->callbacks && (_bitset_)->callbacks->update)
|
||||
(_bitset_)->callbacks->update();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to)
|
||||
@@ -243,8 +251,9 @@ _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to)
|
||||
_bitset_->buffer[end_index] ^= end_mask;
|
||||
}
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->update)
|
||||
_bitset_->callbacks->update();
|
||||
if ((_bitset_)->callbacks && (_bitset_)->callbacks->update)
|
||||
(_bitset_)->callbacks->update();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state)
|
||||
@@ -266,8 +275,9 @@ _Bool bs_set_all(struct bitset *_bitset_)
|
||||
for (size_t i = 0; i < _bitset_->capacity; i++)
|
||||
_bitset_->buffer[i] = ~((cmc_bitset_word)0);
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->create)
|
||||
_bitset_->callbacks->create();
|
||||
if ((_bitset_)->callbacks && (_bitset_)->callbacks->create)
|
||||
(_bitset_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool bs_clear_all(struct bitset *_bitset_)
|
||||
@@ -275,8 +285,9 @@ _Bool bs_clear_all(struct bitset *_bitset_)
|
||||
for (size_t i = 0; i < _bitset_->capacity; i++)
|
||||
_bitset_->buffer[i] = 0;
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->delete)
|
||||
_bitset_->callbacks->delete ();
|
||||
if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete)
|
||||
(_bitset_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool bs_flip_all(struct bitset *_bitset_)
|
||||
@@ -284,8 +295,9 @@ _Bool bs_flip_all(struct bitset *_bitset_)
|
||||
for (size_t i = 0; i < _bitset_->capacity; i++)
|
||||
_bitset_->buffer[i] ^= ~((cmc_bitset_word)0);
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->create)
|
||||
_bitset_->callbacks->create();
|
||||
if ((_bitset_)->callbacks && (_bitset_)->callbacks->create)
|
||||
(_bitset_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool bs_get(struct bitset *_bitset_, size_t bit_index)
|
||||
@@ -318,8 +330,9 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize)
|
||||
if (_bitset_->capacity < words)
|
||||
memset(_bitset_->buffer + _bitset_->capacity, 0, (words - _bitset_->capacity) * sizeof(cmc_bitset_word));
|
||||
_bitset_->capacity = words;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->resize)
|
||||
_bitset_->callbacks->resize();
|
||||
if ((_bitset_)->callbacks && (_bitset_)->callbacks->resize)
|
||||
(_bitset_)->callbacks->resize();
|
||||
;
|
||||
_bitset_->flag = CMC_FLAG_OK;
|
||||
return 1;
|
||||
}
|
||||
|
||||
+124
-42
@@ -24,20 +24,11 @@ struct deque_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct deque_iter
|
||||
{
|
||||
struct deque *target;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct deque *d_new(size_t capacity, struct deque_fval *f_val);
|
||||
struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks);
|
||||
void d_clear(struct deque *_deque_);
|
||||
void d_free(struct deque *_deque_);
|
||||
void d_release(struct deque _deque_);
|
||||
void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
|
||||
_Bool d_push_front(struct deque *_deque_, size_t value);
|
||||
_Bool d_push_back(struct deque *_deque_, size_t value);
|
||||
@@ -54,8 +45,18 @@ int d_flag(struct deque *_deque_);
|
||||
_Bool d_resize(struct deque *_deque_, size_t capacity);
|
||||
struct deque *d_copy_of(struct deque *_deque_);
|
||||
_Bool d_equals(struct deque *_deque1_, struct deque *_deque2_);
|
||||
struct cmc_string d_to_string(struct deque *_deque_);
|
||||
_Bool d_print(struct deque *_deque_, FILE *fptr);
|
||||
struct deque d_init(size_t capacity, struct deque_fval *f_val);
|
||||
struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks);
|
||||
void d_release(struct deque _deque_);
|
||||
struct deque_iter
|
||||
{
|
||||
struct deque *target;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct deque_iter d_iter_start(struct deque *target);
|
||||
struct deque_iter d_iter_end(struct deque *target);
|
||||
_Bool d_iter_at_start(struct deque_iter *iter);
|
||||
@@ -70,6 +71,8 @@ _Bool d_iter_go_to(struct deque_iter *iter, size_t index);
|
||||
size_t d_iter_value(struct deque_iter *iter);
|
||||
size_t *d_iter_rvalue(struct deque_iter *iter);
|
||||
size_t d_iter_index(struct deque_iter *iter);
|
||||
_Bool d_to_string(struct deque *_deque_, FILE *fptr);
|
||||
_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end);
|
||||
struct deque *d_new(size_t capacity, struct deque_fval *f_val)
|
||||
{
|
||||
return d_new_custom(capacity, f_val, ((void *)0), ((void *)0));
|
||||
@@ -77,6 +80,7 @@ struct deque *d_new(size_t capacity, struct deque_fval *f_val)
|
||||
struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
@@ -99,7 +103,7 @@ struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc
|
||||
_deque_->flag = CMC_FLAG_OK;
|
||||
_deque_->f_val = f_val;
|
||||
_deque_->alloc = alloc;
|
||||
_deque_->callbacks = callbacks;
|
||||
(_deque_)->callbacks = callbacks;
|
||||
return _deque_;
|
||||
}
|
||||
void d_clear(struct deque *_deque_)
|
||||
@@ -131,25 +135,14 @@ void d_free(struct deque *_deque_)
|
||||
_deque_->alloc->free(_deque_->buffer);
|
||||
_deque_->alloc->free(_deque_);
|
||||
}
|
||||
void d_release(struct deque _deque_)
|
||||
{
|
||||
if (_deque_.f_val->free)
|
||||
{
|
||||
for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++)
|
||||
{
|
||||
_deque_.f_val->free(_deque_.buffer[i]);
|
||||
i = (i + 1) % _deque_.capacity;
|
||||
}
|
||||
}
|
||||
_deque_.alloc->free(_deque_.buffer);
|
||||
}
|
||||
void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_deque_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_deque_->alloc = alloc;
|
||||
_deque_->callbacks = callbacks;
|
||||
(_deque_)->callbacks = callbacks;
|
||||
_deque_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool d_push_front(struct deque *_deque_, size_t value)
|
||||
@@ -163,8 +156,9 @@ _Bool d_push_front(struct deque *_deque_, size_t value)
|
||||
_deque_->buffer[_deque_->front] = value;
|
||||
_deque_->count++;
|
||||
_deque_->flag = CMC_FLAG_OK;
|
||||
if (_deque_->callbacks && _deque_->callbacks->create)
|
||||
_deque_->callbacks->create();
|
||||
if ((_deque_)->callbacks && (_deque_)->callbacks->create)
|
||||
(_deque_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool d_push_back(struct deque *_deque_, size_t value)
|
||||
@@ -178,8 +172,9 @@ _Bool d_push_back(struct deque *_deque_, size_t value)
|
||||
_deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1;
|
||||
_deque_->count++;
|
||||
_deque_->flag = CMC_FLAG_OK;
|
||||
if (_deque_->callbacks && _deque_->callbacks->create)
|
||||
_deque_->callbacks->create();
|
||||
if ((_deque_)->callbacks && (_deque_)->callbacks->create)
|
||||
(_deque_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool d_pop_front(struct deque *_deque_)
|
||||
@@ -193,8 +188,9 @@ _Bool d_pop_front(struct deque *_deque_)
|
||||
_deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1;
|
||||
_deque_->count--;
|
||||
_deque_->flag = CMC_FLAG_OK;
|
||||
if (_deque_->callbacks && _deque_->callbacks->delete)
|
||||
_deque_->callbacks->delete ();
|
||||
if ((_deque_)->callbacks && (_deque_)->callbacks->delete)
|
||||
(_deque_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool d_pop_back(struct deque *_deque_)
|
||||
@@ -208,8 +204,9 @@ _Bool d_pop_back(struct deque *_deque_)
|
||||
_deque_->buffer[_deque_->back] = (size_t){ 0 };
|
||||
_deque_->count--;
|
||||
_deque_->flag = CMC_FLAG_OK;
|
||||
if (_deque_->callbacks && _deque_->callbacks->delete)
|
||||
_deque_->callbacks->delete ();
|
||||
if ((_deque_)->callbacks && (_deque_)->callbacks->delete)
|
||||
(_deque_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t d_front(struct deque *_deque_)
|
||||
@@ -220,8 +217,9 @@ size_t d_front(struct deque *_deque_)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_deque_->flag = CMC_FLAG_OK;
|
||||
if (_deque_->callbacks && _deque_->callbacks->read)
|
||||
_deque_->callbacks->read();
|
||||
if ((_deque_)->callbacks && (_deque_)->callbacks->read)
|
||||
(_deque_)->callbacks->read();
|
||||
;
|
||||
return _deque_->buffer[_deque_->front];
|
||||
}
|
||||
size_t d_back(struct deque *_deque_)
|
||||
@@ -232,8 +230,9 @@ size_t d_back(struct deque *_deque_)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_deque_->flag = CMC_FLAG_OK;
|
||||
if (_deque_->callbacks && _deque_->callbacks->read)
|
||||
_deque_->callbacks->read();
|
||||
if ((_deque_)->callbacks && (_deque_)->callbacks->read)
|
||||
(_deque_)->callbacks->read();
|
||||
;
|
||||
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1];
|
||||
}
|
||||
_Bool d_contains(struct deque *_deque_, size_t value)
|
||||
@@ -249,8 +248,9 @@ _Bool d_contains(struct deque *_deque_, size_t value)
|
||||
}
|
||||
i = (i + 1) % _deque_->capacity;
|
||||
}
|
||||
if (_deque_->callbacks && _deque_->callbacks->read)
|
||||
_deque_->callbacks->read();
|
||||
if ((_deque_)->callbacks && (_deque_)->callbacks->read)
|
||||
(_deque_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool d_empty(struct deque *_deque_)
|
||||
@@ -300,18 +300,20 @@ _Bool d_resize(struct deque *_deque_, size_t capacity)
|
||||
_deque_->front = 0;
|
||||
_deque_->back = _deque_->count;
|
||||
success:
|
||||
if (_deque_->callbacks && _deque_->callbacks->resize)
|
||||
_deque_->callbacks->resize();
|
||||
if ((_deque_)->callbacks && (_deque_)->callbacks->resize)
|
||||
(_deque_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct deque *d_copy_of(struct deque *_deque_)
|
||||
{
|
||||
struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, _deque_->callbacks);
|
||||
struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
{
|
||||
_deque_->flag = CMC_FLAG_ERROR;
|
||||
return ((void *)0);
|
||||
}
|
||||
(result)->callbacks = _deque_->callbacks;
|
||||
if (_deque_->f_val->cpy)
|
||||
{
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++)
|
||||
@@ -350,6 +352,46 @@ _Bool d_equals(struct deque *_deque1_, struct deque *_deque2_)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
struct deque d_init(size_t capacity, struct deque_fval *f_val)
|
||||
{
|
||||
return d_init_custom(capacity, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
struct deque _deque_ = { 0 };
|
||||
if (capacity < 1)
|
||||
return _deque_;
|
||||
if (!f_val)
|
||||
return _deque_;
|
||||
if (!alloc)
|
||||
alloc = &cmc_alloc_node_default;
|
||||
_deque_.buffer = alloc->calloc(capacity, sizeof(size_t));
|
||||
if (!_deque_.buffer)
|
||||
return _deque_;
|
||||
_deque_.capacity = capacity;
|
||||
_deque_.count = 0;
|
||||
_deque_.front = 0;
|
||||
_deque_.back = 0;
|
||||
_deque_.flag = CMC_FLAG_OK;
|
||||
_deque_.f_val = f_val;
|
||||
_deque_.alloc = alloc;
|
||||
(&_deque_)->callbacks = callbacks;
|
||||
return _deque_;
|
||||
}
|
||||
void d_release(struct deque _deque_)
|
||||
{
|
||||
if (_deque_.f_val->free)
|
||||
{
|
||||
for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++)
|
||||
{
|
||||
_deque_.f_val->free(_deque_.buffer[i]);
|
||||
i = (i + 1) % _deque_.capacity;
|
||||
}
|
||||
}
|
||||
_deque_.alloc->free(_deque_.buffer);
|
||||
}
|
||||
struct deque_iter d_iter_start(struct deque *target)
|
||||
{
|
||||
struct deque_iter iter;
|
||||
@@ -504,5 +546,45 @@ size_t d_iter_index(struct deque_iter *iter)
|
||||
{
|
||||
return iter->index;
|
||||
}
|
||||
_Bool d_to_string(struct deque *_deque_, FILE *fptr)
|
||||
{
|
||||
struct deque *d_ = _deque_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"front:%"
|
||||
"I64u"
|
||||
", "
|
||||
"back:%"
|
||||
"I64u"
|
||||
", "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"deque", "size_t", d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back, d_->flag,
|
||||
d_->f_val, d_->alloc, (d_)->callbacks);
|
||||
}
|
||||
_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end)
|
||||
{
|
||||
fprintf(fptr, "%s", start);
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++)
|
||||
{
|
||||
if (!_deque_->f_val->str(fptr, _deque_->buffer[i]))
|
||||
return 0;
|
||||
i = (i + 1) % _deque_->capacity;
|
||||
if (j + 1 < _deque_->count)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_DEQUE */
|
||||
@@ -78,8 +78,6 @@ int hbm_flag(struct hashbidimap *_map_);
|
||||
_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity);
|
||||
struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_);
|
||||
_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_);
|
||||
struct cmc_string hbm_to_string(struct hashbidimap *_map_);
|
||||
_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr);
|
||||
struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target);
|
||||
void hbm_iter_free(struct hashbidimap_iter *iter);
|
||||
void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target);
|
||||
@@ -95,6 +93,9 @@ _Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index);
|
||||
size_t hbm_iter_key(struct hashbidimap_iter *iter);
|
||||
size_t hbm_iter_value(struct hashbidimap_iter *iter);
|
||||
size_t hbm_iter_index(struct hashbidimap_iter *iter);
|
||||
_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr);
|
||||
_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
|
||||
const char *key_val_sep);
|
||||
static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, size_t key, size_t value);
|
||||
static struct hashbidimap_entry **hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key);
|
||||
static struct hashbidimap_entry **hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val);
|
||||
@@ -106,40 +107,13 @@ static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_);
|
||||
struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key,
|
||||
struct hashbidimap_fval *f_val)
|
||||
{
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
if (capacity == 0 || load <= 0 || load >= 1)
|
||||
return ((void *)0);
|
||||
if (capacity >= 0xffffffffffffffffULL * load)
|
||||
return ((void *)0);
|
||||
if (!f_key || !f_val)
|
||||
return ((void *)0);
|
||||
size_t real_capacity = hbm_impl_calculate_size(capacity / load);
|
||||
struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap));
|
||||
if (!_map_)
|
||||
return ((void *)0);
|
||||
_map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2]));
|
||||
if (!_map_->buffer)
|
||||
{
|
||||
alloc->free(_map_->buffer);
|
||||
alloc->free(_map_);
|
||||
return ((void *)0);
|
||||
}
|
||||
_map_->count = 0;
|
||||
_map_->capacity = real_capacity;
|
||||
_map_->load = load;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
_map_->f_key = f_key;
|
||||
_map_->f_val = f_val;
|
||||
_map_->alloc = alloc;
|
||||
_map_->callbacks = ((void *)0);
|
||||
_map_->it_start = hbm_impl_it_start;
|
||||
_map_->it_end = hbm_impl_it_end;
|
||||
return _map_;
|
||||
return hbm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key,
|
||||
struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity == 0 || load <= 0 || load >= 1)
|
||||
return ((void *)0);
|
||||
if (capacity >= 0xffffffffffffffffULL * load)
|
||||
@@ -167,7 +141,7 @@ struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidi
|
||||
_map_->f_val = f_val;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
_map_->alloc = alloc;
|
||||
_map_->callbacks = callbacks;
|
||||
(_map_)->callbacks = callbacks;
|
||||
_map_->it_start = hbm_impl_it_start;
|
||||
_map_->it_end = hbm_impl_it_end;
|
||||
return _map_;
|
||||
@@ -199,11 +173,12 @@ void hbm_free(struct hashbidimap *_map_)
|
||||
}
|
||||
void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_map_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_map_->alloc = alloc;
|
||||
_map_->callbacks = callbacks;
|
||||
(_map_)->callbacks = callbacks;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value)
|
||||
@@ -233,8 +208,9 @@ _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value)
|
||||
}
|
||||
_map_->count++;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->create)
|
||||
_map_->callbacks->create();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->create)
|
||||
(_map_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key)
|
||||
@@ -277,8 +253,9 @@ _Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key)
|
||||
}
|
||||
success:
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->update)
|
||||
_map_->callbacks->update();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->update)
|
||||
(_map_)->callbacks->update();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val)
|
||||
@@ -321,8 +298,9 @@ _Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val)
|
||||
}
|
||||
success:
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->update)
|
||||
_map_->callbacks->update();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->update)
|
||||
(_map_)->callbacks->update();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val)
|
||||
@@ -354,8 +332,9 @@ _Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key,
|
||||
*val_entry = ((void *)1);
|
||||
_map_->count--;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->delete)
|
||||
_map_->callbacks->delete ();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->delete)
|
||||
(_map_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val)
|
||||
@@ -387,8 +366,9 @@ _Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key,
|
||||
*val_entry = ((void *)1);
|
||||
_map_->count--;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->delete)
|
||||
_map_->callbacks->delete ();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->delete)
|
||||
(_map_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t hbm_get_key(struct hashbidimap *_map_, size_t val)
|
||||
@@ -400,8 +380,9 @@ size_t hbm_get_key(struct hashbidimap *_map_, size_t val)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return (*entry)->key;
|
||||
}
|
||||
size_t hbm_get_val(struct hashbidimap *_map_, size_t key)
|
||||
@@ -413,24 +394,27 @@ size_t hbm_get_val(struct hashbidimap *_map_, size_t key)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return (*entry)->value;
|
||||
}
|
||||
_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key)
|
||||
{
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
_Bool result = hbm_impl_get_entry_by_key(_map_, key) != ((void *)0);
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val)
|
||||
{
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
_Bool result = hbm_impl_get_entry_by_val(_map_, val) != ((void *)0);
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool hbm_empty(struct hashbidimap *_map_)
|
||||
@@ -516,19 +500,21 @@ _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity)
|
||||
_map_->alloc->free(tmp_buff);
|
||||
_map_->alloc->free(_new_map_);
|
||||
success:
|
||||
if (_map_->callbacks && _map_->callbacks->resize)
|
||||
_map_->callbacks->resize();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->resize)
|
||||
(_map_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_)
|
||||
{
|
||||
struct hashbidimap *result = hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val,
|
||||
_map_->alloc, _map_->callbacks);
|
||||
_map_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
{
|
||||
_map_->flag = CMC_FLAG_ERROR;
|
||||
return ((void *)0);
|
||||
}
|
||||
(result)->callbacks = _map_->callbacks;
|
||||
for (size_t i = 0; i < _map_->capacity; i++)
|
||||
{
|
||||
struct hashbidimap_entry *scan = _map_->buffer[i][0];
|
||||
@@ -607,8 +593,8 @@ void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target)
|
||||
{
|
||||
for (size_t i = 0; i < target->capacity; i++)
|
||||
{
|
||||
struct hashbidimap_entry *tmp = target->buffer[i][0];
|
||||
if (tmp != ((void *)0) && tmp != ((void *)1))
|
||||
struct hashbidimap_entry *entry = target->buffer[i][0];
|
||||
if (entry && entry != ((void *)1))
|
||||
{
|
||||
iter->first = i;
|
||||
break;
|
||||
@@ -617,8 +603,8 @@ void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target)
|
||||
iter->cursor = iter->first;
|
||||
for (size_t i = target->capacity; i > 0; i--)
|
||||
{
|
||||
struct hashbidimap_entry *tmp = target->buffer[i - 1][0];
|
||||
if (tmp != ((void *)0) && tmp != ((void *)1))
|
||||
struct hashbidimap_entry *entry = target->buffer[i - 1][0];
|
||||
if (entry && entry != ((void *)1))
|
||||
{
|
||||
iter->last = i - 1;
|
||||
break;
|
||||
@@ -910,5 +896,58 @@ static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_)
|
||||
hbm_iter_to_end(&iter);
|
||||
return iter;
|
||||
}
|
||||
_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr)
|
||||
{
|
||||
struct hashbidimap *m_ = _map_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s, %s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"load:%lf, "
|
||||
"flag:%d, "
|
||||
"f_key:%p, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"hashbidimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag,
|
||||
m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks);
|
||||
}
|
||||
_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
|
||||
const char *key_val_sep)
|
||||
{
|
||||
fprintf(fptr, "%s", start);
|
||||
size_t last = 0;
|
||||
for (size_t i = _map_->capacity; i > 0; i--)
|
||||
{
|
||||
struct hashbidimap_entry *entry = _map_->buffer[i - 1][0];
|
||||
if (entry && entry != ((void *)1))
|
||||
{
|
||||
last = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < _map_->capacity; i++)
|
||||
{
|
||||
struct hashbidimap_entry *entry = _map_->buffer[i][0];
|
||||
if (entry && entry != ((void *)1))
|
||||
{
|
||||
if (!_map_->f_key->str(fptr, entry->key))
|
||||
return 0;
|
||||
fprintf(fptr, "%s", key_val_sep);
|
||||
if (!_map_->f_val->str(fptr, entry->value))
|
||||
return 0;
|
||||
if (i + 1 < last)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_HASHBIDIMAP */
|
||||
+230
-104
@@ -40,22 +40,11 @@ struct hashmap_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct hashmap_iter
|
||||
{
|
||||
struct hashmap *target;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
size_t first;
|
||||
size_t last;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val);
|
||||
struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val,
|
||||
struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
|
||||
void hm_clear(struct hashmap *_map_);
|
||||
void hm_free(struct hashmap *_map_);
|
||||
void hm_release(struct hashmap _map_);
|
||||
void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
|
||||
_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value);
|
||||
_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value);
|
||||
@@ -74,8 +63,20 @@ int hm_flag(struct hashmap *_map_);
|
||||
_Bool hm_resize(struct hashmap *_map_, size_t capacity);
|
||||
struct hashmap *hm_copy_of(struct hashmap *_map_);
|
||||
_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_);
|
||||
struct cmc_string hm_to_string(struct hashmap *_map_);
|
||||
_Bool hm_print(struct hashmap *_map_, FILE *fptr);
|
||||
struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val);
|
||||
struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val,
|
||||
struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
|
||||
void hm_release(struct hashmap _map_);
|
||||
struct hashmap_iter
|
||||
{
|
||||
struct hashmap *target;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
size_t first;
|
||||
size_t last;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct hashmap_iter hm_iter_start(struct hashmap *target);
|
||||
struct hashmap_iter hm_iter_end(struct hashmap *target);
|
||||
_Bool hm_iter_at_start(struct hashmap_iter *iter);
|
||||
@@ -91,6 +92,9 @@ size_t hm_iter_key(struct hashmap_iter *iter);
|
||||
size_t hm_iter_value(struct hashmap_iter *iter);
|
||||
size_t *hm_iter_rvalue(struct hashmap_iter *iter);
|
||||
size_t hm_iter_index(struct hashmap_iter *iter);
|
||||
_Bool hm_to_string(struct hashmap *_map_, FILE *fptr);
|
||||
_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
|
||||
const char *key_val_sep);
|
||||
static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key);
|
||||
static size_t hm_impl_calculate_size(size_t required);
|
||||
struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val)
|
||||
@@ -100,6 +104,7 @@ struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key,
|
||||
struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val,
|
||||
struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity == 0 || load <= 0 || load >= 1)
|
||||
return ((void *)0);
|
||||
if (capacity >= 0xffffffffffffffffULL * load)
|
||||
@@ -125,7 +130,7 @@ struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey
|
||||
_map_->f_key = f_key;
|
||||
_map_->f_val = f_val;
|
||||
_map_->alloc = alloc;
|
||||
_map_->callbacks = callbacks;
|
||||
(_map_)->callbacks = callbacks;
|
||||
return _map_;
|
||||
}
|
||||
void hm_clear(struct hashmap *_map_)
|
||||
@@ -167,31 +172,14 @@ void hm_free(struct hashmap *_map_)
|
||||
_map_->alloc->free(_map_->buffer);
|
||||
_map_->alloc->free(_map_);
|
||||
}
|
||||
void hm_release(struct hashmap _map_)
|
||||
{
|
||||
if (_map_.f_key->free || _map_.f_val->free)
|
||||
{
|
||||
for (size_t i = 0; i < _map_.capacity; i++)
|
||||
{
|
||||
struct hashmap_entry *entry = &(_map_.buffer[i]);
|
||||
if (entry->state == CMC_ES_FILLED)
|
||||
{
|
||||
if (_map_.f_key->free)
|
||||
_map_.f_key->free(entry->key);
|
||||
if (_map_.f_val->free)
|
||||
_map_.f_val->free(entry->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
_map_.alloc->free(_map_.buffer);
|
||||
}
|
||||
void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_map_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_map_->alloc = alloc;
|
||||
_map_->callbacks = callbacks;
|
||||
(_map_)->callbacks = callbacks;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value)
|
||||
@@ -247,8 +235,9 @@ _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value)
|
||||
}
|
||||
_map_->count++;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->create)
|
||||
_map_->callbacks->create();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->create)
|
||||
(_map_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value)
|
||||
@@ -268,8 +257,9 @@ _Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old
|
||||
*old_value = entry->value;
|
||||
entry->value = new_value;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->update)
|
||||
_map_->callbacks->update();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->update)
|
||||
(_map_)->callbacks->update();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value)
|
||||
@@ -293,8 +283,9 @@ _Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value)
|
||||
result->state = CMC_ES_DELETED;
|
||||
_map_->count--;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->delete)
|
||||
_map_->callbacks->delete ();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->delete)
|
||||
(_map_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value)
|
||||
@@ -304,26 +295,36 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value)
|
||||
_map_->flag = CMC_FLAG_EMPTY;
|
||||
return 0;
|
||||
}
|
||||
struct hashmap_iter iter = hm_iter_start(_map_);
|
||||
size_t max_key = hm_iter_key(&iter);
|
||||
size_t max_val = hm_iter_value(&iter);
|
||||
hm_iter_next(&iter);
|
||||
for (; !hm_iter_at_end(&iter); hm_iter_next(&iter))
|
||||
size_t max_key;
|
||||
size_t max_val;
|
||||
size_t first = 0;
|
||||
for (; first < _map_->capacity; first++)
|
||||
{
|
||||
size_t iter_key = hm_iter_key(&iter);
|
||||
size_t iter_val = hm_iter_value(&iter);
|
||||
if (_map_->f_key->cmp(iter_key, max_key) > 0)
|
||||
if (_map_->buffer[first].state == CMC_ES_FILLED)
|
||||
{
|
||||
max_key = iter_key;
|
||||
max_val = iter_val;
|
||||
max_key = _map_->buffer[first].key;
|
||||
max_val = _map_->buffer[first].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (size_t i = first + 1; i < _map_->capacity; i++)
|
||||
{
|
||||
if (_map_->buffer[i].state == CMC_ES_FILLED)
|
||||
{
|
||||
if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0)
|
||||
{
|
||||
max_key = _map_->buffer[i].key;
|
||||
max_val = _map_->buffer[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key)
|
||||
*key = max_key;
|
||||
if (value)
|
||||
*value = max_val;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value)
|
||||
@@ -333,26 +334,36 @@ _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value)
|
||||
_map_->flag = CMC_FLAG_EMPTY;
|
||||
return 0;
|
||||
}
|
||||
struct hashmap_iter iter = hm_iter_start(_map_);
|
||||
size_t min_key = hm_iter_key(&iter);
|
||||
size_t min_val = hm_iter_value(&iter);
|
||||
hm_iter_next(&iter);
|
||||
for (; !hm_iter_at_end(&iter); hm_iter_next(&iter))
|
||||
size_t min_key;
|
||||
size_t min_val;
|
||||
size_t first = 0;
|
||||
for (; first < _map_->capacity; first++)
|
||||
{
|
||||
size_t iter_key = hm_iter_key(&iter);
|
||||
size_t iter_val = hm_iter_value(&iter);
|
||||
if (_map_->f_key->cmp(iter_key, min_key) < 0)
|
||||
if (_map_->buffer[first].state == CMC_ES_FILLED)
|
||||
{
|
||||
min_key = iter_key;
|
||||
min_val = iter_val;
|
||||
min_key = _map_->buffer[first].key;
|
||||
min_val = _map_->buffer[first].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (size_t i = first + 1; i < _map_->capacity; i++)
|
||||
{
|
||||
if (_map_->buffer[i].state == CMC_ES_FILLED)
|
||||
{
|
||||
if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0)
|
||||
{
|
||||
min_key = _map_->buffer[i].key;
|
||||
min_val = _map_->buffer[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key)
|
||||
*key = min_key;
|
||||
if (value)
|
||||
*value = min_val;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t hm_get(struct hashmap *_map_, size_t key)
|
||||
@@ -369,8 +380,9 @@ size_t hm_get(struct hashmap *_map_, size_t key)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return entry->value;
|
||||
}
|
||||
size_t *hm_get_ref(struct hashmap *_map_, size_t key)
|
||||
@@ -387,16 +399,18 @@ size_t *hm_get_ref(struct hashmap *_map_, size_t key)
|
||||
return ((void *)0);
|
||||
}
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return &(entry->value);
|
||||
}
|
||||
_Bool hm_contains(struct hashmap *_map_, size_t key)
|
||||
{
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
_Bool result = hm_impl_get_entry(_map_, key) != ((void *)0);
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool hm_empty(struct hashmap *_map_)
|
||||
@@ -448,12 +462,14 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity)
|
||||
_map_->flag = CMC_FLAG_ALLOC;
|
||||
return 0;
|
||||
}
|
||||
struct hashmap_iter iter = hm_iter_start(_map_);
|
||||
for (; !hm_iter_at_end(&iter); hm_iter_next(&iter))
|
||||
for (size_t i = 0; i < _map_->capacity; i++)
|
||||
{
|
||||
size_t key = hm_iter_key(&iter);
|
||||
size_t value = hm_iter_value(&iter);
|
||||
hm_insert(_new_map_, key, value);
|
||||
if (_map_->buffer[i].state == CMC_ES_FILLED)
|
||||
{
|
||||
size_t key = _map_->buffer[i].key;
|
||||
size_t value = _map_->buffer[i].value;
|
||||
hm_insert(_new_map_, key, value);
|
||||
}
|
||||
}
|
||||
if (_map_->count != _new_map_->count)
|
||||
{
|
||||
@@ -471,19 +487,21 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity)
|
||||
_new_map_->f_val = &(struct hashmap_fval){ ((void *)0) };
|
||||
hm_free(_new_map_);
|
||||
success:
|
||||
if (_map_->callbacks && _map_->callbacks->resize)
|
||||
_map_->callbacks->resize();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->resize)
|
||||
(_map_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct hashmap *hm_copy_of(struct hashmap *_map_)
|
||||
{
|
||||
struct hashmap *result = hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val,
|
||||
_map_->alloc, _map_->callbacks);
|
||||
_map_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
{
|
||||
_map_->flag = CMC_FLAG_ERROR;
|
||||
return ((void *)0);
|
||||
}
|
||||
(result)->callbacks = _map_->callbacks;
|
||||
if (_map_->f_key->cpy || _map_->f_val->cpy)
|
||||
{
|
||||
for (size_t i = 0; i < _map_->capacity; i++)
|
||||
@@ -522,17 +540,97 @@ _Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_)
|
||||
_map2_->flag = CMC_FLAG_OK;
|
||||
if (_map1_->count != _map2_->count)
|
||||
return 0;
|
||||
struct hashmap_iter iter = hm_iter_start(_map1_);
|
||||
for (; !hm_iter_at_end(&iter); hm_iter_next(&iter))
|
||||
struct hashmap *_map_a_;
|
||||
struct hashmap *_map_b_;
|
||||
_map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_;
|
||||
_map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_;
|
||||
for (size_t i = 0; i < _map_a_->capacity; i++)
|
||||
{
|
||||
struct hashmap_entry *entry = hm_impl_get_entry(_map2_, hm_iter_key(&iter));
|
||||
if (entry == ((void *)0))
|
||||
return 0;
|
||||
if (_map1_->f_val->cmp(entry->value, hm_iter_value(&iter)) != 0)
|
||||
return 0;
|
||||
if (_map_a_->buffer[i].state == CMC_ES_FILLED)
|
||||
{
|
||||
struct hashmap_entry *entry_a = &(_map_a_->buffer[i]);
|
||||
struct hashmap_entry *entry_b = hm_impl_get_entry(_map_b_, entry_a->key);
|
||||
if (!entry_b)
|
||||
return 0;
|
||||
if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key)
|
||||
{
|
||||
size_t hash = _map_->f_key->hash(key);
|
||||
size_t pos = hash % _map_->capacity;
|
||||
struct hashmap_entry *target = &(_map_->buffer[pos]);
|
||||
while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
|
||||
{
|
||||
if (_map_->f_key->cmp(target->key, key) == 0)
|
||||
return target;
|
||||
pos++;
|
||||
target = &(_map_->buffer[pos % _map_->capacity]);
|
||||
}
|
||||
return ((void *)0);
|
||||
}
|
||||
static size_t hm_impl_calculate_size(size_t required)
|
||||
{
|
||||
const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
|
||||
if (cmc_hashtable_primes[count - 1] < required)
|
||||
return required;
|
||||
size_t i = 0;
|
||||
while (cmc_hashtable_primes[i] < required)
|
||||
i++;
|
||||
return cmc_hashtable_primes[i];
|
||||
}
|
||||
struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val)
|
||||
{
|
||||
return hm_init_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val,
|
||||
struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
struct hashmap _map_ = { 0 };
|
||||
if (capacity == 0 || load <= 0 || load >= 1)
|
||||
return _map_;
|
||||
if (capacity >= 0xffffffffffffffffULL * load)
|
||||
return _map_;
|
||||
if (!f_key || !f_val)
|
||||
return _map_;
|
||||
size_t real_capacity = hm_impl_calculate_size(capacity / load);
|
||||
if (!alloc)
|
||||
alloc = &cmc_alloc_node_default;
|
||||
_map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry));
|
||||
if (!_map_.buffer)
|
||||
return _map_;
|
||||
_map_.count = 0;
|
||||
_map_.capacity = real_capacity;
|
||||
_map_.load = load;
|
||||
_map_.flag = CMC_FLAG_OK;
|
||||
_map_.f_key = f_key;
|
||||
_map_.f_val = f_val;
|
||||
_map_.alloc = alloc;
|
||||
(&_map_)->callbacks = callbacks;
|
||||
return _map_;
|
||||
}
|
||||
void hm_release(struct hashmap _map_)
|
||||
{
|
||||
if (_map_.f_key->free || _map_.f_val->free)
|
||||
{
|
||||
for (size_t i = 0; i < _map_.capacity; i++)
|
||||
{
|
||||
struct hashmap_entry *entry = &(_map_.buffer[i]);
|
||||
if (entry->state == CMC_ES_FILLED)
|
||||
{
|
||||
if (_map_.f_key->free)
|
||||
_map_.f_key->free(entry->key);
|
||||
if (_map_.f_val->free)
|
||||
_map_.f_val->free(entry->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
_map_.alloc->free(_map_.buffer);
|
||||
}
|
||||
struct hashmap_iter hm_iter_start(struct hashmap *target)
|
||||
{
|
||||
struct hashmap_iter iter;
|
||||
@@ -734,29 +832,57 @@ size_t hm_iter_index(struct hashmap_iter *iter)
|
||||
{
|
||||
return iter->index;
|
||||
}
|
||||
static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key)
|
||||
_Bool hm_to_string(struct hashmap *_map_, FILE *fptr)
|
||||
{
|
||||
size_t hash = _map_->f_key->hash(key);
|
||||
size_t pos = hash % _map_->capacity;
|
||||
struct hashmap_entry *target = &(_map_->buffer[pos]);
|
||||
while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
|
||||
{
|
||||
if (_map_->f_key->cmp(target->key, key) == 0)
|
||||
return target;
|
||||
pos++;
|
||||
target = &(_map_->buffer[pos % _map_->capacity]);
|
||||
}
|
||||
return ((void *)0);
|
||||
struct hashmap *m_ = _map_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s, %s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"load:%lf, "
|
||||
"flag:%d, "
|
||||
"f_key:%p, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"hashmap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag,
|
||||
m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks);
|
||||
}
|
||||
static size_t hm_impl_calculate_size(size_t required)
|
||||
_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
|
||||
const char *key_val_sep)
|
||||
{
|
||||
const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
|
||||
if (cmc_hashtable_primes[count - 1] < required)
|
||||
return required;
|
||||
size_t i = 0;
|
||||
while (cmc_hashtable_primes[i] < required)
|
||||
i++;
|
||||
return cmc_hashtable_primes[i];
|
||||
fprintf(fptr, "%s", start);
|
||||
size_t last = 0;
|
||||
for (size_t i = _map_->capacity; i > 0; i--)
|
||||
{
|
||||
if ((_map_->buffer[i - 1]).state == CMC_ES_FILLED)
|
||||
{
|
||||
last = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < _map_->capacity; i++)
|
||||
{
|
||||
struct hashmap_entry *entry = &(_map_->buffer[i]);
|
||||
if (entry->state == CMC_ES_FILLED)
|
||||
{
|
||||
if (!_map_->f_key->str(fptr, entry->key))
|
||||
return 0;
|
||||
fprintf(fptr, "%s", key_val_sep);
|
||||
if (!_map_->f_val->str(fptr, entry->value))
|
||||
return 0;
|
||||
if (i + 1 < last)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_HASHMAP */
|
||||
+155
-108
@@ -40,17 +40,6 @@ struct hashmultimap_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct hashmultimap_iter
|
||||
{
|
||||
struct hashmultimap *target;
|
||||
struct hashmultimap_entry *curr_entry;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
size_t first;
|
||||
size_t last;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key,
|
||||
struct hashmultimap_fval *f_val);
|
||||
struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key,
|
||||
@@ -79,8 +68,17 @@ int hmm_flag(struct hashmultimap *_map_);
|
||||
_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity);
|
||||
struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_);
|
||||
_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_);
|
||||
struct cmc_string hmm_to_string(struct hashmultimap *_map_);
|
||||
_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr);
|
||||
struct hashmultimap_iter
|
||||
{
|
||||
struct hashmultimap *target;
|
||||
struct hashmultimap_entry *curr_entry;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
size_t first;
|
||||
size_t last;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target);
|
||||
struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target);
|
||||
_Bool hmm_iter_at_start(struct hashmultimap_iter *iter);
|
||||
@@ -96,6 +94,9 @@ size_t hmm_iter_key(struct hashmultimap_iter *iter);
|
||||
size_t hmm_iter_value(struct hashmultimap_iter *iter);
|
||||
size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter);
|
||||
size_t hmm_iter_index(struct hashmultimap_iter *iter);
|
||||
_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr);
|
||||
_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
|
||||
const char *key_val_sep);
|
||||
struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value);
|
||||
struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key);
|
||||
size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key);
|
||||
@@ -103,37 +104,13 @@ size_t hmm_impl_calculate_size(size_t required);
|
||||
struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key,
|
||||
struct hashmultimap_fval *f_val)
|
||||
{
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
if (capacity == 0 || load <= 0)
|
||||
return ((void *)0);
|
||||
if (capacity >= 0xffffffffffffffffULL * load)
|
||||
return ((void *)0);
|
||||
if (!f_key || !f_val)
|
||||
return ((void *)0);
|
||||
size_t real_capacity = hmm_impl_calculate_size(capacity / load);
|
||||
struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap));
|
||||
if (!_map_)
|
||||
return ((void *)0);
|
||||
_map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2]));
|
||||
if (!_map_->buffer)
|
||||
{
|
||||
alloc->free(_map_);
|
||||
return ((void *)0);
|
||||
}
|
||||
_map_->count = 0;
|
||||
_map_->capacity = real_capacity;
|
||||
_map_->load = load;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
_map_->f_key = f_key;
|
||||
_map_->f_val = f_val;
|
||||
_map_->alloc = alloc;
|
||||
_map_->callbacks = ((void *)0);
|
||||
return _map_;
|
||||
return hmm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key,
|
||||
struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity == 0 || load <= 0)
|
||||
return ((void *)0);
|
||||
if (capacity >= 0xffffffffffffffffULL * load)
|
||||
@@ -159,7 +136,7 @@ struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmul
|
||||
_map_->f_key = f_key;
|
||||
_map_->f_val = f_val;
|
||||
_map_->alloc = alloc;
|
||||
_map_->callbacks = callbacks;
|
||||
(_map_)->callbacks = callbacks;
|
||||
return _map_;
|
||||
}
|
||||
void hmm_clear(struct hashmultimap *_map_)
|
||||
@@ -219,11 +196,12 @@ void hmm_free(struct hashmultimap *_map_)
|
||||
}
|
||||
void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_map_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_map_->alloc = alloc;
|
||||
_map_->callbacks = callbacks;
|
||||
(_map_)->callbacks = callbacks;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value)
|
||||
@@ -249,8 +227,9 @@ _Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value)
|
||||
}
|
||||
_map_->count++;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->create)
|
||||
_map_->callbacks->create();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->create)
|
||||
(_map_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value)
|
||||
@@ -270,8 +249,9 @@ _Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_
|
||||
*old_value = entry->value;
|
||||
entry->value = new_value;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->update)
|
||||
_map_->callbacks->update();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->update)
|
||||
(_map_)->callbacks->update();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values)
|
||||
@@ -316,8 +296,9 @@ size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value,
|
||||
entry = entry->next;
|
||||
}
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->update)
|
||||
_map_->callbacks->update();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->update)
|
||||
(_map_)->callbacks->update();
|
||||
;
|
||||
return index;
|
||||
}
|
||||
_Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value)
|
||||
@@ -383,8 +364,9 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value)
|
||||
_map_->alloc->free(entry);
|
||||
_map_->count--;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->delete)
|
||||
_map_->callbacks->delete ();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->delete)
|
||||
(_map_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values)
|
||||
@@ -455,8 +437,9 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_value
|
||||
}
|
||||
_map_->count -= index;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->delete)
|
||||
_map_->callbacks->delete ();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->delete)
|
||||
(_map_)->callbacks->delete ();
|
||||
;
|
||||
return index;
|
||||
}
|
||||
_Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value)
|
||||
@@ -490,8 +473,9 @@ _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value)
|
||||
if (value)
|
||||
*value = max_val;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value)
|
||||
@@ -525,8 +509,9 @@ _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value)
|
||||
if (value)
|
||||
*value = min_val;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t hmm_get(struct hashmultimap *_map_, size_t key)
|
||||
@@ -543,8 +528,9 @@ size_t hmm_get(struct hashmultimap *_map_, size_t key)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return entry->value;
|
||||
}
|
||||
size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key)
|
||||
@@ -561,16 +547,18 @@ size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key)
|
||||
return ((void *)0);
|
||||
}
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return &(entry->value);
|
||||
}
|
||||
_Bool hmm_contains(struct hashmultimap *_map_, size_t key)
|
||||
{
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
_Bool result = hmm_impl_get_entry(_map_, key) != ((void *)0);
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool hmm_empty(struct hashmultimap *_map_)
|
||||
@@ -649,8 +637,9 @@ _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity)
|
||||
_new_map_->f_val = &(struct hashmultimap_fval){ ((void *)0) };
|
||||
hmm_free(_new_map_);
|
||||
success:
|
||||
if (_map_->callbacks && _map_->callbacks->resize)
|
||||
_map_->callbacks->resize();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->resize)
|
||||
(_map_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_)
|
||||
@@ -676,7 +665,7 @@ struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_)
|
||||
hmm_insert(result, key, value);
|
||||
}
|
||||
}
|
||||
result->callbacks = _map_->callbacks;
|
||||
(result)->callbacks = _map_->callbacks;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
return result;
|
||||
}
|
||||
@@ -695,6 +684,54 @@ _Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value)
|
||||
{
|
||||
struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry));
|
||||
if (!entry)
|
||||
return ((void *)0);
|
||||
entry->key = key;
|
||||
entry->value = value;
|
||||
entry->next = ((void *)0);
|
||||
entry->prev = ((void *)0);
|
||||
return entry;
|
||||
}
|
||||
struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key)
|
||||
{
|
||||
size_t hash = _map_->f_key->hash(key);
|
||||
struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0];
|
||||
while (entry != ((void *)0))
|
||||
{
|
||||
if (_map_->f_key->cmp(entry->key, key) == 0)
|
||||
return entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
return ((void *)0);
|
||||
}
|
||||
size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key)
|
||||
{
|
||||
size_t hash = _map_->f_key->hash(key);
|
||||
struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0];
|
||||
size_t total_count = 0;
|
||||
if (!entry)
|
||||
return total_count;
|
||||
while (entry != ((void *)0))
|
||||
{
|
||||
if (_map_->f_key->cmp(entry->key, key) == 0)
|
||||
total_count++;
|
||||
entry = entry->next;
|
||||
}
|
||||
return total_count;
|
||||
}
|
||||
size_t hmm_impl_calculate_size(size_t required)
|
||||
{
|
||||
const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
|
||||
if (cmc_hashtable_primes[count - 1] < required)
|
||||
return required;
|
||||
size_t i = 0;
|
||||
while (cmc_hashtable_primes[i] < required)
|
||||
i++;
|
||||
return cmc_hashtable_primes[i];
|
||||
}
|
||||
struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target)
|
||||
{
|
||||
struct hashmultimap_iter iter;
|
||||
@@ -710,7 +747,8 @@ struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target)
|
||||
{
|
||||
for (size_t i = 0; i < target->capacity; i++)
|
||||
{
|
||||
if (target->buffer[i][0] != ((void *)0))
|
||||
struct hashmultimap_entry *entry = target->buffer[i][0];
|
||||
if (entry && entry != ((void *)1))
|
||||
{
|
||||
iter.curr_entry = target->buffer[i][0];
|
||||
iter.first = i;
|
||||
@@ -720,7 +758,8 @@ struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target)
|
||||
iter.cursor = iter.first;
|
||||
for (size_t i = target->capacity; i > 0; i--)
|
||||
{
|
||||
if (target->buffer[i - 1][1] != ((void *)0))
|
||||
struct hashmultimap_entry *entry = target->buffer[i - 1][1];
|
||||
if (entry && entry != ((void *)1))
|
||||
{
|
||||
iter.last = i - 1;
|
||||
break;
|
||||
@@ -744,7 +783,8 @@ struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target)
|
||||
{
|
||||
for (size_t i = 0; i < target->capacity; i++)
|
||||
{
|
||||
if (target->buffer[i][0] != ((void *)0))
|
||||
struct hashmultimap_entry *entry = target->buffer[i][0];
|
||||
if (entry && entry != ((void *)1))
|
||||
{
|
||||
iter.first = i;
|
||||
break;
|
||||
@@ -752,7 +792,8 @@ struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target)
|
||||
}
|
||||
for (size_t i = target->capacity; i > 0; i--)
|
||||
{
|
||||
if (target->buffer[i - 1][1] != ((void *)0))
|
||||
struct hashmultimap_entry *entry = target->buffer[i - 1][1];
|
||||
if (entry && entry != ((void *)1))
|
||||
{
|
||||
iter.curr_entry = target->buffer[i - 1][1];
|
||||
iter.last = i - 1;
|
||||
@@ -910,53 +951,59 @@ size_t hmm_iter_index(struct hashmultimap_iter *iter)
|
||||
{
|
||||
return iter->index;
|
||||
}
|
||||
struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value)
|
||||
_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr)
|
||||
{
|
||||
struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry));
|
||||
if (!entry)
|
||||
return ((void *)0);
|
||||
entry->key = key;
|
||||
entry->value = value;
|
||||
entry->next = ((void *)0);
|
||||
entry->prev = ((void *)0);
|
||||
return entry;
|
||||
struct hashmultimap *m_ = _map_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s, %s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"load:%lf, "
|
||||
"flag:%d, "
|
||||
"f_key:%p, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"hashmultimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag,
|
||||
m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks);
|
||||
}
|
||||
struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key)
|
||||
_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
|
||||
const char *key_val_sep)
|
||||
{
|
||||
size_t hash = _map_->f_key->hash(key);
|
||||
struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0];
|
||||
while (entry != ((void *)0))
|
||||
fprintf(fptr, "%s", start);
|
||||
size_t last = 0;
|
||||
for (size_t i = _map_->capacity; i > 0; i--)
|
||||
{
|
||||
if (_map_->f_key->cmp(entry->key, key) == 0)
|
||||
return entry;
|
||||
entry = entry->next;
|
||||
struct hashmultimap_entry *entry = _map_->buffer[i - 1][1];
|
||||
if (entry && entry != ((void *)1))
|
||||
{
|
||||
last = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ((void *)0);
|
||||
}
|
||||
size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key)
|
||||
{
|
||||
size_t hash = _map_->f_key->hash(key);
|
||||
struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0];
|
||||
size_t total_count = 0;
|
||||
if (!entry)
|
||||
return total_count;
|
||||
while (entry != ((void *)0))
|
||||
for (size_t i = 0; i < _map_->capacity; i++)
|
||||
{
|
||||
if (_map_->f_key->cmp(entry->key, key) == 0)
|
||||
total_count++;
|
||||
entry = entry->next;
|
||||
struct hashmultimap_entry *scan = _map_->buffer[i][0];
|
||||
while (scan != ((void *)0))
|
||||
{
|
||||
if (!_map_->f_key->str(fptr, scan->key))
|
||||
return 0;
|
||||
fprintf(fptr, "%s", key_val_sep);
|
||||
if (!_map_->f_val->str(fptr, scan->value))
|
||||
return 0;
|
||||
scan = scan->next;
|
||||
if (i + 1 < last)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
}
|
||||
return total_count;
|
||||
}
|
||||
size_t hmm_impl_calculate_size(size_t required)
|
||||
{
|
||||
const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
|
||||
if (cmc_hashtable_primes[count - 1] < required)
|
||||
return required;
|
||||
size_t i = 0;
|
||||
while (cmc_hashtable_primes[i] < required)
|
||||
i++;
|
||||
return cmc_hashtable_primes[i];
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_HASHMULTIMAP */
|
||||
+357
-310
@@ -31,16 +31,6 @@ struct hashmultiset_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct hashmultiset_iter
|
||||
{
|
||||
struct hashmultiset *target;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
size_t first;
|
||||
size_t last;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val);
|
||||
struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val,
|
||||
struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
|
||||
@@ -66,18 +56,16 @@ int hms_flag(struct hashmultiset *_set_);
|
||||
_Bool hms_resize(struct hashmultiset *_set_, size_t capacity);
|
||||
struct hashmultiset *hms_copy_of(struct hashmultiset *_set_);
|
||||
_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
struct cmc_string hms_to_string(struct hashmultiset *_set_);
|
||||
_Bool hms_print(struct hashmultiset *_set_, FILE *fptr);
|
||||
struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
struct hashmultiset_iter
|
||||
{
|
||||
struct hashmultiset *target;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
size_t first;
|
||||
size_t last;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct hashmultiset_iter hms_iter_start(struct hashmultiset *target);
|
||||
struct hashmultiset_iter hms_iter_end(struct hashmultiset *target);
|
||||
_Bool hms_iter_at_start(struct hashmultiset_iter *iter);
|
||||
@@ -92,42 +80,31 @@ _Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index);
|
||||
size_t hms_iter_value(struct hashmultiset_iter *iter);
|
||||
size_t hms_iter_multiplicity(struct hashmultiset_iter *iter);
|
||||
size_t hms_iter_index(struct hashmultiset_iter *iter);
|
||||
struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
|
||||
_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr);
|
||||
_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end,
|
||||
const char *key_val_sep);
|
||||
static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value);
|
||||
static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node);
|
||||
static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value);
|
||||
static size_t hms_impl_calculate_size(size_t required);
|
||||
struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val)
|
||||
{
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
if (capacity == 0 || load <= 0 || load >= 1)
|
||||
return ((void *)0);
|
||||
if (capacity >= 0xffffffffffffffffULL * load)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
return ((void *)0);
|
||||
size_t real_capacity = hms_impl_calculate_size(capacity / load);
|
||||
struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset));
|
||||
if (!_set_)
|
||||
return ((void *)0);
|
||||
_set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry));
|
||||
if (!_set_->buffer)
|
||||
{
|
||||
alloc->free(_set_);
|
||||
return ((void *)0);
|
||||
}
|
||||
_set_->count = 0;
|
||||
_set_->cardinality = 0;
|
||||
_set_->capacity = real_capacity;
|
||||
_set_->load = load;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
_set_->f_val = f_val;
|
||||
_set_->alloc = alloc;
|
||||
_set_->callbacks = ((void *)0);
|
||||
return _set_;
|
||||
return hms_new_custom(capacity, load, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val,
|
||||
struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity == 0 || load <= 0 || load >= 1)
|
||||
return ((void *)0);
|
||||
if (capacity >= 0xffffffffffffffffULL * load)
|
||||
@@ -153,7 +130,7 @@ struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmul
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
_set_->f_val = f_val;
|
||||
_set_->alloc = alloc;
|
||||
_set_->callbacks = callbacks;
|
||||
(_set_)->callbacks = callbacks;
|
||||
return _set_;
|
||||
}
|
||||
void hms_clear(struct hashmultiset *_set_)
|
||||
@@ -191,11 +168,12 @@ void hms_free(struct hashmultiset *_set_)
|
||||
}
|
||||
void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_set_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_set_->alloc = alloc;
|
||||
_set_->callbacks = callbacks;
|
||||
(_set_)->callbacks = callbacks;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool hms_insert(struct hashmultiset *_set_, size_t value)
|
||||
@@ -211,8 +189,9 @@ _Bool hms_insert(struct hashmultiset *_set_, size_t value)
|
||||
entry->multiplicity++;
|
||||
_set_->cardinality++;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->create)
|
||||
_set_->callbacks->create();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->create)
|
||||
(_set_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count)
|
||||
@@ -233,8 +212,9 @@ _Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count)
|
||||
_set_->cardinality += count;
|
||||
success:
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->create)
|
||||
_set_->callbacks->create();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->create)
|
||||
(_set_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity)
|
||||
@@ -262,8 +242,9 @@ _Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity)
|
||||
entry->multiplicity = multiplicity;
|
||||
success:
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->update)
|
||||
_set_->callbacks->update();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->update)
|
||||
(_set_)->callbacks->update();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hms_remove(struct hashmultiset *_set_, size_t value)
|
||||
@@ -291,8 +272,9 @@ _Bool hms_remove(struct hashmultiset *_set_, size_t value)
|
||||
}
|
||||
_set_->cardinality--;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->delete)
|
||||
_set_->callbacks->delete ();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->delete)
|
||||
(_set_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t hms_remove_all(struct hashmultiset *_set_, size_t value)
|
||||
@@ -316,8 +298,9 @@ size_t hms_remove_all(struct hashmultiset *_set_, size_t value)
|
||||
_set_->count--;
|
||||
_set_->cardinality -= removed;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->delete)
|
||||
_set_->callbacks->delete ();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->delete)
|
||||
(_set_)->callbacks->delete ();
|
||||
;
|
||||
return removed;
|
||||
}
|
||||
_Bool hms_max(struct hashmultiset *_set_, size_t *value)
|
||||
@@ -341,8 +324,9 @@ _Bool hms_max(struct hashmultiset *_set_, size_t *value)
|
||||
if (value)
|
||||
*value = max_val;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->read)
|
||||
_set_->callbacks->read();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hms_min(struct hashmultiset *_set_, size_t *value)
|
||||
@@ -366,16 +350,18 @@ _Bool hms_min(struct hashmultiset *_set_, size_t *value)
|
||||
if (value)
|
||||
*value = min_val;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->read)
|
||||
_set_->callbacks->read();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value)
|
||||
{
|
||||
struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value);
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->read)
|
||||
_set_->callbacks->read();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
;
|
||||
if (!entry)
|
||||
return 0;
|
||||
return entry->multiplicity;
|
||||
@@ -384,8 +370,9 @@ _Bool hms_contains(struct hashmultiset *_set_, size_t value)
|
||||
{
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
_Bool result = hms_impl_get_entry(_set_, value) != ((void *)0);
|
||||
if (_set_->callbacks && _set_->callbacks->read)
|
||||
_set_->callbacks->read();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool hms_empty(struct hashmultiset *_set_)
|
||||
@@ -460,19 +447,21 @@ _Bool hms_resize(struct hashmultiset *_set_, size_t capacity)
|
||||
_new_set_->f_val = &(struct hashmultiset_fval){ ((void *)0) };
|
||||
hms_free(_new_set_);
|
||||
success:
|
||||
if (_set_->callbacks && _set_->callbacks->resize)
|
||||
_set_->callbacks->resize();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->resize)
|
||||
(_set_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct hashmultiset *hms_copy_of(struct hashmultiset *_set_)
|
||||
{
|
||||
struct hashmultiset *result =
|
||||
hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, _set_->callbacks);
|
||||
hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
{
|
||||
_set_->flag = CMC_FLAG_ERROR;
|
||||
return ((void *)0);
|
||||
}
|
||||
(result)->callbacks = _set_->callbacks;
|
||||
if (_set_->f_val->cpy)
|
||||
{
|
||||
for (size_t i = 0; i < _set_->capacity; i++)
|
||||
@@ -521,186 +510,97 @@ _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value)
|
||||
{
|
||||
struct hashmultiset *_set_r_ =
|
||||
hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
|
||||
struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
|
||||
for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter1);
|
||||
size_t m1 = hms_iter_multiplicity(&iter1);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set2_, value);
|
||||
size_t max_ = m1 > m2 ? m1 : m2;
|
||||
hms_update(_set_r_, value, max_);
|
||||
}
|
||||
for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter2);
|
||||
size_t m1 = hms_impl_multiplicity_of(_set1_, value);
|
||||
size_t m2 = hms_iter_multiplicity(&iter2);
|
||||
size_t max_ = m1 > m2 ? m1 : m2;
|
||||
hms_update(_set_r_, value, max_);
|
||||
}
|
||||
_set_r_->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value);
|
||||
if (!entry)
|
||||
return 0;
|
||||
return entry->multiplicity;
|
||||
}
|
||||
struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node)
|
||||
{
|
||||
struct hashmultiset *_set_r_ =
|
||||
hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_;
|
||||
struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_;
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set_A_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
*new_node = 0;
|
||||
struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value);
|
||||
if (entry != ((void *)0))
|
||||
return entry;
|
||||
*new_node = 1;
|
||||
if (hms_full(_set_))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter);
|
||||
size_t m1 = hms_iter_multiplicity(&iter);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set_B_, value);
|
||||
size_t max_ = m1 < m2 ? m1 : m2;
|
||||
hms_update(_set_r_, value, max_);
|
||||
if (!hms_resize(_set_, _set_->capacity + 1))
|
||||
return ((void *)0);
|
||||
}
|
||||
_set_r_->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
struct hashmultiset *_set_r_ =
|
||||
hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set1_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
size_t hash = _set_->f_val->hash(value);
|
||||
size_t original_pos = hash % _set_->capacity;
|
||||
size_t pos = original_pos;
|
||||
size_t curr_mul = 1;
|
||||
struct hashmultiset_entry *target = &(_set_->buffer[pos]);
|
||||
struct hashmultiset_entry *to_return = ((void *)0);
|
||||
if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED)
|
||||
{
|
||||
size_t value = hms_iter_value(&iter);
|
||||
size_t m1 = hms_iter_multiplicity(&iter);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set2_, value);
|
||||
if (m1 > m2)
|
||||
hms_update(_set_r_, value, m1 - m2);
|
||||
target->value = value;
|
||||
target->multiplicity = curr_mul;
|
||||
target->dist = pos - original_pos;
|
||||
target->state = CMC_ES_FILLED;
|
||||
to_return = target;
|
||||
}
|
||||
_set_r_->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
struct hashmultiset *_set_r_ =
|
||||
hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
|
||||
struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
|
||||
for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
|
||||
else
|
||||
{
|
||||
hms_insert_many(_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1));
|
||||
}
|
||||
for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
|
||||
{
|
||||
hms_insert_many(_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2));
|
||||
}
|
||||
_set_r_->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
struct hashmultiset *_set_r_ =
|
||||
hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
|
||||
struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
|
||||
for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter1);
|
||||
size_t m1 = hms_iter_multiplicity(&iter1);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set2_, value);
|
||||
if (m1 != m2)
|
||||
while (1)
|
||||
{
|
||||
if (m1 > m2)
|
||||
hms_update(_set_r_, value, m1 - m2);
|
||||
else
|
||||
hms_update(_set_r_, value, m2 - m1);
|
||||
pos++;
|
||||
target = &(_set_->buffer[pos % _set_->capacity]);
|
||||
if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED)
|
||||
{
|
||||
target->value = value;
|
||||
target->multiplicity = curr_mul;
|
||||
target->dist = pos - original_pos;
|
||||
target->state = CMC_ES_FILLED;
|
||||
if (!to_return)
|
||||
to_return = target;
|
||||
break;
|
||||
}
|
||||
else if (target->dist < pos - original_pos)
|
||||
{
|
||||
size_t tmp = target->value;
|
||||
size_t tmp_dist = target->dist;
|
||||
size_t tmp_mul = target->multiplicity;
|
||||
target->value = value;
|
||||
target->dist = pos - original_pos;
|
||||
target->multiplicity = curr_mul;
|
||||
value = tmp;
|
||||
original_pos = pos - tmp_dist;
|
||||
curr_mul = tmp_mul;
|
||||
if (!to_return)
|
||||
to_return = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter2);
|
||||
size_t m1 = hms_impl_multiplicity_of(_set1_, value);
|
||||
size_t m2 = hms_iter_multiplicity(&iter2);
|
||||
if (m1 != m2)
|
||||
{
|
||||
if (m1 > m2)
|
||||
hms_update(_set_r_, value, m1 - m2);
|
||||
else
|
||||
hms_update(_set_r_, value, m2 - m1);
|
||||
}
|
||||
}
|
||||
_set_r_->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
_set_->count++;
|
||||
return to_return;
|
||||
}
|
||||
_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value)
|
||||
{
|
||||
if (_set1_->count > _set2_->count)
|
||||
return 0;
|
||||
if (hms_empty(_set1_))
|
||||
return 1;
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set1_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
size_t hash = _set_->f_val->hash(value);
|
||||
size_t pos = hash % _set_->capacity;
|
||||
struct hashmultiset_entry *target = &(_set_->buffer[pos]);
|
||||
while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
|
||||
{
|
||||
size_t value = hms_iter_value(&iter);
|
||||
size_t m1 = hms_iter_multiplicity(&iter);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set2_, value);
|
||||
if (m1 > m2)
|
||||
return 0;
|
||||
if (_set_->f_val->cmp(target->value, value) == 0)
|
||||
return target;
|
||||
pos++;
|
||||
target = &(_set_->buffer[pos % _set_->capacity]);
|
||||
}
|
||||
return 1;
|
||||
return ((void *)0);
|
||||
}
|
||||
_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
static size_t hms_impl_calculate_size(size_t required)
|
||||
{
|
||||
return hms_is_subset(_set2_, _set1_);
|
||||
}
|
||||
_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
if (_set1_->count >= _set2_->count)
|
||||
return 0;
|
||||
if (hms_empty(_set1_))
|
||||
{
|
||||
if (!hms_empty(_set2_))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set1_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter);
|
||||
size_t m1 = hms_iter_multiplicity(&iter);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set2_, value);
|
||||
if (m1 >= m2)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
return hms_is_proper_subset(_set2_, _set1_);
|
||||
}
|
||||
_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
if (hms_empty(_set1_))
|
||||
return 1;
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set1_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter);
|
||||
if (hms_impl_get_entry(_set2_, value) != ((void *)0))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
|
||||
if (cmc_hashtable_primes[count - 1] < required)
|
||||
return required;
|
||||
size_t i = 0;
|
||||
while (cmc_hashtable_primes[i] < required)
|
||||
i++;
|
||||
return cmc_hashtable_primes[i];
|
||||
}
|
||||
struct hashmultiset_iter hms_iter_start(struct hashmultiset *target)
|
||||
{
|
||||
@@ -897,97 +797,244 @@ size_t hms_iter_index(struct hashmultiset_iter *iter)
|
||||
{
|
||||
return iter->index;
|
||||
}
|
||||
static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value)
|
||||
struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value);
|
||||
if (!entry)
|
||||
return 0;
|
||||
return entry->multiplicity;
|
||||
struct hashmultiset *_set_r_ =
|
||||
hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
|
||||
struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
|
||||
for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter1);
|
||||
size_t m1 = hms_iter_multiplicity(&iter1);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set2_, value);
|
||||
size_t max_ = m1 > m2 ? m1 : m2;
|
||||
hms_update(_set_r_, value, max_);
|
||||
}
|
||||
for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter2);
|
||||
size_t m1 = hms_impl_multiplicity_of(_set1_, value);
|
||||
size_t m2 = hms_iter_multiplicity(&iter2);
|
||||
size_t max_ = m1 > m2 ? m1 : m2;
|
||||
hms_update(_set_r_, value, max_);
|
||||
}
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node)
|
||||
struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
*new_node = 0;
|
||||
struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value);
|
||||
if (entry != ((void *)0))
|
||||
return entry;
|
||||
*new_node = 1;
|
||||
if (hms_full(_set_))
|
||||
struct hashmultiset *_set_r_ =
|
||||
hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_;
|
||||
struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_;
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set_A_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
{
|
||||
if (!hms_resize(_set_, _set_->capacity + 1))
|
||||
return ((void *)0);
|
||||
size_t value = hms_iter_value(&iter);
|
||||
size_t m1 = hms_iter_multiplicity(&iter);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set_B_, value);
|
||||
size_t max_ = m1 < m2 ? m1 : m2;
|
||||
hms_update(_set_r_, value, max_);
|
||||
}
|
||||
size_t hash = _set_->f_val->hash(value);
|
||||
size_t original_pos = hash % _set_->capacity;
|
||||
size_t pos = original_pos;
|
||||
size_t curr_mul = 1;
|
||||
struct hashmultiset_entry *target = &(_set_->buffer[pos]);
|
||||
struct hashmultiset_entry *to_return = ((void *)0);
|
||||
if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED)
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
struct hashmultiset *_set_r_ =
|
||||
hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set1_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
{
|
||||
target->value = value;
|
||||
target->multiplicity = curr_mul;
|
||||
target->dist = pos - original_pos;
|
||||
target->state = CMC_ES_FILLED;
|
||||
to_return = target;
|
||||
size_t value = hms_iter_value(&iter);
|
||||
size_t m1 = hms_iter_multiplicity(&iter);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set2_, value);
|
||||
if (m1 > m2)
|
||||
hms_update(_set_r_, value, m1 - m2);
|
||||
}
|
||||
else
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
struct hashmultiset *_set_r_ =
|
||||
hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
|
||||
struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
|
||||
for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
|
||||
{
|
||||
while (1)
|
||||
hms_insert_many(_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1));
|
||||
}
|
||||
for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
|
||||
{
|
||||
hms_insert_many(_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2));
|
||||
}
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
struct hashmultiset *_set_r_ =
|
||||
hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
|
||||
struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
|
||||
for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter1);
|
||||
size_t m1 = hms_iter_multiplicity(&iter1);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set2_, value);
|
||||
if (m1 != m2)
|
||||
{
|
||||
pos++;
|
||||
target = &(_set_->buffer[pos % _set_->capacity]);
|
||||
if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED)
|
||||
{
|
||||
target->value = value;
|
||||
target->multiplicity = curr_mul;
|
||||
target->dist = pos - original_pos;
|
||||
target->state = CMC_ES_FILLED;
|
||||
if (!to_return)
|
||||
to_return = target;
|
||||
break;
|
||||
}
|
||||
else if (target->dist < pos - original_pos)
|
||||
{
|
||||
size_t tmp = target->value;
|
||||
size_t tmp_dist = target->dist;
|
||||
size_t tmp_mul = target->multiplicity;
|
||||
target->value = value;
|
||||
target->dist = pos - original_pos;
|
||||
target->multiplicity = curr_mul;
|
||||
value = tmp;
|
||||
original_pos = pos - tmp_dist;
|
||||
curr_mul = tmp_mul;
|
||||
if (!to_return)
|
||||
to_return = target;
|
||||
}
|
||||
if (m1 > m2)
|
||||
hms_update(_set_r_, value, m1 - m2);
|
||||
else
|
||||
hms_update(_set_r_, value, m2 - m1);
|
||||
}
|
||||
}
|
||||
_set_->count++;
|
||||
return to_return;
|
||||
}
|
||||
static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value)
|
||||
{
|
||||
size_t hash = _set_->f_val->hash(value);
|
||||
size_t pos = hash % _set_->capacity;
|
||||
struct hashmultiset_entry *target = &(_set_->buffer[pos]);
|
||||
while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
|
||||
for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
|
||||
{
|
||||
if (_set_->f_val->cmp(target->value, value) == 0)
|
||||
return target;
|
||||
pos++;
|
||||
target = &(_set_->buffer[pos % _set_->capacity]);
|
||||
size_t value = hms_iter_value(&iter2);
|
||||
size_t m1 = hms_impl_multiplicity_of(_set1_, value);
|
||||
size_t m2 = hms_iter_multiplicity(&iter2);
|
||||
if (m1 != m2)
|
||||
{
|
||||
if (m1 > m2)
|
||||
hms_update(_set_r_, value, m1 - m2);
|
||||
else
|
||||
hms_update(_set_r_, value, m2 - m1);
|
||||
}
|
||||
}
|
||||
return ((void *)0);
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
static size_t hms_impl_calculate_size(size_t required)
|
||||
_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
|
||||
if (cmc_hashtable_primes[count - 1] < required)
|
||||
return required;
|
||||
size_t i = 0;
|
||||
while (cmc_hashtable_primes[i] < required)
|
||||
i++;
|
||||
return cmc_hashtable_primes[i];
|
||||
if (_set1_->count > _set2_->count)
|
||||
return 0;
|
||||
if (hms_empty(_set1_))
|
||||
return 1;
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set1_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter);
|
||||
size_t m1 = hms_iter_multiplicity(&iter);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set2_, value);
|
||||
if (m1 > m2)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
return hms_is_subset(_set2_, _set1_);
|
||||
}
|
||||
_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
if (_set1_->count >= _set2_->count)
|
||||
return 0;
|
||||
if (hms_empty(_set1_))
|
||||
{
|
||||
if (!hms_empty(_set2_))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set1_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter);
|
||||
size_t m1 = hms_iter_multiplicity(&iter);
|
||||
size_t m2 = hms_impl_multiplicity_of(_set2_, value);
|
||||
if (m1 >= m2)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
return hms_is_proper_subset(_set2_, _set1_);
|
||||
}
|
||||
_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
|
||||
{
|
||||
if (hms_empty(_set1_))
|
||||
return 1;
|
||||
struct hashmultiset_iter iter = hms_iter_start(_set1_);
|
||||
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
|
||||
{
|
||||
size_t value = hms_iter_value(&iter);
|
||||
if (hms_impl_get_entry(_set2_, value) != ((void *)0))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr)
|
||||
{
|
||||
struct hashmultiset *s_ = _set_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"cardinality:%"
|
||||
"I64u"
|
||||
", "
|
||||
"load:%lf, "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"hashmultiset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->cardinality, s_->load,
|
||||
s_->flag, s_->f_val, s_->alloc, (s_)->callbacks);
|
||||
}
|
||||
_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end,
|
||||
const char *val_mul_sep)
|
||||
{
|
||||
fprintf(fptr, "%s", start);
|
||||
size_t last = 0;
|
||||
for (size_t i = _set_->capacity; i > 0; i--)
|
||||
{
|
||||
if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED)
|
||||
{
|
||||
last = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < _set_->capacity; i++)
|
||||
{
|
||||
struct hashmultiset_entry *entry = &(_set_->buffer[i]);
|
||||
if (entry->state == CMC_ES_FILLED)
|
||||
{
|
||||
if (!_set_->f_val->str(fptr, entry->value))
|
||||
return 0;
|
||||
fprintf(fptr, "%s", val_mul_sep);
|
||||
if (fprintf(fptr,
|
||||
"%"
|
||||
"I64u"
|
||||
"",
|
||||
entry->multiplicity) < 0)
|
||||
return 0;
|
||||
if (i + 1 < last)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_HASHMULTISET */
|
||||
+255
-225
@@ -29,16 +29,6 @@ struct hashset_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct hashset_iter
|
||||
{
|
||||
struct hashset *target;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
size_t first;
|
||||
size_t last;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val);
|
||||
struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks);
|
||||
@@ -59,17 +49,16 @@ int hs_flag(struct hashset *_set_);
|
||||
_Bool hs_resize(struct hashset *_set_, size_t capacity);
|
||||
struct hashset *hs_copy_of(struct hashset *_set_);
|
||||
_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_);
|
||||
struct cmc_string hs_to_string(struct hashset *_set_);
|
||||
_Bool hs_print(struct hashset *_set_, FILE *fptr);
|
||||
struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_);
|
||||
struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_);
|
||||
struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_);
|
||||
struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_);
|
||||
_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_);
|
||||
_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_);
|
||||
_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_);
|
||||
_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_);
|
||||
_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_);
|
||||
struct hashset_iter
|
||||
{
|
||||
struct hashset *target;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
size_t first;
|
||||
size_t last;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct hashset_iter hs_iter_start(struct hashset *target);
|
||||
struct hashset_iter hs_iter_end(struct hashset *target);
|
||||
_Bool hs_iter_at_start(struct hashset_iter *iter);
|
||||
@@ -83,41 +72,27 @@ _Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps);
|
||||
_Bool hs_iter_go_to(struct hashset_iter *iter, size_t index);
|
||||
size_t hs_iter_value(struct hashset_iter *iter);
|
||||
size_t hs_iter_index(struct hashset_iter *iter);
|
||||
struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_);
|
||||
struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_);
|
||||
struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_);
|
||||
struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_);
|
||||
_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_);
|
||||
_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_);
|
||||
_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_);
|
||||
_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_);
|
||||
_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_);
|
||||
_Bool hs_to_string(struct hashset *_set_, FILE *fptr);
|
||||
_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end);
|
||||
static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value);
|
||||
static size_t hs_impl_calculate_size(size_t required);
|
||||
static struct hashset_iter hs_impl_it_start(struct hashset *_set_);
|
||||
static struct hashset_iter hs_impl_it_end(struct hashset *_set_);
|
||||
struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val)
|
||||
{
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
if (capacity == 0 || load <= 0 || load >= 1)
|
||||
return ((void *)0);
|
||||
if (capacity >= 0xffffffffffffffffULL * load)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
return ((void *)0);
|
||||
size_t real_capacity = hs_impl_calculate_size(capacity / load);
|
||||
struct hashset *_set_ = alloc->malloc(sizeof(struct hashset));
|
||||
if (!_set_)
|
||||
return ((void *)0);
|
||||
_set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashset_entry));
|
||||
if (!_set_->buffer)
|
||||
{
|
||||
alloc->free(_set_);
|
||||
return ((void *)0);
|
||||
}
|
||||
_set_->count = 0;
|
||||
_set_->capacity = real_capacity;
|
||||
_set_->load = load;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
_set_->f_val = f_val;
|
||||
_set_->alloc = alloc;
|
||||
_set_->callbacks = ((void *)0);
|
||||
return _set_;
|
||||
return hs_new_custom(capacity, load, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity == 0 || load <= 0 || load >= 1)
|
||||
return ((void *)0);
|
||||
if (capacity >= 0xffffffffffffffffULL * load)
|
||||
@@ -142,7 +117,7 @@ struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
_set_->f_val = f_val;
|
||||
_set_->alloc = alloc;
|
||||
_set_->callbacks = callbacks;
|
||||
(_set_)->callbacks = callbacks;
|
||||
return _set_;
|
||||
}
|
||||
void hs_clear(struct hashset *_set_)
|
||||
@@ -180,11 +155,12 @@ void hs_free(struct hashset *_set_)
|
||||
}
|
||||
void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_set_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_set_->alloc = alloc;
|
||||
_set_->callbacks = callbacks;
|
||||
(_set_)->callbacks = callbacks;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool hs_insert(struct hashset *_set_, size_t value)
|
||||
@@ -235,8 +211,9 @@ _Bool hs_insert(struct hashset *_set_, size_t value)
|
||||
}
|
||||
_set_->count++;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->create)
|
||||
_set_->callbacks->create();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->create)
|
||||
(_set_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hs_remove(struct hashset *_set_, size_t value)
|
||||
@@ -257,8 +234,9 @@ _Bool hs_remove(struct hashset *_set_, size_t value)
|
||||
result->state = CMC_ES_DELETED;
|
||||
_set_->count--;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->delete)
|
||||
_set_->callbacks->delete ();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->delete)
|
||||
(_set_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hs_max(struct hashset *_set_, size_t *value)
|
||||
@@ -282,8 +260,9 @@ _Bool hs_max(struct hashset *_set_, size_t *value)
|
||||
if (value)
|
||||
*value = max_value;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->read)
|
||||
_set_->callbacks->read();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hs_min(struct hashset *_set_, size_t *value)
|
||||
@@ -307,16 +286,18 @@ _Bool hs_min(struct hashset *_set_, size_t *value)
|
||||
if (value)
|
||||
*value = min_value;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->read)
|
||||
_set_->callbacks->read();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool hs_contains(struct hashset *_set_, size_t value)
|
||||
{
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
_Bool result = hs_impl_get_entry(_set_, value) != ((void *)0);
|
||||
if (_set_->callbacks && _set_->callbacks->read)
|
||||
_set_->callbacks->read();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool hs_empty(struct hashset *_set_)
|
||||
@@ -388,19 +369,21 @@ _Bool hs_resize(struct hashset *_set_, size_t capacity)
|
||||
_new_set_->f_val = &(struct hashset_fval){ ((void *)0) };
|
||||
hs_free(_new_set_);
|
||||
success:
|
||||
if (_set_->callbacks && _set_->callbacks->resize)
|
||||
_set_->callbacks->resize();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->resize)
|
||||
(_set_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct hashset *hs_copy_of(struct hashset *_set_)
|
||||
{
|
||||
struct hashset *result =
|
||||
hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, _set_->callbacks);
|
||||
hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
{
|
||||
_set_->flag = CMC_FLAG_ERROR;
|
||||
return ((void *)0);
|
||||
}
|
||||
(result)->callbacks = _set_->callbacks;
|
||||
if (_set_->f_val->cpy)
|
||||
{
|
||||
for (size_t i = 0; i < _set_->capacity; i++)
|
||||
@@ -442,155 +425,29 @@ _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_)
|
||||
static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value)
|
||||
{
|
||||
struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
size_t hash = _set_->f_val->hash(value);
|
||||
size_t pos = hash % _set_->capacity;
|
||||
struct hashset_entry *target = &(_set_->buffer[pos]);
|
||||
while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_ALLOC;
|
||||
_set2_->flag = CMC_FLAG_ALLOC;
|
||||
return ((void *)0);
|
||||
if (_set_->f_val->cmp(target->value, value) == 0)
|
||||
return target;
|
||||
pos++;
|
||||
target = &(_set_->buffer[pos % _set_->capacity]);
|
||||
}
|
||||
struct hashset_iter iter1 = hs_iter_start(_set1_);
|
||||
struct hashset_iter iter2 = hs_iter_start(_set2_);
|
||||
for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1))
|
||||
{
|
||||
hs_insert(_set_r_, hs_iter_value(&iter1));
|
||||
}
|
||||
for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2))
|
||||
{
|
||||
hs_insert(_set_r_, hs_iter_value(&iter2));
|
||||
}
|
||||
_set_r_->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
return ((void *)0);
|
||||
}
|
||||
struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_)
|
||||
static size_t hs_impl_calculate_size(size_t required)
|
||||
{
|
||||
struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_ALLOC;
|
||||
_set2_->flag = CMC_FLAG_ALLOC;
|
||||
return ((void *)0);
|
||||
}
|
||||
struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_;
|
||||
struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_;
|
||||
struct hashset_iter iter = hs_iter_start(_set_A_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter);
|
||||
if (hs_impl_get_entry(_set_B_, value) != ((void *)0))
|
||||
hs_insert(_set_r_, value);
|
||||
}
|
||||
_set_r_->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_ALLOC;
|
||||
_set2_->flag = CMC_FLAG_ALLOC;
|
||||
return ((void *)0);
|
||||
}
|
||||
struct hashset_iter iter = hs_iter_start(_set1_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter);
|
||||
if (hs_impl_get_entry(_set2_, value) == ((void *)0))
|
||||
hs_insert(_set_r_, value);
|
||||
}
|
||||
_set_r_->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_ALLOC;
|
||||
_set2_->flag = CMC_FLAG_ALLOC;
|
||||
return ((void *)0);
|
||||
}
|
||||
struct hashset_iter iter1 = hs_iter_start(_set1_);
|
||||
struct hashset_iter iter2 = hs_iter_start(_set2_);
|
||||
for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter1);
|
||||
if (hs_impl_get_entry(_set2_, value) == ((void *)0))
|
||||
hs_insert(_set_r_, value);
|
||||
}
|
||||
for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter2);
|
||||
if (hs_impl_get_entry(_set1_, value) == ((void *)0))
|
||||
hs_insert(_set_r_, value);
|
||||
}
|
||||
_set_r_->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_OK;
|
||||
_set2_->flag = CMC_FLAG_OK;
|
||||
if (_set1_->count > _set2_->count)
|
||||
return 0;
|
||||
if (hs_empty(_set1_))
|
||||
return 1;
|
||||
struct hashset_iter iter = hs_iter_start(_set1_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter);
|
||||
if (hs_impl_get_entry(_set2_, value) == ((void *)0))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
return hs_is_subset(_set2_, _set1_);
|
||||
}
|
||||
_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_OK;
|
||||
_set2_->flag = CMC_FLAG_OK;
|
||||
if (_set1_->count >= _set2_->count)
|
||||
return 0;
|
||||
if (hs_empty(_set1_))
|
||||
{
|
||||
if (!hs_empty(_set2_))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
struct hashset_iter iter = hs_iter_start(_set1_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter);
|
||||
if (hs_impl_get_entry(_set2_, value) == ((void *)0))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
return hs_is_proper_subset(_set2_, _set1_);
|
||||
}
|
||||
_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_OK;
|
||||
_set2_->flag = CMC_FLAG_OK;
|
||||
if (hs_empty(_set1_))
|
||||
return 1;
|
||||
struct hashset_iter iter = hs_iter_start(_set1_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter);
|
||||
if (hs_impl_get_entry(_set2_, value) != ((void *)0))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
|
||||
if (cmc_hashtable_primes[count - 1] < required)
|
||||
return required;
|
||||
size_t i = 0;
|
||||
while (cmc_hashtable_primes[i] < required)
|
||||
i++;
|
||||
return cmc_hashtable_primes[i];
|
||||
}
|
||||
struct hashset_iter hs_iter_start(struct hashset *target)
|
||||
{
|
||||
@@ -781,29 +638,202 @@ size_t hs_iter_index(struct hashset_iter *iter)
|
||||
{
|
||||
return iter->index;
|
||||
}
|
||||
static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value)
|
||||
struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
size_t hash = _set_->f_val->hash(value);
|
||||
size_t pos = hash % _set_->capacity;
|
||||
struct hashset_entry *target = &(_set_->buffer[pos]);
|
||||
while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
|
||||
struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
{
|
||||
if (_set_->f_val->cmp(target->value, value) == 0)
|
||||
return target;
|
||||
pos++;
|
||||
target = &(_set_->buffer[pos % _set_->capacity]);
|
||||
_set1_->flag = CMC_FLAG_ALLOC;
|
||||
_set2_->flag = CMC_FLAG_ALLOC;
|
||||
return ((void *)0);
|
||||
}
|
||||
return ((void *)0);
|
||||
struct hashset_iter iter1 = hs_iter_start(_set1_);
|
||||
struct hashset_iter iter2 = hs_iter_start(_set2_);
|
||||
for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1))
|
||||
{
|
||||
hs_insert(_set_r_, hs_iter_value(&iter1));
|
||||
}
|
||||
for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2))
|
||||
{
|
||||
hs_insert(_set_r_, hs_iter_value(&iter2));
|
||||
}
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
static size_t hs_impl_calculate_size(size_t required)
|
||||
struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
|
||||
if (cmc_hashtable_primes[count - 1] < required)
|
||||
return required;
|
||||
size_t i = 0;
|
||||
while (cmc_hashtable_primes[i] < required)
|
||||
i++;
|
||||
return cmc_hashtable_primes[i];
|
||||
struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_ALLOC;
|
||||
_set2_->flag = CMC_FLAG_ALLOC;
|
||||
return ((void *)0);
|
||||
}
|
||||
struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_;
|
||||
struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_;
|
||||
struct hashset_iter iter = hs_iter_start(_set_A_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter);
|
||||
if (hs_impl_get_entry(_set_B_, value) != ((void *)0))
|
||||
hs_insert(_set_r_, value);
|
||||
}
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_ALLOC;
|
||||
_set2_->flag = CMC_FLAG_ALLOC;
|
||||
return ((void *)0);
|
||||
}
|
||||
struct hashset_iter iter = hs_iter_start(_set1_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter);
|
||||
if (hs_impl_get_entry(_set2_, value) == ((void *)0))
|
||||
hs_insert(_set_r_, value);
|
||||
}
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_ALLOC;
|
||||
_set2_->flag = CMC_FLAG_ALLOC;
|
||||
return ((void *)0);
|
||||
}
|
||||
struct hashset_iter iter1 = hs_iter_start(_set1_);
|
||||
struct hashset_iter iter2 = hs_iter_start(_set2_);
|
||||
for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter1);
|
||||
if (hs_impl_get_entry(_set2_, value) == ((void *)0))
|
||||
hs_insert(_set_r_, value);
|
||||
}
|
||||
for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter2);
|
||||
if (hs_impl_get_entry(_set1_, value) == ((void *)0))
|
||||
hs_insert(_set_r_, value);
|
||||
}
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_OK;
|
||||
_set2_->flag = CMC_FLAG_OK;
|
||||
if (_set1_->count > _set2_->count)
|
||||
return 0;
|
||||
if (hs_empty(_set1_))
|
||||
return 1;
|
||||
struct hashset_iter iter = hs_iter_start(_set1_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter);
|
||||
if (hs_impl_get_entry(_set2_, value) == ((void *)0))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
return hs_is_subset(_set2_, _set1_);
|
||||
}
|
||||
_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_OK;
|
||||
_set2_->flag = CMC_FLAG_OK;
|
||||
if (_set1_->count >= _set2_->count)
|
||||
return 0;
|
||||
if (hs_empty(_set1_))
|
||||
{
|
||||
if (!hs_empty(_set2_))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
struct hashset_iter iter = hs_iter_start(_set1_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter);
|
||||
if (hs_impl_get_entry(_set2_, value) == ((void *)0))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
return hs_is_proper_subset(_set2_, _set1_);
|
||||
}
|
||||
_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_)
|
||||
{
|
||||
_set1_->flag = CMC_FLAG_OK;
|
||||
_set2_->flag = CMC_FLAG_OK;
|
||||
if (hs_empty(_set1_))
|
||||
return 1;
|
||||
struct hashset_iter iter = hs_iter_start(_set1_);
|
||||
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
|
||||
{
|
||||
size_t value = hs_iter_value(&iter);
|
||||
if (hs_impl_get_entry(_set2_, value) != ((void *)0))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
_Bool hs_to_string(struct hashset *_set_, FILE *fptr)
|
||||
{
|
||||
struct hashset *s_ = _set_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"load:%lf, "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks: %p }",
|
||||
"hashset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->load, s_->flag, s_->f_val,
|
||||
s_->alloc, (s_)->callbacks);
|
||||
}
|
||||
_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end)
|
||||
{
|
||||
fprintf(fptr, "%s", start);
|
||||
size_t last = 0;
|
||||
for (size_t i = _set_->capacity; i > 0; i--)
|
||||
{
|
||||
if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED)
|
||||
{
|
||||
last = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < _set_->capacity; i++)
|
||||
{
|
||||
struct hashset_entry *entry = &(_set_->buffer[i]);
|
||||
if (entry->state == CMC_ES_FILLED)
|
||||
{
|
||||
if (!_set_->f_val->str(fptr, entry->value))
|
||||
return 0;
|
||||
if (i + 1 < last)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_HASHSET */
|
||||
+105
-85
@@ -23,13 +23,6 @@ struct heap_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct heap_iter
|
||||
{
|
||||
struct heap *target;
|
||||
size_t cursor;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val);
|
||||
struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val,
|
||||
struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
|
||||
@@ -48,8 +41,13 @@ int h_flag(struct heap *_heap_);
|
||||
_Bool h_resize(struct heap *_heap_, size_t capacity);
|
||||
struct heap *h_copy_of(struct heap *_heap_);
|
||||
_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_);
|
||||
struct cmc_string h_to_string(struct heap *_heap_);
|
||||
_Bool h_print(struct heap *_heap_, FILE *fptr);
|
||||
struct heap_iter
|
||||
{
|
||||
struct heap *target;
|
||||
size_t cursor;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct heap_iter h_iter_start(struct heap *target);
|
||||
struct heap_iter h_iter_end(struct heap *target);
|
||||
_Bool h_iter_at_start(struct heap_iter *iter);
|
||||
@@ -63,38 +61,18 @@ _Bool h_iter_rewind(struct heap_iter *iter, size_t steps);
|
||||
_Bool h_iter_go_to(struct heap_iter *iter, size_t index);
|
||||
size_t h_iter_value(struct heap_iter *iter);
|
||||
size_t h_iter_index(struct heap_iter *iter);
|
||||
_Bool h_to_string(struct heap *_heap_, FILE *fptr);
|
||||
_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end);
|
||||
static void h_impl_float_up(struct heap *_heap_, size_t index);
|
||||
static void h_impl_float_down(struct heap *_heap_, size_t index);
|
||||
struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val)
|
||||
{
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
return ((void *)0);
|
||||
struct heap *_heap_ = alloc->malloc(sizeof(struct heap));
|
||||
if (!_heap_)
|
||||
return ((void *)0);
|
||||
_heap_->buffer = alloc->calloc(capacity, sizeof(size_t));
|
||||
if (!_heap_->buffer)
|
||||
{
|
||||
alloc->free(_heap_);
|
||||
return ((void *)0);
|
||||
}
|
||||
_heap_->capacity = capacity;
|
||||
_heap_->count = 0;
|
||||
_heap_->HO = HO;
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
_heap_->f_val = f_val;
|
||||
_heap_->alloc = alloc;
|
||||
_heap_->callbacks = ((void *)0);
|
||||
return _heap_;
|
||||
return h_new_custom(capacity, HO, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val,
|
||||
struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP)
|
||||
@@ -118,7 +96,7 @@ struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_f
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
_heap_->f_val = f_val;
|
||||
_heap_->alloc = alloc;
|
||||
_heap_->callbacks = callbacks;
|
||||
(_heap_)->callbacks = callbacks;
|
||||
return _heap_;
|
||||
}
|
||||
void h_clear(struct heap *_heap_)
|
||||
@@ -148,11 +126,12 @@ void h_free(struct heap *_heap_)
|
||||
}
|
||||
void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_heap_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_heap_->alloc = alloc;
|
||||
_heap_->callbacks = callbacks;
|
||||
(_heap_)->callbacks = callbacks;
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool h_insert(struct heap *_heap_, size_t value)
|
||||
@@ -168,8 +147,9 @@ _Bool h_insert(struct heap *_heap_, size_t value)
|
||||
h_impl_float_up(_heap_, _heap_->count - 1);
|
||||
}
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
if (_heap_->callbacks && _heap_->callbacks->create)
|
||||
_heap_->callbacks->create();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->create)
|
||||
(_heap_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool h_remove(struct heap *_heap_)
|
||||
@@ -184,8 +164,9 @@ _Bool h_remove(struct heap *_heap_)
|
||||
_heap_->count--;
|
||||
h_impl_float_down(_heap_, 0);
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
if (_heap_->callbacks && _heap_->callbacks->delete)
|
||||
_heap_->callbacks->delete ();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->delete)
|
||||
(_heap_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t h_peek(struct heap *_heap_)
|
||||
@@ -196,8 +177,9 @@ size_t h_peek(struct heap *_heap_)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
if (_heap_->callbacks && _heap_->callbacks->read)
|
||||
_heap_->callbacks->read();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->read)
|
||||
(_heap_)->callbacks->read();
|
||||
;
|
||||
return _heap_->buffer[0];
|
||||
}
|
||||
_Bool h_contains(struct heap *_heap_, size_t value)
|
||||
@@ -212,8 +194,9 @@ _Bool h_contains(struct heap *_heap_, size_t value)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_heap_->callbacks && _heap_->callbacks->read)
|
||||
_heap_->callbacks->read();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->read)
|
||||
(_heap_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool h_empty(struct heap *_heap_)
|
||||
@@ -255,18 +238,20 @@ _Bool h_resize(struct heap *_heap_, size_t capacity)
|
||||
_heap_->buffer = new_buffer;
|
||||
_heap_->capacity = capacity;
|
||||
success:
|
||||
if (_heap_->callbacks && _heap_->callbacks->resize)
|
||||
_heap_->callbacks->resize();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->resize)
|
||||
(_heap_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct heap *h_copy_of(struct heap *_heap_)
|
||||
{
|
||||
struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, _heap_->callbacks);
|
||||
struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
{
|
||||
_heap_->flag = CMC_FLAG_ERROR;
|
||||
return ((void *)0);
|
||||
}
|
||||
(result)->callbacks = _heap_->callbacks;
|
||||
if (_heap_->f_val->cpy)
|
||||
{
|
||||
for (size_t i = 0; i < _heap_->count; i++)
|
||||
@@ -291,6 +276,51 @@ _Bool h_equals(struct heap *_heap1_, struct heap *_heap2_)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static void h_impl_float_up(struct heap *_heap_, size_t index)
|
||||
{
|
||||
size_t C = index;
|
||||
size_t child = _heap_->buffer[C];
|
||||
size_t parent = _heap_->buffer[(index - 1) / 2];
|
||||
int mod = _heap_->HO;
|
||||
while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0)
|
||||
{
|
||||
size_t tmp = _heap_->buffer[C];
|
||||
_heap_->buffer[C] = _heap_->buffer[(C - 1) / 2];
|
||||
_heap_->buffer[(C - 1) / 2] = tmp;
|
||||
C = (C - 1) / 2;
|
||||
if (C == 0)
|
||||
break;
|
||||
child = _heap_->buffer[C];
|
||||
parent = _heap_->buffer[(C - 1) / 2];
|
||||
}
|
||||
}
|
||||
static void h_impl_float_down(struct heap *_heap_, size_t index)
|
||||
{
|
||||
int mod = _heap_->HO;
|
||||
while (index < _heap_->count)
|
||||
{
|
||||
size_t L = 2 * index + 1;
|
||||
size_t R = 2 * index + 2;
|
||||
size_t C = index;
|
||||
if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0)
|
||||
{
|
||||
C = L;
|
||||
}
|
||||
if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0)
|
||||
{
|
||||
C = R;
|
||||
}
|
||||
if (C != index)
|
||||
{
|
||||
size_t tmp = _heap_->buffer[index];
|
||||
_heap_->buffer[index] = _heap_->buffer[C];
|
||||
_heap_->buffer[C] = tmp;
|
||||
index = C;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
struct heap_iter h_iter_start(struct heap *target)
|
||||
{
|
||||
struct heap_iter iter;
|
||||
@@ -419,50 +449,40 @@ size_t h_iter_index(struct heap_iter *iter)
|
||||
{
|
||||
return iter->cursor;
|
||||
}
|
||||
static void h_impl_float_up(struct heap *_heap_, size_t index)
|
||||
_Bool h_to_string(struct heap *_heap_, FILE *fptr)
|
||||
{
|
||||
size_t C = index;
|
||||
size_t child = _heap_->buffer[C];
|
||||
size_t parent = _heap_->buffer[(index - 1) / 2];
|
||||
int mod = _heap_->HO;
|
||||
while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0)
|
||||
{
|
||||
size_t tmp = _heap_->buffer[C];
|
||||
_heap_->buffer[C] = _heap_->buffer[(C - 1) / 2];
|
||||
_heap_->buffer[(C - 1) / 2] = tmp;
|
||||
C = (C - 1) / 2;
|
||||
if (C == 0)
|
||||
break;
|
||||
child = _heap_->buffer[C];
|
||||
parent = _heap_->buffer[(C - 1) / 2];
|
||||
}
|
||||
struct heap *h_ = _heap_;
|
||||
const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap";
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"type:%s, "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks: %p}",
|
||||
"heap", "size_t", h_, h_->buffer, h_->capacity, h_->count, t, h_->flag, h_->f_val, h_->alloc,
|
||||
(h_)->callbacks);
|
||||
}
|
||||
static void h_impl_float_down(struct heap *_heap_, size_t index)
|
||||
_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end)
|
||||
{
|
||||
int mod = _heap_->HO;
|
||||
while (index < _heap_->count)
|
||||
fprintf(fptr, "%s", start);
|
||||
for (size_t i = 0; i < _heap_->count; i++)
|
||||
{
|
||||
size_t L = 2 * index + 1;
|
||||
size_t R = 2 * index + 2;
|
||||
size_t C = index;
|
||||
if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0)
|
||||
{
|
||||
C = L;
|
||||
}
|
||||
if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0)
|
||||
{
|
||||
C = R;
|
||||
}
|
||||
if (C != index)
|
||||
{
|
||||
size_t tmp = _heap_->buffer[index];
|
||||
_heap_->buffer[index] = _heap_->buffer[C];
|
||||
_heap_->buffer[C] = tmp;
|
||||
index = C;
|
||||
}
|
||||
else
|
||||
break;
|
||||
if (!_heap_->f_val->str(fptr, _heap_->buffer[i]))
|
||||
return 0;
|
||||
if (i + 1 < _heap_->count)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_HEAP */
|
||||
+207
-182
@@ -23,13 +23,6 @@ struct intervalheap_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct intervalheap_iter
|
||||
{
|
||||
struct intervalheap *target;
|
||||
size_t cursor;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val);
|
||||
struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks);
|
||||
@@ -50,10 +43,15 @@ size_t ih_count(struct intervalheap *_heap_);
|
||||
size_t ih_capacity(struct intervalheap *_heap_);
|
||||
int ih_flag(struct intervalheap *_heap_);
|
||||
_Bool ih_resize(struct intervalheap *_heap_, size_t capacity);
|
||||
struct intervalheap *ih_copy_of(struct intervalheap *_set_);
|
||||
struct intervalheap *ih_copy_of(struct intervalheap *_heap_);
|
||||
_Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_);
|
||||
struct cmc_string ih_to_string(struct intervalheap *_heap_);
|
||||
_Bool ih_print(struct intervalheap *_heap_, FILE *fptr);
|
||||
struct intervalheap_iter
|
||||
{
|
||||
struct intervalheap *target;
|
||||
size_t cursor;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct intervalheap_iter ih_iter_start(struct intervalheap *target);
|
||||
struct intervalheap_iter ih_iter_end(struct intervalheap *target);
|
||||
_Bool ih_iter_at_start(struct intervalheap_iter *iter);
|
||||
@@ -67,39 +65,20 @@ _Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps);
|
||||
_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index);
|
||||
size_t ih_iter_value(struct intervalheap_iter *iter);
|
||||
size_t ih_iter_index(struct intervalheap_iter *iter);
|
||||
_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr);
|
||||
_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end);
|
||||
static void ih_impl_float_up_max(struct intervalheap *_heap_);
|
||||
static void ih_impl_float_up_min(struct intervalheap *_heap_);
|
||||
static void ih_impl_float_down_max(struct intervalheap *_heap_);
|
||||
static void ih_impl_float_down_min(struct intervalheap *_heap_);
|
||||
struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val)
|
||||
{
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
if (capacity == 0 || capacity == 0xffffffffffffffffULL)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
return ((void *)0);
|
||||
struct intervalheap *_heap_ = alloc->malloc(sizeof(struct intervalheap));
|
||||
if (!_heap_)
|
||||
return ((void *)0);
|
||||
capacity = (capacity + capacity % 2) / 2;
|
||||
_heap_->buffer = alloc->calloc(capacity, sizeof(size_t[2]));
|
||||
if (!_heap_->buffer)
|
||||
{
|
||||
alloc->free(_heap_);
|
||||
return ((void *)0);
|
||||
}
|
||||
_heap_->capacity = capacity;
|
||||
_heap_->size = 0;
|
||||
_heap_->count = 0;
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
_heap_->f_val = f_val;
|
||||
_heap_->alloc = alloc;
|
||||
_heap_->callbacks = ((void *)0);
|
||||
return _heap_;
|
||||
return ih_new_custom(capacity, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity == 0 || capacity == 0xffffffffffffffffULL)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
@@ -122,7 +101,7 @@ struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
_heap_->f_val = f_val;
|
||||
_heap_->alloc = alloc;
|
||||
_heap_->callbacks = callbacks;
|
||||
(_heap_)->callbacks = callbacks;
|
||||
return _heap_;
|
||||
}
|
||||
void ih_clear(struct intervalheap *_heap_)
|
||||
@@ -153,11 +132,12 @@ void ih_free(struct intervalheap *_heap_)
|
||||
}
|
||||
void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_heap_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_heap_->alloc = alloc;
|
||||
_heap_->callbacks = callbacks;
|
||||
(_heap_)->callbacks = callbacks;
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool ih_insert(struct intervalheap *_heap_, size_t value)
|
||||
@@ -196,8 +176,9 @@ _Bool ih_insert(struct intervalheap *_heap_, size_t value)
|
||||
else if (_heap_->f_val->cmp((*parent)[1], value) < 0)
|
||||
ih_impl_float_up_max(_heap_);
|
||||
}
|
||||
if (_heap_->callbacks && _heap_->callbacks->create)
|
||||
_heap_->callbacks->create();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->create)
|
||||
(_heap_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_remove_max(struct intervalheap *_heap_)
|
||||
@@ -230,8 +211,9 @@ _Bool ih_remove_max(struct intervalheap *_heap_)
|
||||
ih_impl_float_down_max(_heap_);
|
||||
success:
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
if (_heap_->callbacks && _heap_->callbacks->delete)
|
||||
_heap_->callbacks->delete ();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->delete)
|
||||
(_heap_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_remove_min(struct intervalheap *_heap_)
|
||||
@@ -264,8 +246,9 @@ _Bool ih_remove_min(struct intervalheap *_heap_)
|
||||
ih_impl_float_down_min(_heap_);
|
||||
success:
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
if (_heap_->callbacks && _heap_->callbacks->delete)
|
||||
_heap_->callbacks->delete ();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->delete)
|
||||
(_heap_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_update_max(struct intervalheap *_heap_, size_t value)
|
||||
@@ -291,8 +274,9 @@ _Bool ih_update_max(struct intervalheap *_heap_, size_t value)
|
||||
ih_impl_float_down_max(_heap_);
|
||||
}
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
if (_heap_->callbacks && _heap_->callbacks->update)
|
||||
_heap_->callbacks->update();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->update)
|
||||
(_heap_)->callbacks->update();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_update_min(struct intervalheap *_heap_, size_t value)
|
||||
@@ -318,8 +302,9 @@ _Bool ih_update_min(struct intervalheap *_heap_, size_t value)
|
||||
ih_impl_float_down_min(_heap_);
|
||||
}
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
if (_heap_->callbacks && _heap_->callbacks->update)
|
||||
_heap_->callbacks->update();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->update)
|
||||
(_heap_)->callbacks->update();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t ih_max(struct intervalheap *_heap_)
|
||||
@@ -330,8 +315,9 @@ size_t ih_max(struct intervalheap *_heap_)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
if (_heap_->callbacks && _heap_->callbacks->read)
|
||||
_heap_->callbacks->read();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->read)
|
||||
(_heap_)->callbacks->read();
|
||||
;
|
||||
if (_heap_->count == 1)
|
||||
return _heap_->buffer[0][0];
|
||||
return _heap_->buffer[0][1];
|
||||
@@ -344,8 +330,9 @@ size_t ih_min(struct intervalheap *_heap_)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
if (_heap_->callbacks && _heap_->callbacks->read)
|
||||
_heap_->callbacks->read();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->read)
|
||||
(_heap_)->callbacks->read();
|
||||
;
|
||||
return _heap_->buffer[0][0];
|
||||
}
|
||||
_Bool ih_contains(struct intervalheap *_heap_, size_t value)
|
||||
@@ -360,8 +347,9 @@ _Bool ih_contains(struct intervalheap *_heap_, size_t value)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_heap_->callbacks && _heap_->callbacks->read)
|
||||
_heap_->callbacks->read();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->read)
|
||||
(_heap_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool ih_empty(struct intervalheap *_heap_)
|
||||
@@ -413,8 +401,9 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity)
|
||||
_heap_->capacity = capacity;
|
||||
success:
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
if (_heap_->callbacks && _heap_->callbacks->resize)
|
||||
_heap_->callbacks->resize();
|
||||
if ((_heap_)->callbacks && (_heap_)->callbacks->resize)
|
||||
(_heap_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct intervalheap *ih_copy_of(struct intervalheap *_heap_)
|
||||
@@ -446,7 +435,7 @@ struct intervalheap *ih_copy_of(struct intervalheap *_heap_)
|
||||
result->flag = CMC_FLAG_OK;
|
||||
result->f_val = _heap_->f_val;
|
||||
result->alloc = _heap_->alloc;
|
||||
result->callbacks = _heap_->callbacks;
|
||||
(result)->callbacks = _heap_->callbacks;
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
return result;
|
||||
}
|
||||
@@ -465,134 +454,6 @@ _Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
struct intervalheap_iter ih_iter_start(struct intervalheap *target)
|
||||
{
|
||||
struct intervalheap_iter iter;
|
||||
iter.target = target;
|
||||
iter.cursor = 0;
|
||||
iter.start = 1;
|
||||
iter.end = ih_empty(target);
|
||||
return iter;
|
||||
}
|
||||
struct intervalheap_iter ih_iter_end(struct intervalheap *target)
|
||||
{
|
||||
struct intervalheap_iter iter;
|
||||
iter.target = target;
|
||||
iter.cursor = 0;
|
||||
iter.start = ih_empty(target);
|
||||
iter.end = 1;
|
||||
if (!ih_empty(target))
|
||||
iter.cursor = target->count - 1;
|
||||
return iter;
|
||||
}
|
||||
_Bool ih_iter_at_start(struct intervalheap_iter *iter)
|
||||
{
|
||||
return ih_empty(iter->target) || iter->start;
|
||||
}
|
||||
_Bool ih_iter_at_end(struct intervalheap_iter *iter)
|
||||
{
|
||||
return ih_empty(iter->target) || iter->end;
|
||||
}
|
||||
_Bool ih_iter_to_start(struct intervalheap_iter *iter)
|
||||
{
|
||||
if (!ih_empty(iter->target))
|
||||
{
|
||||
iter->cursor = 0;
|
||||
iter->start = 1;
|
||||
iter->end = ih_empty(iter->target);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
_Bool ih_iter_to_end(struct intervalheap_iter *iter)
|
||||
{
|
||||
if (!ih_empty(iter->target))
|
||||
{
|
||||
iter->cursor = iter->target->count - 1;
|
||||
iter->start = ih_empty(iter->target);
|
||||
iter->end = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
_Bool ih_iter_next(struct intervalheap_iter *iter)
|
||||
{
|
||||
if (iter->end)
|
||||
return 0;
|
||||
if (iter->cursor + 1 == iter->target->count)
|
||||
{
|
||||
iter->end = 1;
|
||||
return 0;
|
||||
}
|
||||
iter->start = ih_empty(iter->target);
|
||||
iter->cursor++;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_iter_prev(struct intervalheap_iter *iter)
|
||||
{
|
||||
if (iter->start)
|
||||
return 0;
|
||||
if (iter->cursor == 0)
|
||||
{
|
||||
iter->start = 1;
|
||||
return 0;
|
||||
}
|
||||
iter->end = ih_empty(iter->target);
|
||||
iter->cursor--;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps)
|
||||
{
|
||||
if (iter->end)
|
||||
return 0;
|
||||
if (iter->cursor + 1 == iter->target->count)
|
||||
{
|
||||
iter->end = 1;
|
||||
return 0;
|
||||
}
|
||||
if (steps == 0 || iter->cursor + steps >= iter->target->count)
|
||||
return 0;
|
||||
if (iter->end)
|
||||
return 0;
|
||||
iter->start = ih_empty(iter->target);
|
||||
iter->cursor += steps;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps)
|
||||
{
|
||||
if (iter->start)
|
||||
return 0;
|
||||
if (iter->cursor == 0)
|
||||
{
|
||||
iter->start = 1;
|
||||
return 0;
|
||||
}
|
||||
if (steps == 0 || iter->cursor < steps)
|
||||
return 0;
|
||||
iter->end = ih_empty(iter->target);
|
||||
iter->cursor -= steps;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index)
|
||||
{
|
||||
if (index >= iter->target->count)
|
||||
return 0;
|
||||
if (iter->cursor > index)
|
||||
return ih_iter_rewind(iter, iter->cursor - index);
|
||||
else if (iter->cursor < index)
|
||||
return ih_iter_advance(iter, index - iter->cursor);
|
||||
return 1;
|
||||
}
|
||||
size_t ih_iter_value(struct intervalheap_iter *iter)
|
||||
{
|
||||
if (ih_empty(iter->target))
|
||||
return (size_t){ 0 };
|
||||
return iter->target->buffer[iter->cursor / 2][iter->cursor % 2];
|
||||
}
|
||||
size_t ih_iter_index(struct intervalheap_iter *iter)
|
||||
{
|
||||
return iter->cursor;
|
||||
}
|
||||
static void ih_impl_float_up_max(struct intervalheap *_heap_)
|
||||
{
|
||||
size_t index = _heap_->size - 1;
|
||||
@@ -725,5 +586,169 @@ static void ih_impl_float_down_min(struct intervalheap *_heap_)
|
||||
curr_node = child_node;
|
||||
}
|
||||
}
|
||||
struct intervalheap_iter ih_iter_start(struct intervalheap *target)
|
||||
{
|
||||
struct intervalheap_iter iter;
|
||||
iter.target = target;
|
||||
iter.cursor = 0;
|
||||
iter.start = 1;
|
||||
iter.end = ih_empty(target);
|
||||
return iter;
|
||||
}
|
||||
struct intervalheap_iter ih_iter_end(struct intervalheap *target)
|
||||
{
|
||||
struct intervalheap_iter iter;
|
||||
iter.target = target;
|
||||
iter.cursor = 0;
|
||||
iter.start = ih_empty(target);
|
||||
iter.end = 1;
|
||||
if (!ih_empty(target))
|
||||
iter.cursor = target->count - 1;
|
||||
return iter;
|
||||
}
|
||||
_Bool ih_iter_at_start(struct intervalheap_iter *iter)
|
||||
{
|
||||
return ih_empty(iter->target) || iter->start;
|
||||
}
|
||||
_Bool ih_iter_at_end(struct intervalheap_iter *iter)
|
||||
{
|
||||
return ih_empty(iter->target) || iter->end;
|
||||
}
|
||||
_Bool ih_iter_to_start(struct intervalheap_iter *iter)
|
||||
{
|
||||
if (!ih_empty(iter->target))
|
||||
{
|
||||
iter->cursor = 0;
|
||||
iter->start = 1;
|
||||
iter->end = ih_empty(iter->target);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
_Bool ih_iter_to_end(struct intervalheap_iter *iter)
|
||||
{
|
||||
if (!ih_empty(iter->target))
|
||||
{
|
||||
iter->cursor = iter->target->count - 1;
|
||||
iter->start = ih_empty(iter->target);
|
||||
iter->end = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
_Bool ih_iter_next(struct intervalheap_iter *iter)
|
||||
{
|
||||
if (iter->end)
|
||||
return 0;
|
||||
if (iter->cursor + 1 == iter->target->count)
|
||||
{
|
||||
iter->end = 1;
|
||||
return 0;
|
||||
}
|
||||
iter->start = ih_empty(iter->target);
|
||||
iter->cursor++;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_iter_prev(struct intervalheap_iter *iter)
|
||||
{
|
||||
if (iter->start)
|
||||
return 0;
|
||||
if (iter->cursor == 0)
|
||||
{
|
||||
iter->start = 1;
|
||||
return 0;
|
||||
}
|
||||
iter->end = ih_empty(iter->target);
|
||||
iter->cursor--;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps)
|
||||
{
|
||||
if (iter->end)
|
||||
return 0;
|
||||
if (iter->cursor + 1 == iter->target->count)
|
||||
{
|
||||
iter->end = 1;
|
||||
return 0;
|
||||
}
|
||||
if (steps == 0 || iter->cursor + steps >= iter->target->count)
|
||||
return 0;
|
||||
if (iter->end)
|
||||
return 0;
|
||||
iter->start = ih_empty(iter->target);
|
||||
iter->cursor += steps;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps)
|
||||
{
|
||||
if (iter->start)
|
||||
return 0;
|
||||
if (iter->cursor == 0)
|
||||
{
|
||||
iter->start = 1;
|
||||
return 0;
|
||||
}
|
||||
if (steps == 0 || iter->cursor < steps)
|
||||
return 0;
|
||||
iter->end = ih_empty(iter->target);
|
||||
iter->cursor -= steps;
|
||||
return 1;
|
||||
}
|
||||
_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index)
|
||||
{
|
||||
if (index >= iter->target->count)
|
||||
return 0;
|
||||
if (iter->cursor > index)
|
||||
return ih_iter_rewind(iter, iter->cursor - index);
|
||||
else if (iter->cursor < index)
|
||||
return ih_iter_advance(iter, index - iter->cursor);
|
||||
return 1;
|
||||
}
|
||||
size_t ih_iter_value(struct intervalheap_iter *iter)
|
||||
{
|
||||
if (ih_empty(iter->target))
|
||||
return (size_t){ 0 };
|
||||
return iter->target->buffer[iter->cursor / 2][iter->cursor % 2];
|
||||
}
|
||||
size_t ih_iter_index(struct intervalheap_iter *iter)
|
||||
{
|
||||
return iter->cursor;
|
||||
}
|
||||
_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr)
|
||||
{
|
||||
struct intervalheap *h_ = _heap_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"size:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"intervalheap", "size_t", h_, h_->buffer, h_->capacity, h_->size, h_->count, h_->flag,
|
||||
h_->f_val, h_->alloc, (h_)->callbacks);
|
||||
}
|
||||
_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end)
|
||||
{
|
||||
fprintf(fptr, "%s", start);
|
||||
for (size_t i = 0; i < _heap_->count; i++)
|
||||
{
|
||||
if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2]))
|
||||
return 0;
|
||||
if (i + 1 < _heap_->count)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_INTERVALHEAP */
|
||||
+234
-200
@@ -28,14 +28,6 @@ struct linkedlist_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct linkedlist_iter
|
||||
{
|
||||
struct linkedlist *target;
|
||||
struct linkedlist_node *cursor;
|
||||
size_t index;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct linkedlist *ll_new(struct linkedlist_fval *f_val);
|
||||
struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks);
|
||||
@@ -58,20 +50,14 @@ size_t ll_count(struct linkedlist *_list_);
|
||||
int ll_flag(struct linkedlist *_list_);
|
||||
struct linkedlist *ll_copy_of(struct linkedlist *_list_);
|
||||
_Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_);
|
||||
struct cmc_string ll_to_string(struct linkedlist *_list_);
|
||||
_Bool ll_print(struct linkedlist *_list_, FILE *fptr);
|
||||
struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value);
|
||||
void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_);
|
||||
struct linkedlist_node *ll_head(struct linkedlist *_list_);
|
||||
struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index);
|
||||
struct linkedlist_node *ll_tail(struct linkedlist *_list_);
|
||||
_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value);
|
||||
_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value);
|
||||
_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_);
|
||||
_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_);
|
||||
_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_);
|
||||
struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_);
|
||||
struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_);
|
||||
struct linkedlist_iter
|
||||
{
|
||||
struct linkedlist *target;
|
||||
struct linkedlist_node *cursor;
|
||||
size_t index;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct linkedlist_iter ll_iter_start(struct linkedlist *target);
|
||||
struct linkedlist_iter ll_iter_end(struct linkedlist *target);
|
||||
_Bool ll_iter_at_start(struct linkedlist_iter *iter);
|
||||
@@ -87,26 +73,28 @@ size_t ll_iter_value(struct linkedlist_iter *iter);
|
||||
size_t *ll_iter_rvalue(struct linkedlist_iter *iter);
|
||||
size_t ll_iter_index(struct linkedlist_iter *iter);
|
||||
struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter);
|
||||
struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value);
|
||||
void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_);
|
||||
struct linkedlist_node *ll_head(struct linkedlist *_list_);
|
||||
struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index);
|
||||
struct linkedlist_node *ll_tail(struct linkedlist *_list_);
|
||||
_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value);
|
||||
_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value);
|
||||
_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_);
|
||||
_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_);
|
||||
_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_);
|
||||
struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_);
|
||||
struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_);
|
||||
_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr);
|
||||
_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end);
|
||||
struct linkedlist *ll_new(struct linkedlist_fval *f_val)
|
||||
{
|
||||
if (!f_val)
|
||||
return ((void *)0);
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
struct linkedlist *_list_ = alloc->malloc(sizeof(struct linkedlist));
|
||||
if (!_list_)
|
||||
return ((void *)0);
|
||||
_list_->count = 0;
|
||||
_list_->head = ((void *)0);
|
||||
_list_->tail = ((void *)0);
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
_list_->f_val = f_val;
|
||||
_list_->alloc = alloc;
|
||||
_list_->callbacks = ((void *)0);
|
||||
return _list_;
|
||||
return ll_new_custom(f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!f_val)
|
||||
return ((void *)0);
|
||||
if (!alloc)
|
||||
@@ -120,7 +108,7 @@ struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
_list_->f_val = f_val;
|
||||
_list_->alloc = alloc;
|
||||
_list_->callbacks = callbacks;
|
||||
(_list_)->callbacks = callbacks;
|
||||
return _list_;
|
||||
}
|
||||
void ll_clear(struct linkedlist *_list_)
|
||||
@@ -148,11 +136,12 @@ void ll_free(struct linkedlist *_list_)
|
||||
}
|
||||
void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_list_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_list_->alloc = alloc;
|
||||
_list_->callbacks = callbacks;
|
||||
(_list_)->callbacks = callbacks;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool ll_push_front(struct linkedlist *_list_, size_t value)
|
||||
@@ -173,8 +162,9 @@ _Bool ll_push_front(struct linkedlist *_list_, size_t value)
|
||||
}
|
||||
_list_->count++;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->create)
|
||||
_list_->callbacks->create();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->create)
|
||||
(_list_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index)
|
||||
@@ -202,8 +192,9 @@ _Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index)
|
||||
_node_->prev->next = _node_;
|
||||
_list_->count++;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->create)
|
||||
_list_->callbacks->create();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->create)
|
||||
(_list_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_push_back(struct linkedlist *_list_, size_t value)
|
||||
@@ -224,8 +215,9 @@ _Bool ll_push_back(struct linkedlist *_list_, size_t value)
|
||||
}
|
||||
_list_->count++;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->create)
|
||||
_list_->callbacks->create();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->create)
|
||||
(_list_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_pop_front(struct linkedlist *_list_)
|
||||
@@ -244,8 +236,9 @@ _Bool ll_pop_front(struct linkedlist *_list_)
|
||||
_list_->head->prev = ((void *)0);
|
||||
_list_->count--;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->delete)
|
||||
_list_->callbacks->delete ();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->delete)
|
||||
(_list_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_pop_at(struct linkedlist *_list_, size_t index)
|
||||
@@ -276,8 +269,9 @@ _Bool ll_pop_at(struct linkedlist *_list_, size_t index)
|
||||
_list_->alloc->free(_node_);
|
||||
_list_->count--;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->delete)
|
||||
_list_->callbacks->delete ();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->delete)
|
||||
(_list_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_pop_back(struct linkedlist *_list_)
|
||||
@@ -296,8 +290,9 @@ _Bool ll_pop_back(struct linkedlist *_list_)
|
||||
_list_->tail->next = ((void *)0);
|
||||
_list_->count--;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->delete)
|
||||
_list_->callbacks->delete ();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->delete)
|
||||
(_list_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t ll_front(struct linkedlist *_list_)
|
||||
@@ -308,8 +303,9 @@ size_t ll_front(struct linkedlist *_list_)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return _list_->head->value;
|
||||
}
|
||||
size_t ll_get(struct linkedlist *_list_, size_t index)
|
||||
@@ -327,8 +323,9 @@ size_t ll_get(struct linkedlist *_list_, size_t index)
|
||||
struct linkedlist_node *scan = ll_get_node(_list_, index);
|
||||
if (scan == ((void *)0))
|
||||
return (size_t){ 0 };
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return scan->value;
|
||||
}
|
||||
size_t *ll_get_ref(struct linkedlist *_list_, size_t index)
|
||||
@@ -346,8 +343,9 @@ size_t *ll_get_ref(struct linkedlist *_list_, size_t index)
|
||||
struct linkedlist_node *scan = ll_get_node(_list_, index);
|
||||
if (scan == ((void *)0))
|
||||
return ((void *)0);
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return &(scan->value);
|
||||
}
|
||||
size_t ll_back(struct linkedlist *_list_)
|
||||
@@ -358,8 +356,9 @@ size_t ll_back(struct linkedlist *_list_)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return _list_->tail->value;
|
||||
}
|
||||
_Bool ll_contains(struct linkedlist *_list_, size_t value)
|
||||
@@ -376,8 +375,9 @@ _Bool ll_contains(struct linkedlist *_list_, size_t value)
|
||||
}
|
||||
scan = scan->next;
|
||||
}
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool ll_empty(struct linkedlist *_list_)
|
||||
@@ -394,9 +394,10 @@ int ll_flag(struct linkedlist *_list_)
|
||||
}
|
||||
struct linkedlist *ll_copy_of(struct linkedlist *_list_)
|
||||
{
|
||||
struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, _list_->callbacks);
|
||||
struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
return ((void *)0);
|
||||
(result)->callbacks = _list_->callbacks;
|
||||
struct linkedlist_node *scan = _list_->head;
|
||||
while (scan != ((void *)0))
|
||||
{
|
||||
@@ -439,6 +440,152 @@ _Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
struct linkedlist_iter ll_iter_start(struct linkedlist *target)
|
||||
{
|
||||
struct linkedlist_iter iter;
|
||||
iter.target = target;
|
||||
iter.cursor = target->head;
|
||||
iter.index = 0;
|
||||
iter.start = 1;
|
||||
iter.end = ll_empty(target);
|
||||
return iter;
|
||||
}
|
||||
struct linkedlist_iter ll_iter_end(struct linkedlist *target)
|
||||
{
|
||||
struct linkedlist_iter iter;
|
||||
iter.target = target;
|
||||
iter.cursor = target->tail;
|
||||
iter.index = 0;
|
||||
iter.start = ll_empty(target);
|
||||
iter.end = 1;
|
||||
if (!ll_empty(target))
|
||||
iter.index = target->count - 1;
|
||||
return iter;
|
||||
}
|
||||
_Bool ll_iter_at_start(struct linkedlist_iter *iter)
|
||||
{
|
||||
return ll_empty(iter->target) || iter->start;
|
||||
}
|
||||
_Bool ll_iter_at_end(struct linkedlist_iter *iter)
|
||||
{
|
||||
return ll_empty(iter->target) || iter->end;
|
||||
}
|
||||
_Bool ll_iter_to_start(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (!ll_empty(iter->target))
|
||||
{
|
||||
iter->cursor = iter->target->head;
|
||||
iter->index = 0;
|
||||
iter->start = 1;
|
||||
iter->end = ll_empty(iter->target);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
_Bool ll_iter_to_end(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (!ll_empty(iter->target))
|
||||
{
|
||||
iter->cursor = iter->target->tail;
|
||||
iter->index = iter->target->count - 1;
|
||||
iter->start = ll_empty(iter->target);
|
||||
iter->end = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
_Bool ll_iter_next(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (iter->end)
|
||||
return 0;
|
||||
if (iter->cursor->next == ((void *)0))
|
||||
{
|
||||
iter->end = 1;
|
||||
return 0;
|
||||
}
|
||||
iter->start = ll_empty(iter->target);
|
||||
iter->cursor = iter->cursor->next;
|
||||
iter->index++;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_iter_prev(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (iter->start)
|
||||
return 0;
|
||||
if (iter->cursor->prev == ((void *)0))
|
||||
{
|
||||
iter->start = 1;
|
||||
return 0;
|
||||
}
|
||||
iter->end = ll_empty(iter->target);
|
||||
iter->cursor = iter->cursor->prev;
|
||||
iter->index--;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps)
|
||||
{
|
||||
if (iter->end)
|
||||
return 0;
|
||||
if (iter->cursor->next == ((void *)0))
|
||||
{
|
||||
iter->end = 1;
|
||||
return 0;
|
||||
}
|
||||
if (steps == 0 || iter->index + steps >= iter->target->count)
|
||||
return 0;
|
||||
iter->start = ll_empty(iter->target);
|
||||
iter->index += steps;
|
||||
for (size_t i = 0; i < steps; i++)
|
||||
iter->cursor = iter->cursor->next;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps)
|
||||
{
|
||||
if (iter->start)
|
||||
return 0;
|
||||
if (iter->cursor->prev == ((void *)0))
|
||||
{
|
||||
iter->start = 1;
|
||||
return 0;
|
||||
}
|
||||
if (steps == 0 || iter->index < steps)
|
||||
return 0;
|
||||
iter->end = ll_empty(iter->target);
|
||||
iter->index -= steps;
|
||||
for (size_t i = 0; i < steps; i++)
|
||||
iter->cursor = iter->cursor->prev;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index)
|
||||
{
|
||||
if (index >= iter->target->count)
|
||||
return 0;
|
||||
if (iter->index > index)
|
||||
return ll_iter_rewind(iter, iter->index - index);
|
||||
else if (iter->index < index)
|
||||
return ll_iter_advance(iter, index - iter->index);
|
||||
return 1;
|
||||
}
|
||||
size_t ll_iter_value(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (ll_empty(iter->target))
|
||||
return (size_t){ 0 };
|
||||
return iter->cursor->value;
|
||||
}
|
||||
size_t *ll_iter_rvalue(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (ll_empty(iter->target))
|
||||
return ((void *)0);
|
||||
return &(iter->cursor->value);
|
||||
}
|
||||
size_t ll_iter_index(struct linkedlist_iter *iter)
|
||||
{
|
||||
return iter->index;
|
||||
}
|
||||
struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter)
|
||||
{
|
||||
return iter->cursor;
|
||||
}
|
||||
struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value)
|
||||
{
|
||||
struct linkedlist_node *_node_ = _list_->alloc->malloc(sizeof(struct linkedlist_node));
|
||||
@@ -587,151 +734,38 @@ struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_)
|
||||
{
|
||||
return _node_->prev;
|
||||
}
|
||||
struct linkedlist_iter ll_iter_start(struct linkedlist *target)
|
||||
_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr)
|
||||
{
|
||||
struct linkedlist_iter iter;
|
||||
iter.target = target;
|
||||
iter.cursor = target->head;
|
||||
iter.index = 0;
|
||||
iter.start = 1;
|
||||
iter.end = ll_empty(target);
|
||||
return iter;
|
||||
struct linkedlist *l_ = _list_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"head:%p, "
|
||||
"tail:%p, "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"linkedlist", "size_t", l_, l_->count, l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc,
|
||||
(l_)->callbacks);
|
||||
}
|
||||
struct linkedlist_iter ll_iter_end(struct linkedlist *target)
|
||||
_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end)
|
||||
{
|
||||
struct linkedlist_iter iter;
|
||||
iter.target = target;
|
||||
iter.cursor = target->tail;
|
||||
iter.index = 0;
|
||||
iter.start = ll_empty(target);
|
||||
iter.end = 1;
|
||||
if (!ll_empty(target))
|
||||
iter.index = target->count - 1;
|
||||
return iter;
|
||||
}
|
||||
_Bool ll_iter_at_start(struct linkedlist_iter *iter)
|
||||
{
|
||||
return ll_empty(iter->target) || iter->start;
|
||||
}
|
||||
_Bool ll_iter_at_end(struct linkedlist_iter *iter)
|
||||
{
|
||||
return ll_empty(iter->target) || iter->end;
|
||||
}
|
||||
_Bool ll_iter_to_start(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (!ll_empty(iter->target))
|
||||
fprintf(fptr, "%s", start);
|
||||
struct linkedlist_node *scan = _list_->head;
|
||||
while (scan != ((void *)0))
|
||||
{
|
||||
iter->cursor = iter->target->head;
|
||||
iter->index = 0;
|
||||
iter->start = 1;
|
||||
iter->end = ll_empty(iter->target);
|
||||
return 1;
|
||||
if (!_list_->f_val->str(fptr, scan->value))
|
||||
return 0;
|
||||
scan = scan->next;
|
||||
if (scan)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
_Bool ll_iter_to_end(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (!ll_empty(iter->target))
|
||||
{
|
||||
iter->cursor = iter->target->tail;
|
||||
iter->index = iter->target->count - 1;
|
||||
iter->start = ll_empty(iter->target);
|
||||
iter->end = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
_Bool ll_iter_next(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (iter->end)
|
||||
return 0;
|
||||
if (iter->cursor->next == ((void *)0))
|
||||
{
|
||||
iter->end = 1;
|
||||
return 0;
|
||||
}
|
||||
iter->start = ll_empty(iter->target);
|
||||
iter->cursor = iter->cursor->next;
|
||||
iter->index++;
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_iter_prev(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (iter->start)
|
||||
return 0;
|
||||
if (iter->cursor->prev == ((void *)0))
|
||||
{
|
||||
iter->start = 1;
|
||||
return 0;
|
||||
}
|
||||
iter->end = ll_empty(iter->target);
|
||||
iter->cursor = iter->cursor->prev;
|
||||
iter->index--;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps)
|
||||
{
|
||||
if (iter->end)
|
||||
return 0;
|
||||
if (iter->cursor->next == ((void *)0))
|
||||
{
|
||||
iter->end = 1;
|
||||
return 0;
|
||||
}
|
||||
if (steps == 0 || iter->index + steps >= iter->target->count)
|
||||
return 0;
|
||||
iter->start = ll_empty(iter->target);
|
||||
iter->index += steps;
|
||||
for (size_t i = 0; i < steps; i++)
|
||||
iter->cursor = iter->cursor->next;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps)
|
||||
{
|
||||
if (iter->start)
|
||||
return 0;
|
||||
if (iter->cursor->prev == ((void *)0))
|
||||
{
|
||||
iter->start = 1;
|
||||
return 0;
|
||||
}
|
||||
if (steps == 0 || iter->index < steps)
|
||||
return 0;
|
||||
iter->end = ll_empty(iter->target);
|
||||
iter->index -= steps;
|
||||
for (size_t i = 0; i < steps; i++)
|
||||
iter->cursor = iter->cursor->prev;
|
||||
return 1;
|
||||
}
|
||||
_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index)
|
||||
{
|
||||
if (index >= iter->target->count)
|
||||
return 0;
|
||||
if (iter->index > index)
|
||||
return ll_iter_rewind(iter, iter->index - index);
|
||||
else if (iter->index < index)
|
||||
return ll_iter_advance(iter, index - iter->index);
|
||||
return 1;
|
||||
}
|
||||
size_t ll_iter_value(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (ll_empty(iter->target))
|
||||
return (size_t){ 0 };
|
||||
return iter->cursor->value;
|
||||
}
|
||||
size_t *ll_iter_rvalue(struct linkedlist_iter *iter)
|
||||
{
|
||||
if (ll_empty(iter->target))
|
||||
return ((void *)0);
|
||||
return &(iter->cursor->value);
|
||||
}
|
||||
size_t ll_iter_index(struct linkedlist_iter *iter)
|
||||
{
|
||||
return iter->index;
|
||||
}
|
||||
struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter)
|
||||
{
|
||||
return iter->cursor;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_LINKEDLIST */
|
||||
+217
-181
@@ -22,13 +22,6 @@ struct list_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct list_iter
|
||||
{
|
||||
struct list *target;
|
||||
size_t cursor;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct list *l_new(size_t capacity, struct list_fval *f_val);
|
||||
struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks);
|
||||
@@ -41,11 +34,6 @@ _Bool l_push_back(struct list *_list_, size_t value);
|
||||
_Bool l_pop_front(struct list *_list_);
|
||||
_Bool l_pop_at(struct list *_list_, size_t index);
|
||||
_Bool l_pop_back(struct list *_list_);
|
||||
_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size);
|
||||
_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index);
|
||||
_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size);
|
||||
_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to);
|
||||
struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to);
|
||||
size_t l_front(struct list *_list_);
|
||||
size_t l_get(struct list *_list_, size_t index);
|
||||
size_t *l_get_ref(struct list *_list_, size_t index);
|
||||
@@ -61,8 +49,13 @@ int l_flag(struct list *_list_);
|
||||
_Bool l_resize(struct list *_list_, size_t capacity);
|
||||
struct list *l_copy_of(struct list *_list_);
|
||||
_Bool l_equals(struct list *_list1_, struct list *_list2_);
|
||||
struct cmc_string l_to_string(struct list *_list_);
|
||||
_Bool l_print(struct list *_list_, FILE *fptr);
|
||||
struct list_iter
|
||||
{
|
||||
struct list *target;
|
||||
size_t cursor;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct list_iter l_iter_start(struct list *target);
|
||||
struct list_iter l_iter_end(struct list *target);
|
||||
_Bool l_iter_at_start(struct list_iter *iter);
|
||||
@@ -77,31 +70,21 @@ _Bool l_iter_go_to(struct list_iter *iter, size_t index);
|
||||
size_t l_iter_value(struct list_iter *iter);
|
||||
size_t *l_iter_rvalue(struct list_iter *iter);
|
||||
size_t l_iter_index(struct list_iter *iter);
|
||||
_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size);
|
||||
_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index);
|
||||
_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size);
|
||||
_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to);
|
||||
struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to);
|
||||
_Bool l_to_string(struct list *_list_, FILE *fptr);
|
||||
_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end);
|
||||
struct list *l_new(size_t capacity, struct list_fval *f_val)
|
||||
{
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
struct list *_list_ = alloc->malloc(sizeof(struct list));
|
||||
if (!_list_)
|
||||
return ((void *)0);
|
||||
_list_->buffer = alloc->calloc(capacity, sizeof(size_t));
|
||||
if (!_list_->buffer)
|
||||
{
|
||||
alloc->free(_list_);
|
||||
return ((void *)0);
|
||||
}
|
||||
_list_->capacity = capacity;
|
||||
_list_->count = 0;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
_list_->f_val = f_val;
|
||||
_list_->alloc = alloc;
|
||||
_list_->callbacks = ((void *)0);
|
||||
return _list_;
|
||||
return l_new_custom(capacity, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
@@ -122,7 +105,7 @@ struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_a
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
_list_->f_val = f_val;
|
||||
_list_->alloc = alloc;
|
||||
_list_->callbacks = callbacks;
|
||||
(_list_)->callbacks = callbacks;
|
||||
return _list_;
|
||||
}
|
||||
void l_clear(struct list *_list_)
|
||||
@@ -148,11 +131,12 @@ void l_free(struct list *_list_)
|
||||
}
|
||||
void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_list_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_list_->alloc = alloc;
|
||||
_list_->callbacks = callbacks;
|
||||
(_list_)->callbacks = callbacks;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool l_push_front(struct list *_list_, size_t value)
|
||||
@@ -169,8 +153,9 @@ _Bool l_push_front(struct list *_list_, size_t value)
|
||||
_list_->buffer[0] = value;
|
||||
_list_->count++;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->create)
|
||||
_list_->callbacks->create();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->create)
|
||||
(_list_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool l_push_at(struct list *_list_, size_t value, size_t index)
|
||||
@@ -189,8 +174,9 @@ _Bool l_push_at(struct list *_list_, size_t value, size_t index)
|
||||
_list_->buffer[index] = value;
|
||||
_list_->count++;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->create)
|
||||
_list_->callbacks->create();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->create)
|
||||
(_list_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool l_push_back(struct list *_list_, size_t value)
|
||||
@@ -202,8 +188,9 @@ _Bool l_push_back(struct list *_list_, size_t value)
|
||||
}
|
||||
_list_->buffer[_list_->count++] = value;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->create)
|
||||
_list_->callbacks->create();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->create)
|
||||
(_list_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool l_pop_front(struct list *_list_)
|
||||
@@ -216,8 +203,9 @@ _Bool l_pop_front(struct list *_list_)
|
||||
memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(size_t));
|
||||
_list_->buffer[--_list_->count] = (size_t){ 0 };
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->delete)
|
||||
_list_->callbacks->delete ();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->delete)
|
||||
(_list_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool l_pop_at(struct list *_list_, size_t index)
|
||||
@@ -235,8 +223,9 @@ _Bool l_pop_at(struct list *_list_, size_t index)
|
||||
memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(size_t));
|
||||
_list_->buffer[--_list_->count] = (size_t){ 0 };
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->delete)
|
||||
_list_->callbacks->delete ();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->delete)
|
||||
(_list_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool l_pop_back(struct list *_list_)
|
||||
@@ -245,128 +234,11 @@ _Bool l_pop_back(struct list *_list_)
|
||||
return 0;
|
||||
_list_->buffer[--_list_->count] = (size_t){ 0 };
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->delete)
|
||||
_list_->callbacks->delete ();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->delete)
|
||||
(_list_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (!l_fits(_list_, size))
|
||||
{
|
||||
if (!l_resize(_list_, _list_->count + size))
|
||||
return 0;
|
||||
}
|
||||
memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t));
|
||||
memcpy(_list_->buffer, values, size * sizeof(size_t));
|
||||
_list_->count += size;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->create)
|
||||
_list_->callbacks->create();
|
||||
return 1;
|
||||
}
|
||||
_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (index > _list_->count)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_RANGE;
|
||||
return 0;
|
||||
}
|
||||
if (index == 0)
|
||||
return l_seq_push_front(_list_, values, size);
|
||||
else if (index == _list_->count)
|
||||
return l_seq_push_back(_list_, values, size);
|
||||
if (!l_fits(_list_, size))
|
||||
{
|
||||
if (!l_resize(_list_, _list_->count + size))
|
||||
return 0;
|
||||
}
|
||||
memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t));
|
||||
memcpy(_list_->buffer + index, values, size * sizeof(size_t));
|
||||
_list_->count += size;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->create)
|
||||
_list_->callbacks->create();
|
||||
return 1;
|
||||
}
|
||||
_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (!l_fits(_list_, size))
|
||||
{
|
||||
if (!l_resize(_list_, _list_->count + size))
|
||||
return 0;
|
||||
}
|
||||
memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t));
|
||||
_list_->count += size;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->create)
|
||||
_list_->callbacks->create();
|
||||
return 1;
|
||||
}
|
||||
_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to)
|
||||
{
|
||||
if (from > to)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (to >= _list_->count)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_RANGE;
|
||||
return 0;
|
||||
}
|
||||
size_t length = (to - from + 1);
|
||||
memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t));
|
||||
memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t));
|
||||
_list_->count -= to - from + 1;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->delete)
|
||||
_list_->callbacks->delete ();
|
||||
return 1;
|
||||
}
|
||||
struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to)
|
||||
{
|
||||
if (from > to)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_INVALID;
|
||||
return ((void *)0);
|
||||
}
|
||||
if (to >= _list_->count)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_RANGE;
|
||||
return ((void *)0);
|
||||
}
|
||||
size_t length = to - from + 1;
|
||||
struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, _list_->callbacks);
|
||||
if (!result)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_ALLOC;
|
||||
return ((void *)0);
|
||||
}
|
||||
memcpy(result->buffer, _list_->buffer, length * sizeof(size_t));
|
||||
memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t));
|
||||
memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t));
|
||||
_list_->count -= length;
|
||||
result->count = length;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->delete)
|
||||
_list_->callbacks->delete ();
|
||||
return result;
|
||||
}
|
||||
size_t l_front(struct list *_list_)
|
||||
{
|
||||
if (l_empty(_list_))
|
||||
@@ -375,8 +247,9 @@ size_t l_front(struct list *_list_)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return _list_->buffer[0];
|
||||
}
|
||||
size_t l_get(struct list *_list_, size_t index)
|
||||
@@ -392,8 +265,9 @@ size_t l_get(struct list *_list_, size_t index)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return _list_->buffer[index];
|
||||
}
|
||||
size_t *l_get_ref(struct list *_list_, size_t index)
|
||||
@@ -409,8 +283,9 @@ size_t *l_get_ref(struct list *_list_, size_t index)
|
||||
return ((void *)0);
|
||||
}
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return &(_list_->buffer[index]);
|
||||
}
|
||||
size_t l_back(struct list *_list_)
|
||||
@@ -421,8 +296,9 @@ size_t l_back(struct list *_list_)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return _list_->buffer[_list_->count - 1];
|
||||
}
|
||||
size_t l_index_of(struct list *_list_, size_t value, _Bool from_start)
|
||||
@@ -451,8 +327,9 @@ size_t l_index_of(struct list *_list_, size_t value, _Bool from_start)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool l_contains(struct list *_list_, size_t value)
|
||||
@@ -467,8 +344,9 @@ _Bool l_contains(struct list *_list_, size_t value)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool l_empty(struct list *_list_)
|
||||
@@ -513,18 +391,20 @@ _Bool l_resize(struct list *_list_, size_t capacity)
|
||||
}
|
||||
_list_->buffer = new_buffer;
|
||||
_list_->capacity = capacity;
|
||||
if (_list_->callbacks && _list_->callbacks->resize)
|
||||
_list_->callbacks->resize();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->resize)
|
||||
(_list_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct list *l_copy_of(struct list *_list_)
|
||||
{
|
||||
struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, _list_->callbacks);
|
||||
struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_ALLOC;
|
||||
return ((void *)0);
|
||||
}
|
||||
(result)->callbacks = _list_->callbacks;
|
||||
if (_list_->f_val->cpy)
|
||||
{
|
||||
for (size_t i = 0; i < _list_->count; i++)
|
||||
@@ -544,7 +424,7 @@ _Bool l_equals(struct list *_list1_, struct list *_list2_)
|
||||
return 0;
|
||||
for (size_t i = 0; i < _list1_->count; i++)
|
||||
{
|
||||
if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0)
|
||||
if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -681,5 +561,161 @@ size_t l_iter_index(struct list_iter *iter)
|
||||
{
|
||||
return iter->cursor;
|
||||
}
|
||||
_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (!l_fits(_list_, size))
|
||||
{
|
||||
if (!l_resize(_list_, _list_->count + size))
|
||||
return 0;
|
||||
}
|
||||
memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t));
|
||||
memcpy(_list_->buffer, values, size * sizeof(size_t));
|
||||
_list_->count += size;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->create)
|
||||
(_list_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (index > _list_->count)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_RANGE;
|
||||
return 0;
|
||||
}
|
||||
if (index == 0)
|
||||
return l_seq_push_front(_list_, values, size);
|
||||
else if (index == _list_->count)
|
||||
return l_seq_push_back(_list_, values, size);
|
||||
if (!l_fits(_list_, size))
|
||||
{
|
||||
if (!l_resize(_list_, _list_->count + size))
|
||||
return 0;
|
||||
}
|
||||
memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t));
|
||||
memcpy(_list_->buffer + index, values, size * sizeof(size_t));
|
||||
_list_->count += size;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->create)
|
||||
(_list_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (!l_fits(_list_, size))
|
||||
{
|
||||
if (!l_resize(_list_, _list_->count + size))
|
||||
return 0;
|
||||
}
|
||||
memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t));
|
||||
_list_->count += size;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->create)
|
||||
(_list_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to)
|
||||
{
|
||||
if (from > to)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (to >= _list_->count)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_RANGE;
|
||||
return 0;
|
||||
}
|
||||
size_t length = (to - from + 1);
|
||||
memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t));
|
||||
memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t));
|
||||
_list_->count -= to - from + 1;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->delete)
|
||||
(_list_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to)
|
||||
{
|
||||
if (from > to)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_INVALID;
|
||||
return ((void *)0);
|
||||
}
|
||||
if (to >= _list_->count)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_RANGE;
|
||||
return ((void *)0);
|
||||
}
|
||||
size_t length = to - from + 1;
|
||||
struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, (_list_)->callbacks);
|
||||
if (!result)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_ALLOC;
|
||||
return ((void *)0);
|
||||
}
|
||||
memcpy(result->buffer, _list_->buffer, length * sizeof(size_t));
|
||||
memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t));
|
||||
memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t));
|
||||
_list_->count -= length;
|
||||
result->count = length;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->delete)
|
||||
(_list_)->callbacks->delete ();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool l_to_string(struct list *_list_, FILE *fptr)
|
||||
{
|
||||
struct list *l_ = _list_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"list", "size_t", l_, l_->buffer, l_->capacity, l_->count, l_->flag, l_->f_val, l_->alloc,
|
||||
(l_)->callbacks);
|
||||
}
|
||||
_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end)
|
||||
{
|
||||
fprintf(fptr, "%s", start);
|
||||
for (size_t i = 0; i < _list_->count; i++)
|
||||
{
|
||||
if (!_list_->f_val->str(fptr, _list_->buffer[i]))
|
||||
return 0;
|
||||
if (i + 1 < _list_->count)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_LIST */
|
||||
+64
-38
@@ -50,8 +50,6 @@ int q_flag(struct queue *_queue_);
|
||||
_Bool q_resize(struct queue *_queue_, size_t capacity);
|
||||
struct queue *q_copy_of(struct queue *_queue_);
|
||||
_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_);
|
||||
struct cmc_string q_to_string(struct queue *_queue_);
|
||||
_Bool q_print(struct queue *_queue_, FILE *fptr);
|
||||
struct queue_iter q_iter_start(struct queue *target);
|
||||
struct queue_iter q_iter_end(struct queue *target);
|
||||
_Bool q_iter_at_start(struct queue_iter *iter);
|
||||
@@ -66,35 +64,16 @@ _Bool q_iter_go_to(struct queue_iter *iter, size_t index);
|
||||
size_t q_iter_value(struct queue_iter *iter);
|
||||
size_t *q_iter_rvalue(struct queue_iter *iter);
|
||||
size_t q_iter_index(struct queue_iter *iter);
|
||||
_Bool q_to_string(struct queue *_queue_, FILE *fptr);
|
||||
_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end);
|
||||
struct queue *q_new(size_t capacity, struct queue_fval *f_val)
|
||||
{
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
return ((void *)0);
|
||||
struct queue *_queue_ = alloc->malloc(sizeof(struct queue));
|
||||
if (!_queue_)
|
||||
return ((void *)0);
|
||||
_queue_->buffer = alloc->calloc(capacity, sizeof(size_t));
|
||||
if (!_queue_->buffer)
|
||||
{
|
||||
alloc->free(_queue_);
|
||||
return ((void *)0);
|
||||
}
|
||||
_queue_->capacity = capacity;
|
||||
_queue_->count = 0;
|
||||
_queue_->front = 0;
|
||||
_queue_->back = 0;
|
||||
_queue_->flag = CMC_FLAG_OK;
|
||||
_queue_->f_val = f_val;
|
||||
_queue_->alloc = alloc;
|
||||
_queue_->callbacks = ((void *)0);
|
||||
return _queue_;
|
||||
return q_new_custom(capacity, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
@@ -117,7 +96,7 @@ struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc
|
||||
_queue_->flag = CMC_FLAG_OK;
|
||||
_queue_->f_val = f_val;
|
||||
_queue_->alloc = alloc;
|
||||
_queue_->callbacks = callbacks;
|
||||
(_queue_)->callbacks = callbacks;
|
||||
return _queue_;
|
||||
}
|
||||
void q_clear(struct queue *_queue_)
|
||||
@@ -151,11 +130,12 @@ void q_free(struct queue *_queue_)
|
||||
}
|
||||
void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_queue_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_queue_->alloc = alloc;
|
||||
_queue_->callbacks = callbacks;
|
||||
(_queue_)->callbacks = callbacks;
|
||||
_queue_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool q_enqueue(struct queue *_queue_, size_t value)
|
||||
@@ -169,8 +149,9 @@ _Bool q_enqueue(struct queue *_queue_, size_t value)
|
||||
_queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1;
|
||||
_queue_->count++;
|
||||
_queue_->flag = CMC_FLAG_OK;
|
||||
if (_queue_->callbacks && _queue_->callbacks->create)
|
||||
_queue_->callbacks->create();
|
||||
if ((_queue_)->callbacks && (_queue_)->callbacks->create)
|
||||
(_queue_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool q_dequeue(struct queue *_queue_)
|
||||
@@ -184,8 +165,9 @@ _Bool q_dequeue(struct queue *_queue_)
|
||||
_queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1;
|
||||
_queue_->count--;
|
||||
_queue_->flag = CMC_FLAG_OK;
|
||||
if (_queue_->callbacks && _queue_->callbacks->delete)
|
||||
_queue_->callbacks->delete ();
|
||||
if ((_queue_)->callbacks && (_queue_)->callbacks->delete)
|
||||
(_queue_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t q_peek(struct queue *_queue_)
|
||||
@@ -196,8 +178,9 @@ size_t q_peek(struct queue *_queue_)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_queue_->flag = CMC_FLAG_OK;
|
||||
if (_queue_->callbacks && _queue_->callbacks->read)
|
||||
_queue_->callbacks->read();
|
||||
if ((_queue_)->callbacks && (_queue_)->callbacks->read)
|
||||
(_queue_)->callbacks->read();
|
||||
;
|
||||
return _queue_->buffer[_queue_->front];
|
||||
}
|
||||
_Bool q_contains(struct queue *_queue_, size_t value)
|
||||
@@ -213,8 +196,9 @@ _Bool q_contains(struct queue *_queue_, size_t value)
|
||||
}
|
||||
i = (i + 1) % _queue_->capacity;
|
||||
}
|
||||
if (_queue_->callbacks && _queue_->callbacks->read)
|
||||
_queue_->callbacks->read();
|
||||
if ((_queue_)->callbacks && (_queue_)->callbacks->read)
|
||||
(_queue_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool q_empty(struct queue *_queue_)
|
||||
@@ -264,18 +248,20 @@ _Bool q_resize(struct queue *_queue_, size_t capacity)
|
||||
_queue_->back = _queue_->count;
|
||||
success:
|
||||
_queue_->flag = CMC_FLAG_OK;
|
||||
if (_queue_->callbacks && _queue_->callbacks->resize)
|
||||
_queue_->callbacks->resize();
|
||||
if ((_queue_)->callbacks && (_queue_)->callbacks->resize)
|
||||
(_queue_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct queue *q_copy_of(struct queue *_queue_)
|
||||
{
|
||||
struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, _queue_->callbacks);
|
||||
struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
{
|
||||
_queue_->flag = CMC_FLAG_ERROR;
|
||||
return ((void *)0);
|
||||
}
|
||||
(result)->callbacks = _queue_->callbacks;
|
||||
if (_queue_->f_val->cpy)
|
||||
{
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++)
|
||||
@@ -468,5 +454,45 @@ size_t q_iter_index(struct queue_iter *iter)
|
||||
{
|
||||
return iter->index;
|
||||
}
|
||||
_Bool q_to_string(struct queue *_queue_, FILE *fptr)
|
||||
{
|
||||
struct queue *q_ = _queue_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"front:%"
|
||||
"I64u"
|
||||
", "
|
||||
"back:%"
|
||||
"I64u"
|
||||
", "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"queue", "size_t", q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back, q_->flag,
|
||||
q_->f_val, q_->alloc, (q_)->callbacks);
|
||||
}
|
||||
_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end)
|
||||
{
|
||||
fprintf(fptr, "%s", start);
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++)
|
||||
{
|
||||
if (!_queue_->f_val->str(fptr, _queue_->buffer[i]))
|
||||
return 0;
|
||||
i = (i + 1) % _queue_->capacity;
|
||||
if (j + 1 < _queue_->count)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_QUEUE */
|
||||
+158
-133
@@ -23,13 +23,6 @@ struct sortedlist_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct sortedlist_iter
|
||||
{
|
||||
struct sortedlist *target;
|
||||
size_t cursor;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val);
|
||||
struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks);
|
||||
@@ -52,8 +45,13 @@ _Bool sl_resize(struct sortedlist *_list_, size_t capacity);
|
||||
void sl_sort(struct sortedlist *_list_);
|
||||
struct sortedlist *sl_copy_of(struct sortedlist *_list_);
|
||||
_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_);
|
||||
struct cmc_string sl_to_string(struct sortedlist *_list_);
|
||||
_Bool sl_print(struct sortedlist *_list_, FILE *fptr);
|
||||
struct sortedlist_iter
|
||||
{
|
||||
struct sortedlist *target;
|
||||
size_t cursor;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct sortedlist_iter sl_iter_start(struct sortedlist *target);
|
||||
struct sortedlist_iter sl_iter_end(struct sortedlist *target);
|
||||
_Bool sl_iter_at_start(struct sortedlist_iter *iter);
|
||||
@@ -67,38 +65,20 @@ _Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps);
|
||||
_Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index);
|
||||
size_t sl_iter_value(struct sortedlist_iter *iter);
|
||||
size_t sl_iter_index(struct sortedlist_iter *iter);
|
||||
_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr);
|
||||
_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end);
|
||||
static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value);
|
||||
static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value);
|
||||
void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high);
|
||||
void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high);
|
||||
struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val)
|
||||
{
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
return ((void *)0);
|
||||
struct sortedlist *_list_ = alloc->malloc(sizeof(struct sortedlist));
|
||||
if (!_list_)
|
||||
return ((void *)0);
|
||||
_list_->buffer = alloc->calloc(capacity, sizeof(size_t));
|
||||
if (!_list_->buffer)
|
||||
{
|
||||
alloc->free(_list_);
|
||||
return ((void *)0);
|
||||
}
|
||||
_list_->capacity = capacity;
|
||||
_list_->count = 0;
|
||||
_list_->is_sorted = 0;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
_list_->f_val = f_val;
|
||||
_list_->alloc = alloc;
|
||||
_list_->callbacks = ((void *)0);
|
||||
return _list_;
|
||||
return sl_new_custom(capacity, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
if (!alloc)
|
||||
@@ -118,7 +98,7 @@ struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val,
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
_list_->f_val = f_val;
|
||||
_list_->alloc = alloc;
|
||||
_list_->callbacks = callbacks;
|
||||
(_list_)->callbacks = callbacks;
|
||||
return _list_;
|
||||
}
|
||||
void sl_clear(struct sortedlist *_list_)
|
||||
@@ -144,11 +124,12 @@ void sl_free(struct sortedlist *_list_)
|
||||
}
|
||||
void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_list_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_list_->alloc = alloc;
|
||||
_list_->callbacks = callbacks;
|
||||
(_list_)->callbacks = callbacks;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool sl_insert(struct sortedlist *_list_, size_t value)
|
||||
@@ -161,8 +142,9 @@ _Bool sl_insert(struct sortedlist *_list_, size_t value)
|
||||
_list_->buffer[_list_->count++] = value;
|
||||
_list_->is_sorted = 0;
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->create)
|
||||
_list_->callbacks->create();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->create)
|
||||
(_list_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool sl_remove(struct sortedlist *_list_, size_t index)
|
||||
@@ -180,8 +162,9 @@ _Bool sl_remove(struct sortedlist *_list_, size_t index)
|
||||
memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(size_t));
|
||||
_list_->buffer[--_list_->count] = (size_t){ 0 };
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->delete)
|
||||
_list_->callbacks->delete ();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->delete)
|
||||
(_list_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t sl_max(struct sortedlist *_list_)
|
||||
@@ -193,8 +176,9 @@ size_t sl_max(struct sortedlist *_list_)
|
||||
}
|
||||
sl_sort(_list_);
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return _list_->buffer[_list_->count - 1];
|
||||
}
|
||||
size_t sl_min(struct sortedlist *_list_)
|
||||
@@ -206,8 +190,9 @@ size_t sl_min(struct sortedlist *_list_)
|
||||
}
|
||||
sl_sort(_list_);
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return _list_->buffer[0];
|
||||
}
|
||||
size_t sl_get(struct sortedlist *_list_, size_t index)
|
||||
@@ -224,16 +209,18 @@ size_t sl_get(struct sortedlist *_list_, size_t index)
|
||||
}
|
||||
sl_sort(_list_);
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return _list_->buffer[index];
|
||||
}
|
||||
size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
sl_sort(_list_);
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
if (from_start)
|
||||
{
|
||||
return sl_impl_binary_search_first(_list_, value);
|
||||
@@ -246,8 +233,9 @@ _Bool sl_contains(struct sortedlist *_list_, size_t value)
|
||||
if (sl_empty(_list_))
|
||||
return 0;
|
||||
sl_sort(_list_);
|
||||
if (_list_->callbacks && _list_->callbacks->read)
|
||||
_list_->callbacks->read();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->read)
|
||||
(_list_)->callbacks->read();
|
||||
;
|
||||
return sl_impl_binary_search_first(_list_, value) < _list_->count;
|
||||
}
|
||||
_Bool sl_empty(struct sortedlist *_list_)
|
||||
@@ -289,8 +277,9 @@ _Bool sl_resize(struct sortedlist *_list_, size_t capacity)
|
||||
_list_->capacity = capacity;
|
||||
success:
|
||||
_list_->flag = CMC_FLAG_OK;
|
||||
if (_list_->callbacks && _list_->callbacks->resize)
|
||||
_list_->callbacks->resize();
|
||||
if ((_list_)->callbacks && (_list_)->callbacks->resize)
|
||||
(_list_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
void sl_sort(struct sortedlist *_list_)
|
||||
@@ -304,12 +293,13 @@ void sl_sort(struct sortedlist *_list_)
|
||||
}
|
||||
struct sortedlist *sl_copy_of(struct sortedlist *_list_)
|
||||
{
|
||||
struct sortedlist *result = sl_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, _list_->callbacks);
|
||||
struct sortedlist *result = sl_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
{
|
||||
_list_->flag = CMC_FLAG_ERROR;
|
||||
return ((void *)0);
|
||||
}
|
||||
(result)->callbacks = _list_->callbacks;
|
||||
if (_list_->f_val->cpy)
|
||||
{
|
||||
for (size_t i = 0; i < _list_->count; i++)
|
||||
@@ -334,6 +324,95 @@ _Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value)
|
||||
{
|
||||
if (sl_empty(_list_))
|
||||
return 1;
|
||||
size_t L = 0;
|
||||
size_t R = _list_->count;
|
||||
while (L < R)
|
||||
{
|
||||
size_t M = L + (R - L) / 2;
|
||||
if (_list_->f_val->cmp(_list_->buffer[M], value) < 0)
|
||||
L = M + 1;
|
||||
else
|
||||
R = M;
|
||||
}
|
||||
if (_list_->f_val->cmp(_list_->buffer[L], value) == 0)
|
||||
return L;
|
||||
return _list_->count;
|
||||
}
|
||||
static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value)
|
||||
{
|
||||
if (sl_empty(_list_))
|
||||
return 1;
|
||||
size_t L = 0;
|
||||
size_t R = _list_->count;
|
||||
while (L < R)
|
||||
{
|
||||
size_t M = L + (R - L) / 2;
|
||||
if (_list_->f_val->cmp(_list_->buffer[M], value) > 0)
|
||||
R = M;
|
||||
else
|
||||
L = M + 1;
|
||||
}
|
||||
if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0)
|
||||
return L - 1;
|
||||
return _list_->count;
|
||||
}
|
||||
void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high)
|
||||
{
|
||||
while (low < high)
|
||||
{
|
||||
if (high - low < 10)
|
||||
{
|
||||
sl_impl_sort_insertion(array, cmp, low, high);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t pivot = array[high];
|
||||
size_t pindex = low;
|
||||
for (size_t i = low; i < high; i++)
|
||||
{
|
||||
if (cmp(array[i], pivot) <= 0)
|
||||
{
|
||||
size_t _tmp_ = array[i];
|
||||
array[i] = array[pindex];
|
||||
array[pindex] = _tmp_;
|
||||
pindex++;
|
||||
}
|
||||
}
|
||||
size_t _tmp_ = array[pindex];
|
||||
array[pindex] = array[high];
|
||||
array[high] = _tmp_;
|
||||
if (pindex - low < high - pindex)
|
||||
{
|
||||
sl_impl_sort_quicksort(array, cmp, low, pindex - 1);
|
||||
low = pindex + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sl_impl_sort_quicksort(array, cmp, pindex + 1, high);
|
||||
high = pindex - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high)
|
||||
{
|
||||
for (size_t i = low + 1; i <= high; i++)
|
||||
{
|
||||
size_t _tmp_ = array[i];
|
||||
size_t j = i;
|
||||
while (j > low && cmp(array[j - 1], _tmp_) > 0)
|
||||
{
|
||||
array[j] = array[j - 1];
|
||||
j--;
|
||||
}
|
||||
array[j] = _tmp_;
|
||||
}
|
||||
}
|
||||
struct sortedlist_iter sl_iter_start(struct sortedlist *target)
|
||||
{
|
||||
sl_sort(target);
|
||||
@@ -462,94 +541,40 @@ size_t sl_iter_index(struct sortedlist_iter *iter)
|
||||
{
|
||||
return iter->cursor;
|
||||
}
|
||||
static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value)
|
||||
_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr)
|
||||
{
|
||||
if (sl_empty(_list_))
|
||||
return 1;
|
||||
size_t L = 0;
|
||||
size_t R = _list_->count;
|
||||
while (L < R)
|
||||
{
|
||||
size_t M = L + (R - L) / 2;
|
||||
if (_list_->f_val->cmp(_list_->buffer[M], value) < 0)
|
||||
L = M + 1;
|
||||
else
|
||||
R = M;
|
||||
}
|
||||
if (_list_->f_val->cmp(_list_->buffer[L], value) == 0)
|
||||
return L;
|
||||
return _list_->count;
|
||||
struct sortedlist *l_ = _list_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"is_sorted:%s, "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"sortedlist", "size_t", l_, l_->buffer, l_->capacity, l_->count,
|
||||
l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, (l_)->callbacks);
|
||||
}
|
||||
static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value)
|
||||
_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end)
|
||||
{
|
||||
if (sl_empty(_list_))
|
||||
return 1;
|
||||
size_t L = 0;
|
||||
size_t R = _list_->count;
|
||||
while (L < R)
|
||||
sl_sort(_list_);
|
||||
fprintf(fptr, "%s", start);
|
||||
for (size_t i = 0; i < _list_->count; i++)
|
||||
{
|
||||
size_t M = L + (R - L) / 2;
|
||||
if (_list_->f_val->cmp(_list_->buffer[M], value) > 0)
|
||||
R = M;
|
||||
else
|
||||
L = M + 1;
|
||||
}
|
||||
if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0)
|
||||
return L - 1;
|
||||
return _list_->count;
|
||||
}
|
||||
void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high)
|
||||
{
|
||||
while (low < high)
|
||||
{
|
||||
if (high - low < 10)
|
||||
{
|
||||
sl_impl_sort_insertion(array, cmp, low, high);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t pivot = array[high];
|
||||
size_t pindex = low;
|
||||
for (size_t i = low; i < high; i++)
|
||||
{
|
||||
if (cmp(array[i], pivot) <= 0)
|
||||
{
|
||||
size_t _tmp_ = array[i];
|
||||
array[i] = array[pindex];
|
||||
array[pindex] = _tmp_;
|
||||
pindex++;
|
||||
}
|
||||
}
|
||||
size_t _tmp_ = array[pindex];
|
||||
array[pindex] = array[high];
|
||||
array[high] = _tmp_;
|
||||
if (pindex - low < high - pindex)
|
||||
{
|
||||
sl_impl_sort_quicksort(array, cmp, low, pindex - 1);
|
||||
low = pindex + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sl_impl_sort_quicksort(array, cmp, pindex + 1, high);
|
||||
high = pindex - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high)
|
||||
{
|
||||
for (size_t i = low + 1; i <= high; i++)
|
||||
{
|
||||
size_t _tmp_ = array[i];
|
||||
size_t j = i;
|
||||
while (j > low && cmp(array[j - 1], _tmp_) > 0)
|
||||
{
|
||||
array[j] = array[j - 1];
|
||||
j--;
|
||||
}
|
||||
array[j] = _tmp_;
|
||||
if (!_list_->f_val->str(fptr, _list_->buffer[i]))
|
||||
return 0;
|
||||
if (i + 1 < _list_->count)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_SORTEDLIST */
|
||||
+64
-43
@@ -22,13 +22,6 @@ struct stack_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct stack_iter
|
||||
{
|
||||
struct stack *target;
|
||||
size_t cursor;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct stack *s_new(size_t capacity, struct stack_fval *f_val);
|
||||
struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks);
|
||||
@@ -47,8 +40,13 @@ int s_flag(struct stack *_stack_);
|
||||
_Bool s_resize(struct stack *_stack_, size_t capacity);
|
||||
struct stack *s_copy_of(struct stack *_stack_);
|
||||
_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_);
|
||||
struct cmc_string s_to_string(struct stack *_stack_);
|
||||
_Bool s_print(struct stack *_stack_, FILE *fptr);
|
||||
struct stack_iter
|
||||
{
|
||||
struct stack *target;
|
||||
size_t cursor;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct stack_iter s_iter_start(struct stack *target);
|
||||
struct stack_iter s_iter_end(struct stack *target);
|
||||
_Bool s_iter_at_start(struct stack_iter *iter);
|
||||
@@ -63,33 +61,16 @@ _Bool s_iter_go_to(struct stack_iter *iter, size_t index);
|
||||
size_t s_iter_value(struct stack_iter *iter);
|
||||
size_t *s_iter_rvalue(struct stack_iter *iter);
|
||||
size_t s_iter_index(struct stack_iter *iter);
|
||||
_Bool s_to_string(struct stack *_stack_, FILE *fptr);
|
||||
_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end);
|
||||
struct stack *s_new(size_t capacity, struct stack_fval *f_val)
|
||||
{
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
return ((void *)0);
|
||||
struct stack *_stack_ = alloc->malloc(sizeof(struct stack));
|
||||
if (!_stack_)
|
||||
return ((void *)0);
|
||||
_stack_->buffer = alloc->calloc(capacity, sizeof(size_t));
|
||||
if (!_stack_->buffer)
|
||||
{
|
||||
alloc->free(_stack_);
|
||||
return ((void *)0);
|
||||
}
|
||||
_stack_->capacity = capacity;
|
||||
_stack_->count = 0;
|
||||
_stack_->flag = CMC_FLAG_OK;
|
||||
_stack_->f_val = f_val;
|
||||
_stack_->alloc = alloc;
|
||||
_stack_->callbacks = ((void *)0);
|
||||
return _stack_;
|
||||
return s_new_custom(capacity, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
if (!f_val)
|
||||
@@ -110,7 +91,7 @@ struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc
|
||||
_stack_->flag = CMC_FLAG_OK;
|
||||
_stack_->f_val = f_val;
|
||||
_stack_->alloc = alloc;
|
||||
_stack_->callbacks = callbacks;
|
||||
(_stack_)->callbacks = callbacks;
|
||||
return _stack_;
|
||||
}
|
||||
void s_clear(struct stack *_stack_)
|
||||
@@ -136,11 +117,12 @@ void s_free(struct stack *_stack_)
|
||||
}
|
||||
void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_stack_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_stack_->alloc = alloc;
|
||||
_stack_->callbacks = callbacks;
|
||||
(_stack_)->callbacks = callbacks;
|
||||
_stack_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool s_push(struct stack *_stack_, size_t value)
|
||||
@@ -152,8 +134,9 @@ _Bool s_push(struct stack *_stack_, size_t value)
|
||||
}
|
||||
_stack_->buffer[_stack_->count++] = value;
|
||||
_stack_->flag = CMC_FLAG_OK;
|
||||
if (_stack_->callbacks && _stack_->callbacks->create)
|
||||
_stack_->callbacks->create();
|
||||
if ((_stack_)->callbacks && (_stack_)->callbacks->create)
|
||||
(_stack_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool s_pop(struct stack *_stack_)
|
||||
@@ -165,8 +148,9 @@ _Bool s_pop(struct stack *_stack_)
|
||||
}
|
||||
_stack_->buffer[--_stack_->count] = (size_t){ 0 };
|
||||
_stack_->flag = CMC_FLAG_OK;
|
||||
if (_stack_->callbacks && _stack_->callbacks->delete)
|
||||
_stack_->callbacks->delete ();
|
||||
if ((_stack_)->callbacks && (_stack_)->callbacks->delete)
|
||||
(_stack_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t s_top(struct stack *_stack_)
|
||||
@@ -177,8 +161,9 @@ size_t s_top(struct stack *_stack_)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_stack_->flag = CMC_FLAG_OK;
|
||||
if (_stack_->callbacks && _stack_->callbacks->read)
|
||||
_stack_->callbacks->read();
|
||||
if ((_stack_)->callbacks && (_stack_)->callbacks->read)
|
||||
(_stack_)->callbacks->read();
|
||||
;
|
||||
return _stack_->buffer[_stack_->count - 1];
|
||||
}
|
||||
_Bool s_contains(struct stack *_stack_, size_t value)
|
||||
@@ -193,8 +178,9 @@ _Bool s_contains(struct stack *_stack_, size_t value)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_stack_->callbacks && _stack_->callbacks->read)
|
||||
_stack_->callbacks->read();
|
||||
if ((_stack_)->callbacks && (_stack_)->callbacks->read)
|
||||
(_stack_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool s_empty(struct stack *_stack_)
|
||||
@@ -236,18 +222,20 @@ _Bool s_resize(struct stack *_stack_, size_t capacity)
|
||||
_stack_->capacity = capacity;
|
||||
success:
|
||||
_stack_->flag = CMC_FLAG_OK;
|
||||
if (_stack_->callbacks && _stack_->callbacks->resize)
|
||||
_stack_->callbacks->resize();
|
||||
if ((_stack_)->callbacks && (_stack_)->callbacks->resize)
|
||||
(_stack_)->callbacks->resize();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
struct stack *s_copy_of(struct stack *_stack_)
|
||||
{
|
||||
struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, _stack_->callbacks);
|
||||
struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
{
|
||||
_stack_->flag = CMC_FLAG_ERROR;
|
||||
return ((void *)0);
|
||||
}
|
||||
(_stack_)->callbacks = callbacks;
|
||||
if (_stack_->f_val->cpy)
|
||||
{
|
||||
for (size_t i = 0; i < _stack_->count; i++)
|
||||
@@ -406,5 +394,38 @@ size_t s_iter_index(struct stack_iter *iter)
|
||||
return 0;
|
||||
return iter->target->count - 1 - iter->cursor;
|
||||
}
|
||||
_Bool s_to_string(struct stack *_stack_, FILE *fptr)
|
||||
{
|
||||
struct stack *s_ = _stack_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%"
|
||||
"I64u"
|
||||
", "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"stack", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->flag, s_->f_val, s_->alloc,
|
||||
(s_)->callbacks);
|
||||
}
|
||||
_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end)
|
||||
{
|
||||
fprintf(fptr, "%s", start);
|
||||
for (size_t i = _stack_->count; i > 0; i--)
|
||||
{
|
||||
if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1]))
|
||||
return 0;
|
||||
if (i - 1 != 0)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_STACK */
|
||||
+206
-149
@@ -40,16 +40,6 @@ struct treemap_fval
|
||||
size_t (*hash)(size_t);
|
||||
int (*pri)(size_t, size_t);
|
||||
};
|
||||
struct treemap_iter
|
||||
{
|
||||
struct treemap *target;
|
||||
struct treemap_node *cursor;
|
||||
struct treemap_node *first;
|
||||
struct treemap_node *last;
|
||||
size_t index;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val);
|
||||
struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks);
|
||||
@@ -69,8 +59,16 @@ size_t tm_count(struct treemap *_map_);
|
||||
int tm_flag(struct treemap *_map_);
|
||||
struct treemap *tm_copy_of(struct treemap *_map_);
|
||||
_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_);
|
||||
struct cmc_string tm_to_string(struct treemap *_map_);
|
||||
_Bool tm_print(struct treemap *_map_, FILE *fptr);
|
||||
struct treemap_iter
|
||||
{
|
||||
struct treemap *target;
|
||||
struct treemap_node *cursor;
|
||||
struct treemap_node *first;
|
||||
struct treemap_node *last;
|
||||
size_t index;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
};
|
||||
struct treemap_iter tm_iter_start(struct treemap *target);
|
||||
struct treemap_iter tm_iter_end(struct treemap *target);
|
||||
_Bool tm_iter_at_start(struct treemap_iter *iter);
|
||||
@@ -86,6 +84,9 @@ size_t tm_iter_key(struct treemap_iter *iter);
|
||||
size_t tm_iter_value(struct treemap_iter *iter);
|
||||
size_t *tm_iter_rvalue(struct treemap_iter *iter);
|
||||
size_t tm_iter_index(struct treemap_iter *iter);
|
||||
_Bool tm_to_string(struct treemap *_map_, FILE *fptr);
|
||||
_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
|
||||
const char *key_val_sep);
|
||||
static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value);
|
||||
static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key);
|
||||
static unsigned char tm_impl_h(struct treemap_node *node);
|
||||
@@ -95,24 +96,12 @@ static void tm_impl_rotate_left(struct treemap_node **Z);
|
||||
static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node);
|
||||
struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val)
|
||||
{
|
||||
if (!f_key || !f_val)
|
||||
return ((void *)0);
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
struct treemap *_map_ = alloc->malloc(sizeof(struct treemap));
|
||||
if (!_map_)
|
||||
return ((void *)0);
|
||||
_map_->count = 0;
|
||||
_map_->root = ((void *)0);
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
_map_->f_key = f_key;
|
||||
_map_->f_val = f_val;
|
||||
_map_->alloc = alloc;
|
||||
_map_->callbacks = ((void *)0);
|
||||
return _map_;
|
||||
return tm_new_custom(f_key, f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc,
|
||||
struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!f_key || !f_val)
|
||||
return ((void *)0);
|
||||
if (!alloc)
|
||||
@@ -126,7 +115,7 @@ struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f
|
||||
_map_->f_key = f_key;
|
||||
_map_->f_val = f_val;
|
||||
_map_->alloc = alloc;
|
||||
_map_->callbacks = callbacks;
|
||||
(_map_)->callbacks = callbacks;
|
||||
return _map_;
|
||||
}
|
||||
void tm_clear(struct treemap *_map_)
|
||||
@@ -193,11 +182,12 @@ void tm_free(struct treemap *_map_)
|
||||
}
|
||||
void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_map_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_map_->alloc = alloc;
|
||||
_map_->callbacks = callbacks;
|
||||
(_map_)->callbacks = callbacks;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool tm_insert(struct treemap *_map_, size_t key, size_t value)
|
||||
@@ -255,8 +245,9 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value)
|
||||
}
|
||||
_map_->count++;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->create)
|
||||
_map_->callbacks->create();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->create)
|
||||
(_map_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value)
|
||||
@@ -271,8 +262,9 @@ _Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old
|
||||
*old_value = node->value;
|
||||
node->value = new_value;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->update)
|
||||
_map_->callbacks->update();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->update)
|
||||
(_map_)->callbacks->update();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value)
|
||||
@@ -383,8 +375,9 @@ _Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value)
|
||||
_map_->root = ((void *)0);
|
||||
_map_->count--;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->delete)
|
||||
_map_->callbacks->delete ();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->delete)
|
||||
(_map_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value)
|
||||
@@ -402,8 +395,9 @@ _Bool tm_max(struct treemap *_map_, size_t *key, size_t *value)
|
||||
if (value)
|
||||
*value = scan->value;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value)
|
||||
@@ -421,8 +415,9 @@ _Bool tm_min(struct treemap *_map_, size_t *key, size_t *value)
|
||||
if (value)
|
||||
*value = scan->value;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
size_t tm_get(struct treemap *_map_, size_t key)
|
||||
@@ -439,8 +434,9 @@ size_t tm_get(struct treemap *_map_, size_t key)
|
||||
return (size_t){ 0 };
|
||||
}
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return node->value;
|
||||
}
|
||||
size_t *tm_get_ref(struct treemap *_map_, size_t key)
|
||||
@@ -457,15 +453,17 @@ size_t *tm_get_ref(struct treemap *_map_, size_t key)
|
||||
return ((void *)0);
|
||||
}
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return &(node->value);
|
||||
}
|
||||
_Bool tm_contains(struct treemap *_map_, size_t key)
|
||||
{
|
||||
_Bool result = tm_impl_get_node(_map_, key) != ((void *)0);
|
||||
if (_map_->callbacks && _map_->callbacks->read)
|
||||
_map_->callbacks->read();
|
||||
if ((_map_)->callbacks && (_map_)->callbacks->read)
|
||||
(_map_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool tm_empty(struct treemap *_map_)
|
||||
@@ -499,7 +497,7 @@ struct treemap *tm_copy_of(struct treemap *_map_)
|
||||
value = _map_->f_val->cpy(value);
|
||||
tm_insert(result, key, value);
|
||||
}
|
||||
result->callbacks = _map_->callbacks;
|
||||
(result)->callbacks = _map_->callbacks;
|
||||
_map_->flag = CMC_FLAG_OK;
|
||||
return result;
|
||||
}
|
||||
@@ -520,6 +518,122 @@ _Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value)
|
||||
{
|
||||
struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node));
|
||||
if (!node)
|
||||
return ((void *)0);
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
node->right = ((void *)0);
|
||||
node->left = ((void *)0);
|
||||
node->parent = ((void *)0);
|
||||
node->height = 0;
|
||||
return node;
|
||||
}
|
||||
static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key)
|
||||
{
|
||||
struct treemap_node *scan = _map_->root;
|
||||
while (scan != ((void *)0))
|
||||
{
|
||||
if (_map_->f_key->cmp(scan->key, key) > 0)
|
||||
scan = scan->left;
|
||||
else if (_map_->f_key->cmp(scan->key, key) < 0)
|
||||
scan = scan->right;
|
||||
else
|
||||
return scan;
|
||||
}
|
||||
return ((void *)0);
|
||||
}
|
||||
static unsigned char tm_impl_h(struct treemap_node *node)
|
||||
{
|
||||
if (node == ((void *)0))
|
||||
return 0;
|
||||
return node->height;
|
||||
}
|
||||
static unsigned char tm_impl_hupdate(struct treemap_node *node)
|
||||
{
|
||||
if (node == ((void *)0))
|
||||
return 0;
|
||||
unsigned char h_l = tm_impl_h(node->left);
|
||||
unsigned char h_r = tm_impl_h(node->right);
|
||||
return 1 + (h_l > h_r ? h_l : h_r);
|
||||
}
|
||||
static void tm_impl_rotate_right(struct treemap_node **Z)
|
||||
{
|
||||
struct treemap_node *root = *Z;
|
||||
struct treemap_node *new_root = root->left;
|
||||
if (root->parent != ((void *)0))
|
||||
{
|
||||
if (root->parent->left == root)
|
||||
root->parent->left = new_root;
|
||||
else
|
||||
root->parent->right = new_root;
|
||||
}
|
||||
new_root->parent = root->parent;
|
||||
root->parent = new_root;
|
||||
root->left = new_root->right;
|
||||
if (root->left)
|
||||
root->left->parent = root;
|
||||
new_root->right = root;
|
||||
root->height = tm_impl_hupdate(root);
|
||||
new_root->height = tm_impl_hupdate(new_root);
|
||||
*Z = new_root;
|
||||
}
|
||||
static void tm_impl_rotate_left(struct treemap_node **Z)
|
||||
{
|
||||
struct treemap_node *root = *Z;
|
||||
struct treemap_node *new_root = root->right;
|
||||
if (root->parent != ((void *)0))
|
||||
{
|
||||
if (root->parent->right == root)
|
||||
root->parent->right = new_root;
|
||||
else
|
||||
root->parent->left = new_root;
|
||||
}
|
||||
new_root->parent = root->parent;
|
||||
root->parent = new_root;
|
||||
root->right = new_root->left;
|
||||
if (root->right)
|
||||
root->right->parent = root;
|
||||
new_root->left = root;
|
||||
root->height = tm_impl_hupdate(root);
|
||||
new_root->height = tm_impl_hupdate(new_root);
|
||||
*Z = new_root;
|
||||
}
|
||||
static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node)
|
||||
{
|
||||
struct treemap_node *scan = node, *child = ((void *)0);
|
||||
int balance;
|
||||
_Bool is_root = 0;
|
||||
while (scan != ((void *)0))
|
||||
{
|
||||
if (scan->parent == ((void *)0))
|
||||
is_root = 1;
|
||||
scan->height = tm_impl_hupdate(scan);
|
||||
balance = tm_impl_h(scan->right) - tm_impl_h(scan->left);
|
||||
if (balance >= 2)
|
||||
{
|
||||
child = scan->right;
|
||||
if (tm_impl_h(child->right) < tm_impl_h(child->left))
|
||||
tm_impl_rotate_right(&(scan->right));
|
||||
tm_impl_rotate_left(&scan);
|
||||
}
|
||||
else if (balance <= -2)
|
||||
{
|
||||
child = scan->left;
|
||||
if (tm_impl_h(child->left) < tm_impl_h(child->right))
|
||||
tm_impl_rotate_left(&(scan->left));
|
||||
tm_impl_rotate_right(&scan);
|
||||
}
|
||||
if (is_root)
|
||||
{
|
||||
_map_->root = scan;
|
||||
is_root = 0;
|
||||
}
|
||||
scan = scan->parent;
|
||||
}
|
||||
}
|
||||
struct treemap_iter tm_iter_start(struct treemap *target)
|
||||
{
|
||||
struct treemap_iter iter;
|
||||
@@ -715,121 +829,64 @@ size_t tm_iter_index(struct treemap_iter *iter)
|
||||
{
|
||||
return iter->index;
|
||||
}
|
||||
static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value)
|
||||
_Bool tm_to_string(struct treemap *_map_, FILE *fptr)
|
||||
{
|
||||
struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node));
|
||||
if (!node)
|
||||
return ((void *)0);
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
node->right = ((void *)0);
|
||||
node->left = ((void *)0);
|
||||
node->parent = ((void *)0);
|
||||
node->height = 0;
|
||||
return node;
|
||||
struct treemap *m_ = _map_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s, %s> "
|
||||
"at %p { "
|
||||
"root:%p, "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"f_key:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"treemap", "size_t", "size_t", m_, m_->root, m_->count, m_->flag, m_->f_key, m_->f_val,
|
||||
m_->alloc, (m_)->callbacks);
|
||||
}
|
||||
static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key)
|
||||
_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
|
||||
const char *key_val_sep)
|
||||
{
|
||||
struct treemap_node *scan = _map_->root;
|
||||
while (scan != ((void *)0))
|
||||
fprintf(fptr, "%s", start);
|
||||
struct treemap_node *root = _map_->root;
|
||||
_Bool left_done = 0;
|
||||
size_t i = 0;
|
||||
while (root)
|
||||
{
|
||||
if (_map_->f_key->cmp(scan->key, key) > 0)
|
||||
scan = scan->left;
|
||||
else if (_map_->f_key->cmp(scan->key, key) < 0)
|
||||
scan = scan->right;
|
||||
else
|
||||
return scan;
|
||||
}
|
||||
return ((void *)0);
|
||||
}
|
||||
static unsigned char tm_impl_h(struct treemap_node *node)
|
||||
{
|
||||
if (node == ((void *)0))
|
||||
return 0;
|
||||
return node->height;
|
||||
}
|
||||
static unsigned char tm_impl_hupdate(struct treemap_node *node)
|
||||
{
|
||||
if (node == ((void *)0))
|
||||
return 0;
|
||||
unsigned char h_l = tm_impl_h(node->left);
|
||||
unsigned char h_r = tm_impl_h(node->right);
|
||||
return 1 + (h_l > h_r ? h_l : h_r);
|
||||
}
|
||||
static void tm_impl_rotate_right(struct treemap_node **Z)
|
||||
{
|
||||
struct treemap_node *root = *Z;
|
||||
struct treemap_node *new_root = root->left;
|
||||
if (root->parent != ((void *)0))
|
||||
{
|
||||
if (root->parent->left == root)
|
||||
root->parent->left = new_root;
|
||||
else
|
||||
root->parent->right = new_root;
|
||||
}
|
||||
new_root->parent = root->parent;
|
||||
root->parent = new_root;
|
||||
root->left = new_root->right;
|
||||
if (root->left)
|
||||
root->left->parent = root;
|
||||
new_root->right = root;
|
||||
root->height = tm_impl_hupdate(root);
|
||||
new_root->height = tm_impl_hupdate(new_root);
|
||||
*Z = new_root;
|
||||
}
|
||||
static void tm_impl_rotate_left(struct treemap_node **Z)
|
||||
{
|
||||
struct treemap_node *root = *Z;
|
||||
struct treemap_node *new_root = root->right;
|
||||
if (root->parent != ((void *)0))
|
||||
{
|
||||
if (root->parent->right == root)
|
||||
root->parent->right = new_root;
|
||||
else
|
||||
root->parent->left = new_root;
|
||||
}
|
||||
new_root->parent = root->parent;
|
||||
root->parent = new_root;
|
||||
root->right = new_root->left;
|
||||
if (root->right)
|
||||
root->right->parent = root;
|
||||
new_root->left = root;
|
||||
root->height = tm_impl_hupdate(root);
|
||||
new_root->height = tm_impl_hupdate(new_root);
|
||||
*Z = new_root;
|
||||
}
|
||||
static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node)
|
||||
{
|
||||
struct treemap_node *scan = node, *child = ((void *)0);
|
||||
int balance;
|
||||
_Bool is_root = 0;
|
||||
while (scan != ((void *)0))
|
||||
{
|
||||
if (scan->parent == ((void *)0))
|
||||
is_root = 1;
|
||||
scan->height = tm_impl_hupdate(scan);
|
||||
balance = tm_impl_h(scan->right) - tm_impl_h(scan->left);
|
||||
if (balance >= 2)
|
||||
if (!left_done)
|
||||
{
|
||||
child = scan->right;
|
||||
if (tm_impl_h(child->right) < tm_impl_h(child->left))
|
||||
tm_impl_rotate_right(&(scan->right));
|
||||
tm_impl_rotate_left(&scan);
|
||||
while (root->left)
|
||||
root = root->left;
|
||||
}
|
||||
else if (balance <= -2)
|
||||
if (!_map_->f_key->str(fptr, root->key))
|
||||
return 0;
|
||||
fprintf(fptr, "%s", key_val_sep);
|
||||
if (!_map_->f_val->str(fptr, root->value))
|
||||
return 0;
|
||||
if (++i < _map_->count)
|
||||
fprintf(fptr, "%s", separator);
|
||||
left_done = 1;
|
||||
if (root->right)
|
||||
{
|
||||
child = scan->left;
|
||||
if (tm_impl_h(child->left) < tm_impl_h(child->right))
|
||||
tm_impl_rotate_left(&(scan->left));
|
||||
tm_impl_rotate_right(&scan);
|
||||
left_done = 0;
|
||||
root = root->right;
|
||||
}
|
||||
if (is_root)
|
||||
else if (root->parent)
|
||||
{
|
||||
_map_->root = scan;
|
||||
is_root = 0;
|
||||
while (root->parent && root == root->parent->right)
|
||||
root = root->parent;
|
||||
if (!root->parent)
|
||||
break;
|
||||
root = root->parent;
|
||||
}
|
||||
scan = scan->parent;
|
||||
else
|
||||
break;
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_TREEMAP */
|
||||
+85
-38
@@ -55,8 +55,6 @@ size_t ts_count(struct treeset *_set_);
|
||||
int ts_flag(struct treeset *_set_);
|
||||
struct treeset *ts_copy_of(struct treeset *_set_);
|
||||
_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_);
|
||||
struct cmc_string ts_to_string(struct treeset *_set_);
|
||||
_Bool ts_print(struct treeset *_set_, FILE *fptr);
|
||||
struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_);
|
||||
struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_);
|
||||
struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_);
|
||||
@@ -79,12 +77,8 @@ _Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps);
|
||||
_Bool ts_iter_go_to(struct treeset_iter *iter, size_t index);
|
||||
size_t ts_iter_value(struct treeset_iter *iter);
|
||||
size_t ts_iter_index(struct treeset_iter *iter);
|
||||
static inline size_t ts_impl_default_value(void)
|
||||
{
|
||||
size_t _empty_value_;
|
||||
memset(&_empty_value_, 0, sizeof(size_t));
|
||||
return _empty_value_;
|
||||
}
|
||||
_Bool ts_to_string(struct treeset *_set_, FILE *fptr);
|
||||
_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end);
|
||||
static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value);
|
||||
static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value);
|
||||
static unsigned char ts_impl_h(struct treeset_node *node);
|
||||
@@ -94,22 +88,11 @@ static void ts_impl_rotate_left(struct treeset_node **Z);
|
||||
static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node);
|
||||
struct treeset *ts_new(struct treeset_fval *f_val)
|
||||
{
|
||||
if (!f_val)
|
||||
return ((void *)0);
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
|
||||
struct treeset *_set_ = alloc->malloc(sizeof(struct treeset));
|
||||
if (!_set_)
|
||||
return ((void *)0);
|
||||
_set_->count = 0;
|
||||
_set_->root = ((void *)0);
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
_set_->f_val = f_val;
|
||||
_set_->alloc = alloc;
|
||||
_set_->callbacks = ((void *)0);
|
||||
return _set_;
|
||||
return ts_new_custom(f_val, ((void *)0), ((void *)0));
|
||||
}
|
||||
struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!f_val)
|
||||
return ((void *)0);
|
||||
if (!alloc)
|
||||
@@ -122,7 +105,7 @@ struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
_set_->f_val = f_val;
|
||||
_set_->alloc = alloc;
|
||||
_set_->callbacks = callbacks;
|
||||
(_set_)->callbacks = callbacks;
|
||||
return _set_;
|
||||
}
|
||||
void ts_clear(struct treeset *_set_)
|
||||
@@ -185,11 +168,12 @@ void ts_free(struct treeset *_set_)
|
||||
}
|
||||
void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
|
||||
{
|
||||
;
|
||||
if (!alloc)
|
||||
_set_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_set_->alloc = alloc;
|
||||
_set_->callbacks = callbacks;
|
||||
(_set_)->callbacks = callbacks;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
_Bool ts_insert(struct treeset *_set_, size_t value)
|
||||
@@ -247,8 +231,9 @@ _Bool ts_insert(struct treeset *_set_, size_t value)
|
||||
}
|
||||
_set_->count++;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->create)
|
||||
_set_->callbacks->create();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->create)
|
||||
(_set_)->callbacks->create();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ts_remove(struct treeset *_set_, size_t value)
|
||||
@@ -355,8 +340,9 @@ _Bool ts_remove(struct treeset *_set_, size_t value)
|
||||
_set_->root = ((void *)0);
|
||||
_set_->count--;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->delete)
|
||||
_set_->callbacks->delete ();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->delete)
|
||||
(_set_)->callbacks->delete ();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ts_max(struct treeset *_set_, size_t *value)
|
||||
@@ -372,8 +358,9 @@ _Bool ts_max(struct treeset *_set_, size_t *value)
|
||||
if (value)
|
||||
*value = scan->value;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->read)
|
||||
_set_->callbacks->read();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ts_min(struct treeset *_set_, size_t *value)
|
||||
@@ -389,15 +376,17 @@ _Bool ts_min(struct treeset *_set_, size_t *value)
|
||||
if (value)
|
||||
*value = scan->value;
|
||||
_set_->flag = CMC_FLAG_OK;
|
||||
if (_set_->callbacks && _set_->callbacks->read)
|
||||
_set_->callbacks->read();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
_Bool ts_contains(struct treeset *_set_, size_t value)
|
||||
{
|
||||
_Bool result = ts_impl_get_node(_set_, value) != ((void *)0);
|
||||
if (_set_->callbacks && _set_->callbacks->read)
|
||||
_set_->callbacks->read();
|
||||
if ((_set_)->callbacks && (_set_)->callbacks->read)
|
||||
(_set_)->callbacks->read();
|
||||
;
|
||||
return result;
|
||||
}
|
||||
_Bool ts_empty(struct treeset *_set_)
|
||||
@@ -414,12 +403,13 @@ int ts_flag(struct treeset *_set_)
|
||||
}
|
||||
struct treeset *ts_copy_of(struct treeset *_set_)
|
||||
{
|
||||
struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, _set_->callbacks);
|
||||
struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, ((void *)0));
|
||||
if (!result)
|
||||
{
|
||||
_set_->flag = CMC_FLAG_ERROR;
|
||||
return ((void *)0);
|
||||
}
|
||||
(result)->callbacks = _set_->callbacks;
|
||||
if (!ts_empty(_set_))
|
||||
{
|
||||
struct treeset_iter iter = ts_iter_start(_set_);
|
||||
@@ -450,7 +440,7 @@ _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_)
|
||||
}
|
||||
struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_)
|
||||
{
|
||||
struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks);
|
||||
struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct treeset_iter iter1 = ts_iter_start(_set1_);
|
||||
@@ -463,11 +453,12 @@ struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_)
|
||||
{
|
||||
ts_insert(_set_r_, ts_iter_value(&iter2));
|
||||
}
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_)
|
||||
{
|
||||
struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks);
|
||||
struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_;
|
||||
@@ -479,11 +470,12 @@ struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_)
|
||||
if (ts_impl_get_node(_set_B_, value) != ((void *)0))
|
||||
ts_insert(_set_r_, value);
|
||||
}
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_)
|
||||
{
|
||||
struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks);
|
||||
struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct treeset_iter iter = ts_iter_start(_set1_);
|
||||
@@ -493,11 +485,12 @@ struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_)
|
||||
if (ts_impl_get_node(_set2_, value) == ((void *)0))
|
||||
ts_insert(_set_r_, value);
|
||||
}
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_)
|
||||
{
|
||||
struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks);
|
||||
struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0));
|
||||
if (!_set_r_)
|
||||
return ((void *)0);
|
||||
struct treeset_iter iter1 = ts_iter_start(_set1_);
|
||||
@@ -514,6 +507,7 @@ struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *
|
||||
if (ts_impl_get_node(_set1_, value) == ((void *)0))
|
||||
ts_insert(_set_r_, value);
|
||||
}
|
||||
(_set_r_)->callbacks = _set1_->callbacks;
|
||||
return _set_r_;
|
||||
}
|
||||
_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_)
|
||||
@@ -870,5 +864,58 @@ static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node)
|
||||
scan = scan->parent;
|
||||
}
|
||||
}
|
||||
_Bool ts_to_string(struct treeset *_set_, FILE *fptr)
|
||||
{
|
||||
struct treeset *s_ = _set_;
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"root:%p, "
|
||||
"count:%"
|
||||
"I64u"
|
||||
", "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
"treeset", "size_t", s_, s_->root, s_->count, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks);
|
||||
}
|
||||
_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end)
|
||||
{
|
||||
fprintf(fptr, "%s", start);
|
||||
struct treeset_node *root = _set_->root;
|
||||
_Bool left_done = 0;
|
||||
size_t i = 0;
|
||||
while (root)
|
||||
{
|
||||
if (!left_done)
|
||||
{
|
||||
while (root->left)
|
||||
root = root->left;
|
||||
}
|
||||
if (!_set_->f_val->str(fptr, root->value))
|
||||
return 0;
|
||||
if (++i < _set_->count)
|
||||
fprintf(fptr, "%s", separator);
|
||||
left_done = 1;
|
||||
if (root->right)
|
||||
{
|
||||
left_done = 0;
|
||||
root = root->right;
|
||||
}
|
||||
else if (root->parent)
|
||||
{
|
||||
while (root->parent && root == root->parent->right)
|
||||
root = root->parent;
|
||||
if (!root->parent)
|
||||
break;
|
||||
root = root->parent;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
fprintf(fptr, "%s", end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CMC_TEST_SRC_TREESET */
|
||||
@@ -8,7 +8,6 @@ struct cmc_alloc_node *bs_alloc_node =
|
||||
&(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free };
|
||||
|
||||
CMC_CREATE_UNIT(BitSet, true, {
|
||||
const size_t word_bytes = sizeof(cmc_bitset_word);
|
||||
const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT;
|
||||
|
||||
printf("%s", cmc_test_color(5));
|
||||
@@ -421,8 +420,8 @@ CMC_CREATE_UNIT(BitSet, true, {
|
||||
});
|
||||
|
||||
CMC_CREATE_UNIT(BitSetIter, true, {
|
||||
const size_t word_bytes = sizeof(cmc_bitset_word);
|
||||
const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT;
|
||||
// const size_t word_bytes = sizeof(cmc_bitset_word);
|
||||
// const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT;
|
||||
|
||||
printf("%s", cmc_test_color(5));
|
||||
printf(" BitSet<" CMC_TO_STRING(CMC_BITSET_WORD_TYPE) ">\n");
|
||||
|
||||
@@ -793,10 +793,13 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
|
||||
});
|
||||
});
|
||||
|
||||
CMC_CREATE_UNIT(HashBidiMapIter, true,
|
||||
{
|
||||
|
||||
});
|
||||
CMC_CREATE_UNIT(HashBidiMapIter, true, {
|
||||
CMC_CREATE_TEST(PFX##_iter_start, {
|
||||
// WIP
|
||||
cmc_assert(true);
|
||||
cmc_assert(true);
|
||||
});
|
||||
});
|
||||
|
||||
#ifdef CMC_TEST_MAIN
|
||||
int main(void)
|
||||
|
||||
@@ -123,7 +123,6 @@ CMC_CREATE_UNIT(Heap, true, {
|
||||
for (size_t i = 1; i <= 100; i++)
|
||||
cmc_assert(h_insert(h, i));
|
||||
|
||||
size_t r;
|
||||
size_t i = 0;
|
||||
size_t arr[100];
|
||||
while (!h_empty(h))
|
||||
|
||||
@@ -16,16 +16,19 @@ size_t numhash(size_t a)
|
||||
|
||||
size_t hashcapminus1(size_t a)
|
||||
{
|
||||
(void)a;
|
||||
return cmc_hashtable_primes[0] - 1;
|
||||
}
|
||||
|
||||
size_t hashcapminus4(size_t a)
|
||||
{
|
||||
(void)a;
|
||||
return cmc_hashtable_primes[0] - 1;
|
||||
}
|
||||
|
||||
size_t hash0(size_t a)
|
||||
{
|
||||
(void)a;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -65,6 +68,7 @@ bool k_c_str(FILE *fptr, size_t a)
|
||||
|
||||
void k_c_free(size_t a)
|
||||
{
|
||||
(void)a;
|
||||
k_total_free++;
|
||||
}
|
||||
|
||||
@@ -103,6 +107,7 @@ bool v_c_str(FILE *fptr, size_t a)
|
||||
|
||||
void v_c_free(size_t a)
|
||||
{
|
||||
(void)a;
|
||||
v_total_free++;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l, list, , , int))
|
||||
C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q, queue, , , int))
|
||||
C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl, sortedlist, , , int))
|
||||
C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s, stack, , , int))
|
||||
C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm, treemap, , int, int))
|
||||
C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts, treeset, , , int))
|
||||
|
||||
struct
|
||||
{
|
||||
@@ -49,6 +51,9 @@ int main(void)
|
||||
struct queue *q = q_new(100, (struct queue_fval *)&int_ftab);
|
||||
struct sortedlist *sl = sl_new(100, (struct sortedlist_fval *)&int_ftab);
|
||||
struct stack *s = s_new(100, (struct stack_fval *)&int_ftab);
|
||||
struct treemap *tm = tm_new((struct treemap_fkey *)&int_ftab,
|
||||
(struct treemap_fval *)&int_ftab);
|
||||
struct treeset *ts = ts_new((struct treeset_fval *)&int_ftab);
|
||||
|
||||
d_to_string(d, stdout);
|
||||
d_print(d, stdout, "\n[ ", ", ", " ]\n");
|
||||
@@ -76,6 +81,10 @@ int main(void)
|
||||
sl_print(sl, stdout, "\n[ ", ", ", " ]\n");
|
||||
s_to_string(s, stdout);
|
||||
s_print(s, stdout, "\n[ ", ", ", " ]\n");
|
||||
tm_to_string(tm, stdout);
|
||||
tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
|
||||
ts_to_string(ts, stdout);
|
||||
ts_print(ts, stdout, "\n[ ", ", ", " ]\n");
|
||||
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
@@ -92,6 +101,8 @@ int main(void)
|
||||
q_enqueue(q, 0);
|
||||
sl_insert(sl, 0);
|
||||
s_push(s, 0);
|
||||
tm_insert(tm, 0, 0);
|
||||
ts_insert(ts, 0);
|
||||
|
||||
d_to_string(d, stdout);
|
||||
d_print(d, stdout, "\n[ ", ", ", " ]\n");
|
||||
@@ -119,6 +130,10 @@ int main(void)
|
||||
sl_print(sl, stdout, "\n[ ", ", ", " ]\n");
|
||||
s_to_string(s, stdout);
|
||||
s_print(s, stdout, "\n[ ", ", ", " ]\n");
|
||||
tm_to_string(tm, stdout);
|
||||
tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
|
||||
ts_to_string(ts, stdout);
|
||||
ts_print(ts, stdout, "\n[ ", ", ", " ]\n");
|
||||
|
||||
for (int i = 1; i < 20; i++)
|
||||
{
|
||||
@@ -135,6 +150,8 @@ int main(void)
|
||||
q_enqueue(q, i);
|
||||
sl_insert(sl, i);
|
||||
s_push(s, i);
|
||||
tm_insert(tm, i, i);
|
||||
ts_insert(ts, i);
|
||||
}
|
||||
|
||||
fprintf(stdout, "\n");
|
||||
@@ -165,6 +182,10 @@ int main(void)
|
||||
sl_print(sl, stdout, "\n[ ", ", ", " ]\n");
|
||||
s_to_string(s, stdout);
|
||||
s_print(s, stdout, "\n[ ", ", ", " ]\n");
|
||||
tm_to_string(tm, stdout);
|
||||
tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
|
||||
ts_to_string(ts, stdout);
|
||||
ts_print(ts, stdout, "\n[ ", ", ", " ]\n");
|
||||
|
||||
d_free(d);
|
||||
hbm_free(hbm);
|
||||
@@ -178,6 +199,9 @@ int main(void)
|
||||
l_free(l);
|
||||
q_free(q);
|
||||
sl_free(sl);
|
||||
s_free(s);
|
||||
tm_free(tm);
|
||||
ts_free(ts);
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
Reference in new issue
Block a user