mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-01-04 00:20:14 +01:00
util: add the macros to run through a list backwards
This ended up being unused but I wrote the code so we might as well include it.
This commit is contained in:
parent
d99e42b808
commit
0d5ce5dd87
2 changed files with 84 additions and 0 deletions
|
|
@ -190,4 +190,67 @@ MUNIT_TEST(test_list_nth)
|
|||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(list_first_last)
|
||||
{
|
||||
struct list_test {
|
||||
int val;
|
||||
struct list node;
|
||||
} tests[] = {
|
||||
{ .val = 1 },
|
||||
{ .val = 2 },
|
||||
{ .val = 3 },
|
||||
{ .val = 4 },
|
||||
};
|
||||
struct list_test *t;
|
||||
struct list head;
|
||||
|
||||
list_init(&head);
|
||||
ARRAY_FOR_EACH(tests, t) {
|
||||
list_append(&head, &t->node);
|
||||
}
|
||||
|
||||
struct list_test *first = list_first_entry(&head, t, node);
|
||||
munit_assert_int(first->val, ==, 1);
|
||||
first = list_first_entry_by_type(&head, struct list_test, node);
|
||||
munit_assert_int(first->val, ==, 1);
|
||||
|
||||
struct list_test *last = list_last_entry(&head, t, node);
|
||||
munit_assert_int(last->val, ==, 4);
|
||||
last = list_last_entry_by_type(&head, struct list_test, node);
|
||||
munit_assert_int(last->val, ==, 4);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(list_foreach)
|
||||
{
|
||||
struct list_test {
|
||||
int val;
|
||||
struct list node;
|
||||
} tests[] = {
|
||||
{ .val = 1 },
|
||||
{ .val = 2 },
|
||||
{ .val = 3 },
|
||||
{ .val = 4 },
|
||||
};
|
||||
struct list_test *t;
|
||||
struct list head;
|
||||
|
||||
list_init(&head);
|
||||
ARRAY_FOR_EACH(tests, t) {
|
||||
list_append(&head, &t->node);
|
||||
}
|
||||
|
||||
unsigned int idx = 0;
|
||||
list_for_each(t, &head, node) {
|
||||
munit_assert_int(t->val, ==, tests[idx++].val);
|
||||
}
|
||||
|
||||
list_for_each_backwards(t, &head, node) {
|
||||
munit_assert_int(t->val, ==, tests[--idx].val);
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ void list_append(struct list *list, struct list *elm);
|
|||
*
|
||||
*/
|
||||
void list_remove(struct list *elm);
|
||||
|
||||
/**
|
||||
* Returns true if the given list head is an empty list.
|
||||
*/
|
||||
|
|
@ -139,6 +140,12 @@ bool list_empty(const struct list *list);
|
|||
#define list_first_entry(head, pointer_of_type, member) \
|
||||
container_of((head)->next, __typeof__(*pointer_of_type), member)
|
||||
|
||||
/**
|
||||
* Return the last entry of the list. See list_first_entry() for details.
|
||||
*/
|
||||
#define list_last_entry(head, pointer_of_type, member) \
|
||||
container_of((head)->prev, __typeof__(*pointer_of_type), member)
|
||||
|
||||
/**
|
||||
* Given a list 'head', return the first entry of type 'container_type' that
|
||||
* has a member 'link'.
|
||||
|
|
@ -159,6 +166,12 @@ bool list_empty(const struct list *list);
|
|||
#define list_first_entry_by_type(head, container_type, member) \
|
||||
container_of((head)->next, container_type, member)
|
||||
|
||||
/**
|
||||
* Return the last entry of the list. See list_first_entry_by_type() for details.
|
||||
*/
|
||||
#define list_last_entry_by_type(head, container_type, member) \
|
||||
container_of((head)->prev, container_type, member)
|
||||
|
||||
/**
|
||||
* Iterate through the list.
|
||||
*
|
||||
|
|
@ -177,6 +190,14 @@ bool list_empty(const struct list *list);
|
|||
&pos->member != (head); \
|
||||
pos = list_first_entry_by_type(&pos->member, __typeof__(*pos), member))
|
||||
|
||||
/**
|
||||
* Iterate through the list backwards.
|
||||
*/
|
||||
#define list_for_each_backwards(pos, head, member) \
|
||||
for (pos = list_last_entry_by_type(head, __typeof__(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = list_last_entry_by_type(&pos->member, __typeof__(*pos), member))
|
||||
|
||||
/**
|
||||
* Iterate through the list. Equivalent to list_for_each() but allows
|
||||
* calling list_remove() on the element.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue