diff --git a/m-i-list.h b/m-i-list.h index 211f9b30..83ee6683 100644 --- a/m-i-list.h +++ b/m-i-list.h @@ -41,6 +41,7 @@ #define ILIST_INTERFACE(name, type) \ struct ilist_head_s name + /* Define a doubly-linked intrusive list of a given type. The type needs to have ILIST_INTERFACE(). USAGE: @@ -52,6 +53,20 @@ (name, __VA_ARGS__, M_C(name, _t), M_C(name, _it_t) ))) \ M_END_PROTECTED_CODE + +/* Define a doubly-linked intrusive list of a given type + as the provided type name_t with the iterator named it_t. + The type needs to have ILIST_INTERFACE(). + USAGE: + ILIST_DEF_AS(name, name_t, it_t, type [, oplist_of_the_type]) */ +#define ILIST_DEF_AS(name, name_t, it_t, ...) \ + M_BEGIN_PROTECTED_CODE \ + ILISTI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ + ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), name_t, it_t ), \ + (name, __VA_ARGS__, name_t, it_t ))) \ + M_END_PROTECTED_CODE + + /* Define the oplist of a doubly-linked instrusive list of type. USAGE: ILIST_OPLIST(name [, oplist_of_the_type]) */ @@ -63,7 +78,7 @@ /********************************** INTERNAL ************************************/ -/* Define the structure to be added in all objects. */ +/* Define the basic structure to be added in all objects. */ typedef struct ilist_head_s { struct ilist_head_s *next; struct ilist_head_s *prev; diff --git a/tests/test-milist.c b/tests/test-milist.c index 157fca05..e13cd0bb 100644 --- a/tests/test-milist.c +++ b/tests/test-milist.c @@ -40,6 +40,14 @@ END_COVERAGE ILIST_DEF(ilist_free, test_t, (DEL(free))) +typedef struct testd_s { + double n; + ILIST_INTERFACE (ListDouble, struct testd_s); +} TestDouble; + +ILIST_DEF_AS(ListDouble, ListDouble, ListDoubleIt, TestDouble, M_POD_OPLIST) +#define M_OPL_ListDouble() ILIST_OPLIST(ListDouble, M_POD_OPLIST) + static void test(void) { test_t x1, x2, x3; @@ -239,10 +247,28 @@ static void test_free(void) ilist_free_clear(list); } +static void test_double(void) +{ + M_LET( tab, ListDouble) { + TestDouble base[5]; + for(int i = 0; i < 5; i++) { + base[i].n = (double) i; + ListDouble_init_field(&base[i]); + ListDouble_push_back(tab, &base[i]); + } + double ref = 0.0; + for M_EACH(i, tab, ListDouble) { + assert (i->n == ref); + ref += 1.0; + } + } +} + int main(void) { test(); test2(); test_free(); + test_double(); exit(0); }