diff --git a/README.md b/README.md index 33602b2a..ea9ddc0c 100644 --- a/README.md +++ b/README.md @@ -1572,7 +1572,7 @@ A [dictionary](https://en.wikipedia.org/wiki/Associative_array) (or associative composed of a collection of (key, value) pairs, such that each possible key appears at most once in the collection. -#### DICT\_DEF2(name, key\_type, key\_oplist, value\_type, value\_oplist) +#### DICT\_DEF2(name, key\_type[, key\_oplist], value\_type[, value\_oplist]) Define the dictionary 'name##\_t' and its associated methods as "static inline" functions. 'name' shall be a C identifier which will be used to identify the container. @@ -1596,7 +1596,7 @@ Example: } -#### DICT\_STOREHASH\_DEF2(name, key\_type, key\_oplist, value\_type, value\_oplist) +#### DICT\_STOREHASH\_DEF2(name, key\_type[, key\_oplist], value\_type[, value\_oplist]) Define the dictionary 'name##\_t' and its associated methods as "static inline" functions just like DICT\_DEF2. @@ -1606,7 +1606,7 @@ which allows avoiding recomputing it in some occasions resulting in faster dictionary if the hash is costly to compute, or slower otherwise. -#### DICT\_OA\_DEF2(name, key\_type, key\_oplist, value\_type, value\_oplist) +#### DICT\_OA\_DEF2(name, key\_type[, key\_oplist], value\_type[, value\_oplist]) Define the dictionary 'name##\_t' and its associated methods as "static inline" functions much like DICT\_DEF2. @@ -1645,11 +1645,11 @@ Example: } -#### DICT\_OPLIST(name, key\_oplist, value\_oplist) +#### DICT\_OPLIST(name[, key\_oplist, value\_oplist]) Return the oplist of the dictionary defined by calling DICT\_DEF2 with name & key\_oplist & value\_oplist. -#### DICT\_SET\_DEF2(name, key\_type, key\_oplist) +#### DICT\_SET\_DEF2(name, key\_type[, key\_oplist]) Define the set 'name##\_t' and its associated methods as "static inline" functions. A set is a specialized version of a dictionary with no value. @@ -1664,13 +1664,13 @@ Interface is subjected to minor change. Example: - DICT_SET_DEF2(dict_strSet, string_t, STRING_OPLIST) + DICT_SET_DEF2(dict_strSet, string_t) dict_strSet_t set; void f(string_t key) { dict_strSet_set_at (set, key); } -#### DICT\_SET\_OPLIST(name, key\_oplist) +#### DICT\_SET\_OPLIST(name[, key\_oplist]) Return the oplist of the set defined by calling DICT\_SET\_DEF2 with name & key\_oplist. diff --git a/example/ex-grep01.c b/example/ex-grep01.c index 91054d27..de78ffe6 100644 --- a/example/ex-grep01.c +++ b/example/ex-grep01.c @@ -5,7 +5,7 @@ ARRAY_DEF(array_size, size_t) #define M_OPL_array_size_t() ARRAY_OPLIST(array_size) -DICT_DEF2(map_pos, string_t, STRING_OPLIST, array_size_t, ARRAY_OPLIST(array_size)) +DICT_DEF2(map_pos, string_t, array_size_t) #define M_OPL_map_pos_t() DICT_OPLIST(map_pos, STRING_OPLIST, ARRAY_OPLIST(array_size)) int main(int argc, const char *argv[]) diff --git a/m-dict.h b/m-dict.h index 51a96bc7..3383c01c 100644 --- a/m-dict.h +++ b/m-dict.h @@ -30,10 +30,67 @@ #include "m-tuple.h" /* Define a dictionary with the key key_type to the value value_type. - USAGE: DICT_DEF2(name, key_type, key_oplist, value_type, value_oplist) + USAGE: DICT_DEF2(name, key_type[, key_oplist], value_type[, value_oplist]) */ -#define DICT_DEF2(name, key_type, key_oplist, value_type, value_oplist) \ - \ +#define DICT_DEF2(name, key_type, ...) \ + DICTI_DEF2(M_IF_NARGS_EQ1(__VA_ARGS__) \ + ((name, key_type, M_GLOBAL_OPLIST_OR_DEF(key_type), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__) ), \ + (name, key_type, __VA_ARGS__))) + + +/* Define a dictionary with the key key_type to the value value_type. + which stores the computed hash value (avoiding the need of recomputing it). + USAGE: DICT_STOREHASH_DEF2(name, key_type[, key_oplist], value_type[, value_oplist]) +*/ +#define DICT_STOREHASH_DEF2(name, key_type, ...) \ + DICTI_SHASH_DEF2(M_IF_NARGS_EQ1(__VA_ARGS__) \ + ((name, key_type, M_GLOBAL_OPLIST_OR_DEF(key_type), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__) ), \ + (name, key_type, __VA_ARGS__))) + + +/* Define the oplist of a dictionnary. + USAGE: DICT_OPLIST(name[, oplist of the key type, oplist of the value type]) */ +#define DICT_OPLIST(...) \ + M_IF_NARGS_EQ1(__VA_ARGS__) \ + (DICTI_OPLIST(__VA_ARGS__, M_DEFAULT_OPLIST, M_DEFAULT_OPLIST ), \ + DICTI_OPLIST(__VA_ARGS__ )) + + +/* Define a set with the key key_type + USAGE: DICT_SET_DEF2(name, key_type, key_oplist) +*/ +#define DICT_SET_DEF2(name, ...) \ + DICTI_SET_DEF(M_IF_NARGS_EQ1(__VA_ARGS__) \ + ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__) ), \ + (name, __VA_ARGS__))) + + +/* Define the oplist of a dictionnary. + USAGE: DICT_SET_OPLIST(name[, oplist of the key type]) */ +#define DICT_SET_OPLIST(...) \ + M_IF_NARGS_EQ1(__VA_ARGS__) \ + (DICTI_SET_OPLIST(__VA_ARGS__, M_DEFAULT_OPLIST, M_DEFAULT_OPLIST ), \ + DICTI_SET_OPLIST(__VA_ARGS__ , M_RET_ARG2 (__VA_ARGS__, ) )) + + +/* Define a dictionary with the key key_type to the value value_type + with an Open Addressing implementation. Same oplist. + KEY_OPLIST needs OOR_EQUAL & OOR_SET as methods of the key */ +#define DICT_OA_DEF2(name, key_type, ...) \ + DICTI_OA_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ + ((name, key_type, M_GLOBAL_OPLIST_OR_DEF(key_type), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__) ), \ + (name, key_type, __VA_ARGS__))) + + + + +/********************************** INTERNAL ************************************/ + +/* Define a dictionary with the key key_type to the value value_type. +*/ +#define DICTI_DEF2(arg) DICTI_DEF2B arg +#define DICTI_DEF2B(name, key_type, key_oplist, value_type, value_oplist) \ + \ TUPLE_DEF2(M_C(name, _pair), (key, key_type, key_oplist), (value, value_type, value_oplist)) \ \ M_IF_METHOD(MEMPOOL, key_oplist) \ @@ -54,9 +111,9 @@ /* Define a dictionary with the key key_type to the value value_type. which stores the computed hash value (avoiding the need of recomputing it). - USAGE: DICT_STOREHASH_DEF2(name, key_type, key_oplist, value_type, value_oplist) */ -#define DICT_STOREHASH_DEF2(name, key_type, key_oplist, value_type, value_oplist) \ +#define DICTI_SHASH_DEF2(arg) DICTI_SHASH_DEF2B arg +#define DICTI_SHASH_DEF2B(name, key_type, key_oplist, value_type, value_oplist) \ \ TUPLE_DEF2(M_C(name, _pair), (hash, size_t, M_DEFAULT_OPLIST), (key, key_type, key_oplist), (value, value_type, value_oplist)) \ \ @@ -75,18 +132,11 @@ \ DICTI_FUNC_DEF2(name, key_type, key_oplist, value_type, value_oplist, 0, 1, M_C(name, _t), M_C(name, _it_t)) -/* Define the oplist of a dictionnary. - USAGE: DICT_OPLIST(name[, oplist of the key type, oplist of the value type]) */ -#define DICT_OPLIST(...) \ - M_IF_NARGS_EQ1(__VA_ARGS__) \ - (DICTI_OPLIST(__VA_ARGS__, M_DEFAULT_OPLIST, M_DEFAULT_OPLIST ), \ - DICTI_OPLIST(__VA_ARGS__ )) - /* Define a set with the key key_type - USAGE: DICT_SET_DEF2(name, key_type, key_oplist) */ -#define DICT_SET_DEF2(name, key_type, key_oplist) \ +#define DICTI_SET_DEF(arg) DICTI_SET_DEFB arg +#define DICTI_SET_DEFB(name, key_type, key_oplist) \ \ TUPLE_DEF2(M_C(name, _pair), (key, key_type, key_oplist)) \ \ @@ -108,25 +158,6 @@ 1, 0, M_C(name, _t), M_C(name, _it_t)) -/* Define the oplist of a dictionnary. - USAGE: DICT_SET_OPLIST(name[, oplist of the key type]) */ -#define DICT_SET_OPLIST(...) \ - M_IF_NARGS_EQ1(__VA_ARGS__) \ - (DICTI_SET_OPLIST(__VA_ARGS__, M_DEFAULT_OPLIST, M_DEFAULT_OPLIST ), \ - DICTI_SET_OPLIST(__VA_ARGS__ , M_RET_ARG2 (__VA_ARGS__, ) )) - - -/* Define a dictionary with the key key_type to the value value_type - with an Open Addressing implementation. Same oplist. - KEY_OPLIST needs OOR_EQUAL & OOR_SET as methods of the key */ -#define DICT_OA_DEF2(name, key_type, key_oplist, value_type, value_oplist) \ - DICTI_OA_DEFI(name, key_type, key_oplist, value_type, value_oplist, \ - M_GET_OOR_EQUAL key_oplist, M_GET_OOR_SET key_oplist, \ - 0.2, 0.7, M_C(name,_t), M_C(name, _it_t) ) - - -/********************************** INTERNAL ************************************/ - /* Define a chained dictionnary */ #define DICTI_FUNC_DEF2(name, key_type, key_oplist, value_type, value_oplist, isSet, isStoreHash, dict_t, dict_it_t) \ \ @@ -816,7 +847,13 @@ typedef enum { assert( (dict)->count <= (dict)->mask+1); \ } while (0) -#define DICTI_OA_DEFI(name, key_type, key_oplist, value_type, value_oplist, oor_equal_p, oor_set, coeff_down, coeff_up, dict_t, dict_it_t) \ +#define DICTI_OA_DEF_P1(args) DICTI_OA_DEF_P2 args +#define DICTI_OA_DEF_P2(name, key_type, key_oplist, value_type, value_oplist) \ + DICTI_OA_DEF_P3(name, key_type, key_oplist, value_type, value_oplist, \ + M_GET_OOR_EQUAL key_oplist, M_GET_OOR_SET key_oplist, \ + 0.2, 0.7, M_C(name,_t), M_C(name, _it_t) ) + +#define DICTI_OA_DEF_P3(name, key_type, key_oplist, value_type, value_oplist, oor_equal_p, oor_set, coeff_down, coeff_up, dict_t, dict_it_t) \ \ typedef struct M_C(name, _pair_s) { \ key_type key; \