Support EINA_INLIST to be anywhere in the struct with _FOREACH macros.

Fix pointer arithmetic with EINA_CONTAINER_GET.
Change Inlist test to have the int first and not assume a direct cast works.


SVN revision: 42366
This commit is contained in:
Iván Briano 2009-09-09 14:05:31 +00:00
parent 2d3021f128
commit 555de0f914
2 changed files with 17 additions and 11 deletions

View File

@ -52,7 +52,7 @@ struct _Eina_Inlist
#define EINA_INLIST Eina_Inlist __in_list
#define EINA_INLIST_GET(Inlist) (&((Inlist)->__in_list))
#define EINA_INLIST_CONTAINER_GET(ptr, type) ((type *) ((Eina_Inlist *) ptr - offsetof(type, __in_list)))
#define EINA_INLIST_CONTAINER_GET(ptr, type) ((type *) ((char *) ptr - offsetof(type, __in_list)))
EAPI Eina_Inlist * eina_inlist_append(Eina_Inlist *in_list, Eina_Inlist *in_item) EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT;
EAPI Eina_Inlist * eina_inlist_prepend(Eina_Inlist *in_list, Eina_Inlist *in_item) EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT;
@ -67,8 +67,13 @@ EAPI unsigned int eina_inlist_count(const Eina_Inlist *list) EINA_WARN_UNUSED_RE
EAPI Eina_Iterator *eina_inlist_iterator_new(const Eina_Inlist *in_list) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
EAPI Eina_Accessor *eina_inlist_accessor_new(const Eina_Inlist *in_list) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
#define EINA_INLIST_FOREACH(list, l) for (l = (void*)list; l; l = (void*)(l->__in_list.next))
#define EINA_INLIST_REVERSE_FOREACH(list, l) for (l = (list ? (void*)(list->last) : NULL); l; l = (void*)(l->__in_list.prev))
/* This two macros are helpers for the _FOREACH ones, don't use them */
#define INLIST_OFFSET(ref) ((char*)&(ref)->__in_list - (char*)(ref))
#define INLIST_CONTAINER(ref, ptr) (void*)((char*)(ptr) - INLIST_OFFSET(ref))
#define EINA_INLIST_FOREACH(list, l) for (l = (list ? INLIST_CONTAINER(l, list) : NULL); l; l = (EINA_INLIST_GET(l)->next ? INLIST_CONTAINER(l, EINA_INLIST_GET(l)->next) : NULL))
#define EINA_INLIST_REVERSE_FOREACH(list, l) for (l = (list ? INLIST_CONTAINER(l, list->last) : NULL); l; l = (EINA_INLIST_GET(l)->prev ? INLIST_CONTAINER(l, EINA_INLIST_GET(l)->prev) : NULL))
/**
* @}

View File

@ -30,8 +30,8 @@
typedef struct _Eina_Test_Inlist Eina_Test_Inlist;
struct _Eina_Test_Inlist
{
EINA_INLIST;
int i;
EINA_INLIST;
};
static Eina_Test_Inlist*
@ -63,13 +63,13 @@ START_TEST(eina_inlist_simple)
tmp = _eina_test_inlist_build(1664);
lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), lst);
fail_if(!lst);
fail_if(((Eina_Test_Inlist*)lst)->i != 42);
fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist)->i != 42);
prev = tmp;
tmp = _eina_test_inlist_build(3227);
lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(tmp), EINA_INLIST_GET(prev));
fail_if(!lst);
fail_if(((Eina_Test_Inlist*)lst)->i != 42);
fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist)->i != 42);
lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp));
@ -111,16 +111,17 @@ START_TEST(eina_inlist_simple)
fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
#endif
tmp = (Eina_Test_Inlist*) lst;
tmp = EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist);
lst = eina_inlist_demote(lst, lst);
fail_if(lst == (Eina_Inlist*) tmp);
fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist) == tmp);
lst = eina_inlist_promote(lst, EINA_INLIST_GET(tmp));
fail_if(lst != (Eina_Inlist*) tmp);
fail_if(lst != EINA_INLIST_GET(tmp));
tmp = (Eina_Test_Inlist*) eina_inlist_find(lst, EINA_INLIST_GET(prev));
tmp = EINA_INLIST_CONTAINER_GET(eina_inlist_find(lst, EINA_INLIST_GET(prev)), Eina_Test_Inlist);
lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp));
tmp = (Eina_Test_Inlist*) eina_inlist_find(lst, EINA_INLIST_GET(tmp));
prev = eina_inlist_find(lst, EINA_INLIST_GET(tmp));
tmp = prev ? EINA_INLIST_CONTAINER_GET(prev, Eina_Test_Inlist) : NULL;
fail_if(tmp != NULL);
while (lst)