diff --git a/include/doubly-linked-list.h b/include/doubly-linked-list.h index 0108af73f961..d46d773800b4 100644 --- a/include/doubly-linked-list.h +++ b/include/doubly-linked-list.h @@ -229,14 +229,13 @@ LTYPE##_remove (LWRAPPERTYPE *wrapper, LTYPE *node) \ return previous; \ } -/* Generic swap. */ +/* Swap two nodes in a list. */ #define LINKED_LIST_SWAP(LTYPE) LTYPE##_swap #define LINKED_LIST_DECL_SWAP(LWRAPPERTYPE, LTYPE, EXPORT) \ EXPORT void \ LTYPE##_swap (LWRAPPERTYPE *wrapper, LTYPE *node1, LTYPE *node2) -/* Swap two nodes in a list. */ #define LINKED_LIST_DEFN_SWAP(LWRAPPERTYPE, LTYPE, EXPORT) \ EXPORT void \ LTYPE##_swap (LWRAPPERTYPE *wrapper, LTYPE *node1, LTYPE *node2) \ @@ -276,6 +275,34 @@ LTYPE##_swap (LWRAPPERTYPE *wrapper, LTYPE *node1, LTYPE *node2) \ } \ } +/* Swap two lists, i.e. swap two wrappers. */ +#define LINKED_LIST_SWAP_LISTS(LWRAPPERTYPE) LWRAPPERTYPE##_swap_lists + +#define LINKED_LIST_DECL_SWAP_LISTS(LWRAPPERTYPE, LTYPE, EXPORT) \ + EXPORT void \ + LWRAPPERTYPE##_swap_lists (LWRAPPERTYPE *left_w, LWRAPPERTYPE *right_w) + +#define LINKED_LIST_DEFN_SWAP_LISTS(LWRAPPERTYPE, LTYPE, EXPORT) \ +EXPORT void \ +LWRAPPERTYPE##_swap_lists (LWRAPPERTYPE *left_w, LWRAPPERTYPE *right_w) \ +{ \ + { \ + LTYPE *temp = left_w->first; \ + left_w->first = right_w->first; \ + right_w->first = temp; \ + } \ + { \ + LTYPE *temp = left_w->last; \ + left_w->last = right_w->last; \ + right_w->last = temp; \ + } \ + { \ + unsigned int temp = left_w->size; \ + left_w->size = right_w->size; \ + right_w->size = temp; \ + } \ +} + /* Note: all the mutative operations below also update the data in the wrapper, i.e. first, last and size. */ #define LINKED_LIST_MUTATIVE_OPS_PROTOTYPE(LWRAPPERTYPE, LTYPE, EXPORT) \ @@ -285,7 +312,8 @@ LTYPE##_swap (LWRAPPERTYPE *wrapper, LTYPE *node1, LTYPE *node2) \ LINKED_LIST_DECL_POP_FRONT(LWRAPPERTYPE, LTYPE, EXPORT); \ LINKED_LIST_DECL_POP_BACK(LWRAPPERTYPE, LTYPE, EXPORT); \ LINKED_LIST_DECL_REMOVE(LWRAPPERTYPE, LTYPE, EXPORT); \ - LINKED_LIST_DECL_SWAP(LWRAPPERTYPE, LTYPE, EXPORT) + LINKED_LIST_DECL_SWAP(LWRAPPERTYPE, LTYPE, EXPORT); \ + LINKED_LIST_DECL_SWAP_LISTS(LWRAPPERTYPE, LTYPE, EXPORT) #define LINKED_LIST_MUTATIVE_OPS_DECL(LWRAPPERTYPE, LTYPE, EXPORT) \ LINKED_LIST_DEFN_APPEND(LWRAPPERTYPE, LTYPE, EXPORT) \ @@ -294,7 +322,8 @@ LTYPE##_swap (LWRAPPERTYPE *wrapper, LTYPE *node1, LTYPE *node2) \ LINKED_LIST_DEFN_POP_FRONT(LWRAPPERTYPE, LTYPE, EXPORT) \ LINKED_LIST_DEFN_POP_BACK(LWRAPPERTYPE, LTYPE, EXPORT) \ LINKED_LIST_DEFN_REMOVE(LWRAPPERTYPE, LTYPE, EXPORT) \ - LINKED_LIST_DEFN_SWAP(LWRAPPERTYPE, LTYPE, EXPORT) + LINKED_LIST_DEFN_SWAP(LWRAPPERTYPE, LTYPE, EXPORT); \ + LINKED_LIST_DEFN_SWAP_LISTS(LWRAPPERTYPE, LTYPE, EXPORT) /* Sorting. */ diff --git a/libiberty/testsuite/test-doubly-linked-list.c b/libiberty/testsuite/test-doubly-linked-list.c index 93fe19a27aea..914bc7934e30 100644 --- a/libiberty/testsuite/test-doubly-linked-list.c +++ b/libiberty/testsuite/test-doubly-linked-list.c @@ -190,6 +190,8 @@ const int EXPECT_7 [] = { 10, 9, 2, 4, 3, 8, 11 }; const int EXPECT_8 [] = { 2, 3, 4, 8, 9, 10, 11 }; const int EXPECT_9 [] = { 3, 4, 8, 9, 10, 11 }; const int EXPECT_10 [] = { 3, 4, 8, 9, 10 }; +const int EXPECT_11 [] = { 20, 21, 22 }; +const int EXPECT_12 [] = { 3, 4, 8, 9, 10 }; const struct test_data_t test_data[] = { { .content = EXPECT_0, .size = sizeof(EXPECT_0) / sizeof(EXPECT_0[0]) }, { .content = EXPECT_1, .size = sizeof(EXPECT_1) / sizeof(EXPECT_1[0]) }, @@ -202,6 +204,8 @@ const struct test_data_t test_data[] = { { .content = EXPECT_8, .size = sizeof(EXPECT_8) / sizeof(EXPECT_8[0]) }, { .content = EXPECT_9, .size = sizeof(EXPECT_9) / sizeof(EXPECT_9[0]) }, { .content = EXPECT_10, .size = sizeof(EXPECT_10) / sizeof(EXPECT_10[0]) }, + { .content = EXPECT_11, .size = sizeof(EXPECT_11) / sizeof(EXPECT_11[0]) }, + { .content = EXPECT_12, .size = sizeof(EXPECT_12) / sizeof(EXPECT_12[0]) }, }; int main (void) @@ -272,5 +276,23 @@ int main (void) LINKED_LIST_POP_BACK(ListNodeType) (&wrapper); failures += ! check ("pop_back", &test_data[10], &wrapper); + LinkedListWrapperType other_wrapper = { + .first = NULL, + .last = NULL, + .size = 0, + }; + + LINKED_LIST_APPEND(ListNodeType) (&other_wrapper, l_new_node (20)); + LINKED_LIST_APPEND(ListNodeType) (&other_wrapper, l_new_node (21)); + LINKED_LIST_APPEND(ListNodeType) (&other_wrapper, l_new_node (22)); + + /* Swap wrappers once. */ + LINKED_LIST_SWAP_LISTS (LinkedListWrapperType) (&wrapper, &other_wrapper); + failures += ! check ("swap wrappers once", &test_data[11], &wrapper); + + /* Swap wrappers twice. */ + LINKED_LIST_SWAP_LISTS (LinkedListWrapperType) (&wrapper, &other_wrapper); + failures += ! check ("swap wrappers twice", &test_data[12], &wrapper); + exit (failures ? EXIT_FAILURE : EXIT_SUCCESS); }