Added ./cor/ftable.h and fast forward changes
This commit is contained in:
1 parent
85bef64551
commit
77a7178857
8 files changed
+961
-830
No files matched your search
+475
-759
File diff suppressed because it is too large.
Load diff
@@ -220,8 +220,6 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> "
|
||||
bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \
|
||||
bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \
|
||||
struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Initialization */ \
|
||||
@@ -860,36 +858,6 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> "
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \
|
||||
{ \
|
||||
struct cmc_string str; \
|
||||
struct SNAME *m_ = _map_; \
|
||||
\
|
||||
int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashmap, \
|
||||
#SNAME, #K, #V, m_, m_->buffer, m_->capacity, \
|
||||
m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \
|
||||
m_->alloc, m_->callbacks); \
|
||||
\
|
||||
return n >= 0 ? str : (struct cmc_string){ 0 }; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _map_->capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
if (!_map_->f_key->str(fptr, entry->key) || \
|
||||
!_map_->f_val->str(fptr, entry->value)) \
|
||||
return false; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
|
||||
+1
-22
@@ -32,6 +32,7 @@
|
||||
#include "alloc.h"
|
||||
#include "callbacks.h"
|
||||
#include "flags.h"
|
||||
#include "ftable.h"
|
||||
|
||||
#define CMC__(A, B) A##B
|
||||
#define CMC_(A, B) CMC__(A, B)
|
||||
@@ -91,26 +92,4 @@
|
||||
#define CMC_PARAM_K CMC_TUP_3
|
||||
#define CMC_PARAM_V CMC_TUP_4
|
||||
|
||||
/**
|
||||
* A __VA_ARGS__ argument counter. This argument counter is slightly shifted:
|
||||
*
|
||||
* CMC_NARG(HELLO) -> 0
|
||||
* CMC_NARG(HELLO,) -> 1
|
||||
* CMC_NARG(HELLO, WORLD,) -> 2
|
||||
*/
|
||||
#define CMC_NARG(...) CMC_NARG_(__VA_ARGS__, CMC_SEQ_N())
|
||||
#define CMC_NARG_(...) CMC_ARG_N(__VA_ARGS__)
|
||||
#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \
|
||||
_14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \
|
||||
_26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \
|
||||
_38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \
|
||||
_50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \
|
||||
_62, _63, N, ...) \
|
||||
N
|
||||
#define CMC_SEQ_N() \
|
||||
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \
|
||||
45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \
|
||||
28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \
|
||||
11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
|
||||
|
||||
#endif /* CMC_COR_CORE_H */
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* ftable.h
|
||||
*
|
||||
* Creation Date: 27/05/2020
|
||||
*
|
||||
* Authors:
|
||||
* Leonardo Vencovsky (https://github.com/LeoVen)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Type definitions for Functions Tables.
|
||||
*/
|
||||
|
||||
#ifndef CMC_COR_FTABLE_H
|
||||
#define CMC_COR_FTABLE_H
|
||||
|
||||
/**
|
||||
* Where T can either be K or V
|
||||
*/
|
||||
#define CMC_DEF_FTAB_CMP(T) int (*cmp)(T, T)
|
||||
#define CMC_DEF_FTAB_CPY(T) T (*cpy)(T)
|
||||
#define CMC_DEF_FTAB_STR(T) bool (*str)(FILE *, T)
|
||||
#define CMC_DEF_FTAB_FREE(T) void (*free)(T)
|
||||
#define CMC_DEF_FTAB_HASH(T) size_t (*hash)(T)
|
||||
#define CMC_DEF_FTAB_PRI(T) int (*pri)(T, T)
|
||||
|
||||
#endif /* CMC_COR_FTABLE_H */
|
||||
+336
-9
@@ -8,24 +8,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extensions to CMC<Deque>
|
||||
*
|
||||
* - INIT
|
||||
*/
|
||||
|
||||
#ifndef CMC_EXT_CMC_DEQUE_H
|
||||
#define CMC_EXT_CMC_DEQUE_H
|
||||
|
||||
#include "../../cor/core.h"
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_PARTS INIT,
|
||||
/**
|
||||
* All the EXT parts of CMC Deque.
|
||||
*/
|
||||
#define CMC_EXT_CMC_DEQUE_PARTS INIT, ITER, STR
|
||||
|
||||
/**
|
||||
* INIT
|
||||
*
|
||||
* The part 'INIT' gives a new way of initializing a collection. The collection
|
||||
* struct is not heap allocated, only its internal structure (nodes, buffers)
|
||||
* struct is not heap allocated, only its internal structure (nodes, buffers).
|
||||
*/
|
||||
#define CMC_EXT_CMC_DEQUE_INIT(BODY) \
|
||||
CMC_EXT_CMC_DEQUE_INIT_HEADER(BODY) \
|
||||
@@ -79,7 +76,7 @@
|
||||
_deque_.count = 0; \
|
||||
_deque_.front = 0; \
|
||||
_deque_.back = 0; \
|
||||
_deque_.flag = cmc_flags.OK; \
|
||||
_deque_.flag = CMC_FLAG_OK; \
|
||||
_deque_.f_val = f_val; \
|
||||
_deque_.alloc = alloc; \
|
||||
_deque_.callbacks = callbacks; \
|
||||
@@ -87,4 +84,334 @@
|
||||
return _deque_; \
|
||||
}
|
||||
|
||||
/**
|
||||
* ITER
|
||||
*/
|
||||
#define CMC_EXT_CMC_DEQUE_ITER(BODY) \
|
||||
CMC_EXT_CMC_DEQUE_ITER_HEADER(BODY) \
|
||||
CMC_EXT_CMC_DEQUE_ITER_SOURCE(BODY)
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_ITER_HEADER(BODY) \
|
||||
CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \
|
||||
CMC_PARAM_V(BODY))
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_ITER_SOURCE(BODY) \
|
||||
CMC_EXT_CMC_DEQUE_ITER_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \
|
||||
CMC_PARAM_V(BODY))
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \
|
||||
/* Deque Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* Target deque */ \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* Keeps track of relative index to the iteration of elements */ \
|
||||
size_t index; \
|
||||
\
|
||||
/* If the iterator has reached the start of the iteration */ \
|
||||
bool start; \
|
||||
\
|
||||
/* If the iterator has reached the end of the iteration */ \
|
||||
bool end; \
|
||||
}; \
|
||||
\
|
||||
/* Iterator Initialization */ \
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \
|
||||
/* Iterator State */ \
|
||||
bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
/* Iterator Movement */ \
|
||||
bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps); \
|
||||
bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps); \
|
||||
bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_ITER_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
iter.cursor = target->front; \
|
||||
iter.index = 0; \
|
||||
iter.start = true; \
|
||||
iter.end = CMC_(PFX, _empty)(target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
{ \
|
||||
if (iter.target->back == 0) \
|
||||
iter.cursor = iter.target->capacity - 1; \
|
||||
else \
|
||||
iter.cursor = iter.target->back - 1; \
|
||||
\
|
||||
iter.index = iter.target->count - 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
iter.cursor = 0; \
|
||||
iter.index = 0; \
|
||||
} \
|
||||
\
|
||||
iter.start = CMC_(PFX, _empty)(target); \
|
||||
iter.end = true; \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return CMC_(PFX, _empty)(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return CMC_(PFX, _empty)(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _empty)(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = iter->target->front; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = false; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _empty)(iter->target)) \
|
||||
{ \
|
||||
if (iter->target->back == 0) \
|
||||
iter->cursor = iter->target->capacity - 1; \
|
||||
else \
|
||||
iter->cursor = iter->target->back - 1; \
|
||||
\
|
||||
iter->index = iter->target->count - 1; \
|
||||
\
|
||||
iter->start = false; \
|
||||
iter->end = true; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
|
||||
iter->index++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \
|
||||
: iter->cursor - 1; \
|
||||
iter->index--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index + steps >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->index += steps; \
|
||||
iter->cursor = (iter->cursor + steps) % iter->target->capacity; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index < steps) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->index -= steps; \
|
||||
\
|
||||
/* Prevent underflow */ \
|
||||
if (iter->cursor < steps) \
|
||||
iter->cursor += iter->target->capacity; \
|
||||
\
|
||||
iter->cursor -= steps; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the */ \
|
||||
/* given index */ \
|
||||
bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t index) \
|
||||
{ \
|
||||
if (index >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index > index) \
|
||||
return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
|
||||
else if (iter->index < index) \
|
||||
return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return (V){ 0 }; \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
}
|
||||
|
||||
/**
|
||||
* STR
|
||||
*/
|
||||
#define CMC_EXT_CMC_DEQUE_STR(BODY) \
|
||||
CMC_EXT_CMC_DEQUE_STR_HEADER(BODY) \
|
||||
CMC_EXT_CMC_DEQUE_STR_SOURCE(BODY)
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_STR_HEADER(BODY) \
|
||||
CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \
|
||||
CMC_PARAM_V(BODY))
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_STR_SOURCE(BODY) \
|
||||
CMC_EXT_CMC_DEQUE_STR_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \
|
||||
CMC_PARAM_V(BODY))
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_STR_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
const char *end);
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_STR_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *d_ = _deque_; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, cmc_cmc_string_fmt_deque, \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), d_, \
|
||||
d_->buffer, d_->capacity, d_->count, d_->front, \
|
||||
d_->back, d_->flag, d_->f_val, d_->alloc, \
|
||||
d_->callbacks); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _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 false; \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
\
|
||||
if (j + 1 < _deque_->count) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* CMC_EXT_CMC_DEQUE_H */
|
||||
@@ -7,3 +7,15 @@
|
||||
* Leonardo Vencovsky (https://github.com/LeoVen)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CMC_EXT_CMC_HASHBIDIMAP_H
|
||||
#define CMC_EXT_CMC_HASHBIDIMAP_H
|
||||
|
||||
#include "../../cor/core.h"
|
||||
|
||||
/**
|
||||
* All the EXT parts of CMC HashBidiMap.
|
||||
*/
|
||||
#define CMC_EXT_CMC_HASHBIDIMAP_PARTS
|
||||
|
||||
#endif /* CMC_EXT_CMC_HASHBIDIMAP_H */
|
||||
+80
-8
@@ -8,18 +8,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extensions to CMC<HashMap>
|
||||
*
|
||||
* - INIT
|
||||
*/
|
||||
|
||||
#ifndef CMC_EXT_CMC_HASHMAP_H
|
||||
#define CMC_EXT_CMC_HASHMAP_H
|
||||
|
||||
#include "../../cor/core.h"
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_PARTS INIT, ITER
|
||||
/**
|
||||
* All the EXT parts of CMC HashMap.
|
||||
*/
|
||||
#define CMC_EXT_CMC_HASHMAP_PARTS INIT, STR
|
||||
|
||||
/**
|
||||
* INIT
|
||||
@@ -91,7 +88,7 @@
|
||||
_map_.count = 0; \
|
||||
_map_.capacity = real_capacity; \
|
||||
_map_.load = load; \
|
||||
_map_.flag = cmc_flags.OK; \
|
||||
_map_.flag = CMC_FLAG_OK; \
|
||||
_map_.f_key = f_key; \
|
||||
_map_.f_val = f_val; \
|
||||
_map_.alloc = alloc; \
|
||||
@@ -100,4 +97,79 @@
|
||||
return _map_; \
|
||||
}
|
||||
|
||||
/**
|
||||
* STR
|
||||
*
|
||||
* The part 'STR' gives a new way of initializing a collection. The collection
|
||||
* struct is not heap allocated, only its internal structure (nodes, buffers).
|
||||
*/
|
||||
#define CMC_EXT_CMC_HASHMAP_STR(BODY) \
|
||||
CMC_EXT_CMC_HASHMAP_STR_HEADER(BODY) \
|
||||
CMC_EXT_CMC_HASHMAP_STR_SOURCE(BODY)
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_HEADER(BODY) \
|
||||
CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(BODY), \
|
||||
CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_SOURCE(BODY) \
|
||||
CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(BODY), \
|
||||
CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_, \
|
||||
FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
const char *end)
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *m_ = _map_; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, cmc_string_len, cmc_cmc_string_fmt_hashmap, \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(K), \
|
||||
CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \
|
||||
m_->count, m_->load, m_->flag, m_->f_key, \
|
||||
m_->f_val, m_->alloc, m_->callbacks); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
const char *end) \
|
||||
{ \
|
||||
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 CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
if (!_map_->f_key->str(fptr, entry->key) || \
|
||||
!_map_->f_val->str(fptr, entry->value)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (i + 1 < last) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* CMC_EXT_CMC_HASHMAP_H */
|
||||
@@ -11,6 +11,7 @@
|
||||
#ifndef CMC_MACRO_COLLECTIONS_H
|
||||
#define CMC_MACRO_COLLECTIONS_H
|
||||
|
||||
// clang-format off
|
||||
#include "cmc/bitset.h" /* Added in 30/04/2020 */
|
||||
#include "cmc/deque.h" /* Added in 20/03/2019 */
|
||||
#include "cmc/hashbidimap.h" /* Added in 26/09/2019 */
|
||||
@@ -27,13 +28,18 @@
|
||||
#include "cmc/stack.h" /* Added in 14/02/2019 */
|
||||
#include "cmc/treemap.h" /* Added in 28/03/2019 */
|
||||
#include "cmc/treeset.h" /* Added in 27/03/2019 */
|
||||
|
||||
#include "cor/alloc.h" /* Added in 24/05/2020 */
|
||||
#include "cor/bitset.h" /* Added in 20/05/2020 */
|
||||
#include "cor/callbacks.h" /* Added in 24/05/2020 */
|
||||
#include "cor/core.h" /* Added in 17/03/2020 */
|
||||
#include "cor/flags.h" /* Added in 14/05/2020 */
|
||||
#include "cor/ftable.h" /* Added in 27/05/2020 */
|
||||
#include "cor/hashtable.h" /* Added in 17/03/2020 */
|
||||
|
||||
#include "ext/cmc/deque.h" /* Added in 25/05/2020 */
|
||||
#include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */
|
||||
|
||||
#include "utl/assert.h" /* Added in 27/06/2019 */
|
||||
#include "utl/foreach.h" /* Added in 25/02/2019 */
|
||||
#include "utl/futils.h" /* Added in 15/04/2020 */
|
||||
@@ -42,6 +48,7 @@
|
||||
#include "utl/test.h" /* Added in 26/06/2019 */
|
||||
#include "utl/thread.h" /* Added in 14/05/2020 */
|
||||
#include "utl/timer.h" /* Added in 12/04/2019 */
|
||||
// clang-format on
|
||||
|
||||
/**
|
||||
* Generate a specific part of a collection
|
||||
@@ -72,6 +79,28 @@
|
||||
#define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) \
|
||||
CMC_EXT_##LIB##_##COLLECTION##_PARTS
|
||||
|
||||
/**
|
||||
* A __VA_ARGS__ argument counter. This argument counter is slightly shifted:
|
||||
*
|
||||
* CMC_NARG(HELLO) -> 0
|
||||
* CMC_NARG(HELLO,) -> 1
|
||||
* CMC_NARG(HELLO, WORLD,) -> 2
|
||||
*/
|
||||
#define CMC_NARG(...) CMC_NARG_(__VA_ARGS__, CMC_SEQ_N())
|
||||
#define CMC_NARG_(...) CMC_ARG_N(__VA_ARGS__)
|
||||
#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \
|
||||
_14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \
|
||||
_26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \
|
||||
_38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \
|
||||
_50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \
|
||||
_62, _63, N, ...) \
|
||||
N
|
||||
#define CMC_SEQ_N() \
|
||||
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \
|
||||
45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \
|
||||
28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \
|
||||
11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
|
||||
|
||||
#define CMC_MAP(LIB, COLLECTION, FILE, PARAMS, ...) \
|
||||
CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \
|
||||
(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
|
||||
|
||||
Reference in new issue
Block a user