Update dict_set to be like a B+TREE (API breakage). _ref returns pointer to the data
This commit is contained in:
1 parent
155d01b8c3
commit
998ae05a5b
1 file changed
+68
-38
@@ -193,6 +193,12 @@
|
||||
\
|
||||
typedef struct M_C(name, _s) *M_C(name, _ptr); \
|
||||
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
|
||||
\
|
||||
M_IF(isSet)( \
|
||||
typedef key_type M_C(name, _type_t); \
|
||||
, \
|
||||
typedef struct M_C(name, _pair_s) M_C(name, _type_t); \
|
||||
) \
|
||||
typedef key_type M_C(name, _key_type_t); \
|
||||
typedef value_type M_C(name, _value_type_t); \
|
||||
\
|
||||
@@ -553,20 +559,28 @@
|
||||
it2->list_it); \
|
||||
} \
|
||||
\
|
||||
static inline struct M_C(name, _pair_s) * \
|
||||
static inline M_C(name, _type_t) * \
|
||||
M_C(name, _ref)(const dict_it_t it) \
|
||||
{ \
|
||||
assert(it != NULL); \
|
||||
/* NOTE: partially unsafe if the user modify the 'key' \
|
||||
in a non equivalent way */ \
|
||||
return *M_C(name, _list_pair_ref)(it->list_it); \
|
||||
M_IF(isSet)( \
|
||||
return &(*M_C(name, _list_pair_ref)(it->list_it))->key; \
|
||||
, \
|
||||
return *M_C(name, _list_pair_ref)(it->list_it); \
|
||||
) \
|
||||
} \
|
||||
\
|
||||
static inline const struct M_C(name, _pair_s) * \
|
||||
static inline const M_C(name, _type_t) * \
|
||||
M_C(name, _cref)(const dict_it_t it) \
|
||||
{ \
|
||||
assert(it != NULL); \
|
||||
return *M_C(name, _list_pair_cref)(it->list_it); \
|
||||
M_IF(isSet)( \
|
||||
return &(*M_C(name, _list_pair_cref)(it->list_it))->key; \
|
||||
, \
|
||||
return *M_C(name, _list_pair_cref)(it->list_it); \
|
||||
) \
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(EQUAL, value_oplist)( \
|
||||
@@ -588,15 +602,19 @@
|
||||
for(M_C(name, _it)(it, dict1) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)) { \
|
||||
const struct M_C(name, _pair_s) *item = M_C(name, _cref)(it); \
|
||||
value_type *ptr = M_C(name, _get)(dict2, item->key); \
|
||||
if (ptr == NULL) \
|
||||
return false; \
|
||||
M_IF(isSet)(, \
|
||||
if (M_CALL_EQUAL(value_oplist, item->value, *ptr) == false) \
|
||||
return false; \
|
||||
) \
|
||||
} \
|
||||
const M_C(name, _type_t) *item = M_C(name, _cref)(it); \
|
||||
M_IF(isSet)( \
|
||||
value_type *ptr = M_C(name, _get)(dict2, *item); \
|
||||
if (ptr == NULL) \
|
||||
return false; \
|
||||
, \
|
||||
value_type *ptr = M_C(name, _get)(dict2, item->key); \
|
||||
if (ptr == NULL) \
|
||||
return false; \
|
||||
if (M_CALL_EQUAL(value_oplist, item->value, *ptr) == false) \
|
||||
return false; \
|
||||
) \
|
||||
} \
|
||||
return true; \
|
||||
} \
|
||||
, /* no value equal */ ) \
|
||||
@@ -620,16 +638,21 @@
|
||||
STRINGI_CONTRACT (str); \
|
||||
(append ? string_cat_str : string_set_str) (str, "{"); \
|
||||
dict_it_t it; \
|
||||
bool print_comma = false; \
|
||||
for (M_C(name, _it)(it, dict) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)){ \
|
||||
const struct M_C(name, _pair_s) *item = \
|
||||
M_C(name, _cref)(it); \
|
||||
M_CALL_GET_STR(key_oplist, str, item->key, true); \
|
||||
string_push_back (str, ':'); \
|
||||
M_CALL_GET_STR(value_oplist, str, item->value, true); \
|
||||
if (!M_C(name, _last_p)(it)) \
|
||||
if (print_comma) \
|
||||
string_push_back (str, ','); \
|
||||
const M_C(name, _type_t) *item = M_C(name, _cref)(it); \
|
||||
M_IF(isSet)( \
|
||||
M_CALL_GET_STR(key_oplist, str, *item, true); \
|
||||
, \
|
||||
M_CALL_GET_STR(key_oplist, str, item->key, true); \
|
||||
string_push_back (str, ':'); \
|
||||
M_CALL_GET_STR(value_oplist, str, item->value, true); \
|
||||
) \
|
||||
print_comma = true; \
|
||||
} \
|
||||
string_push_back (str, '}'); \
|
||||
STRINGI_CONTRACT(str); \
|
||||
@@ -643,16 +666,21 @@
|
||||
assert (file != NULL); \
|
||||
fputc ('{', file); \
|
||||
dict_it_t it; \
|
||||
bool print_comma = false; \
|
||||
for (M_C(name, _it)(it, dict) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)){ \
|
||||
const struct M_C(name, _pair_s) *item = \
|
||||
M_C(name, _cref)(it); \
|
||||
M_CALL_OUT_STR(key_oplist, file, item->key); \
|
||||
fputc (':', file); \
|
||||
M_CALL_OUT_STR(value_oplist, file, item->value); \
|
||||
if (!M_C(name, _last_p)(it)) \
|
||||
if (print_comma) \
|
||||
fputc (',', file); \
|
||||
const M_C(name, _type_t) *item = M_C(name, _cref)(it); \
|
||||
M_IF(isSet)( \
|
||||
M_CALL_OUT_STR(key_oplist, file, *item); \
|
||||
, \
|
||||
M_CALL_OUT_STR(key_oplist, file, item->key); \
|
||||
fputc (':', file); \
|
||||
M_CALL_OUT_STR(value_oplist, file, item->value); \
|
||||
) \
|
||||
print_comma = true; \
|
||||
} \
|
||||
fputc ('}', file); \
|
||||
} \
|
||||
@@ -678,13 +706,14 @@
|
||||
do { \
|
||||
while (isspace(*str)) str++; \
|
||||
bool b = M_CALL_PARSE_STR(key_oplist, key, str, &str); \
|
||||
do { c = *str++; } while (isspace(c)); \
|
||||
if (b == false || c != ':') { goto exit; } \
|
||||
b = M_CALL_PARSE_STR(value_oplist, value, str, &str); \
|
||||
if (b == false) { goto exit; } \
|
||||
M_IF(isSet)( \
|
||||
if (b == false) { break; } \
|
||||
M_C(name, _push)(dict, key); \
|
||||
, \
|
||||
do { c = *str++; } while (isspace(c)); \
|
||||
if (b == false || c != ':') { goto exit; } \
|
||||
b = M_CALL_PARSE_STR(value_oplist, value, str, &str); \
|
||||
if (b == false) { goto exit; } \
|
||||
M_C(name, _set_at)(dict, key, value); \
|
||||
) \
|
||||
do { c = *str++; } while (isspace(c)); \
|
||||
@@ -718,14 +747,15 @@
|
||||
do { c = fgetc(file); } while (isspace(c)); \
|
||||
ungetc(c, file); \
|
||||
bool b = M_CALL_IN_STR(key_oplist, key, file); \
|
||||
do { c = fgetc(file); } while (isspace(c)); \
|
||||
if (b == false || c == EOF) { break; } \
|
||||
if (c != ':') { c = 0; break; } \
|
||||
b = M_CALL_IN_STR(value_oplist, value, file); \
|
||||
if (b == false) { c = 0; break; } \
|
||||
M_IF(isSet)( \
|
||||
if (b == false) { break; } \
|
||||
M_C(name, _push)(dict, key); \
|
||||
, \
|
||||
do { c = fgetc(file); } while (isspace(c)); \
|
||||
if (b == false || c == EOF) { break; } \
|
||||
if (c != ':') { c = 0; break; } \
|
||||
b = M_CALL_IN_STR(value_oplist, value, file); \
|
||||
if (b == false) { c = 0; break; } \
|
||||
M_C(name, _set_at)(dict, key, value); \
|
||||
) \
|
||||
do { c = fgetc(file); } while (isspace(c)); \
|
||||
@@ -745,8 +775,8 @@
|
||||
is not as random as other uses of the HASH table as d2 \
|
||||
uses the same order than d1 */ \
|
||||
for (M_C(name, _it)(it, d2); !M_C(name, _end_p)(it); M_C(name, _next)(it)){ \
|
||||
const struct M_C(name, _pair_s) *item = M_C(name, _cref)(it); \
|
||||
M_C(name, _push)(d1, item->key); \
|
||||
const M_C(name, _type_t) *item = M_C(name, _cref)(it); \
|
||||
M_C(name, _push)(d1, *item); \
|
||||
} \
|
||||
M_C(name, _clean)(d2); \
|
||||
} \
|
||||
@@ -794,7 +824,7 @@
|
||||
SWAP(M_C(name, _swap)), \
|
||||
CLEAN(M_C(name, _clean)), \
|
||||
TYPE(M_C(name, _t)), \
|
||||
SUBTYPE(struct M_C(name, _pair_s)), \
|
||||
SUBTYPE(M_C(name, _type_t)), \
|
||||
TEST_EMPTY(M_C(name,_empty_p)), \
|
||||
IT_TYPE(M_C(name, _it_t)), \
|
||||
IT_FIRST(M_C(name,_it)), \
|
||||
@@ -835,7 +865,7 @@
|
||||
SWAP(M_C(name, _swap)), \
|
||||
CLEAN(M_C(name, _clean)), \
|
||||
TYPE(M_C(name, _t)), \
|
||||
SUBTYPE(struct M_C(name, _pair_s)), \
|
||||
SUBTYPE(M_C(name, _type_t)), \
|
||||
TEST_EMPTY(M_C(name,_empty_p)), \
|
||||
PUSH(M_C(name,_push)), \
|
||||
KEY_TYPE(M_C(name, _key_type_t)), \
|
||||
|
||||
Reference in new issue
Block a user