Przeglądaj źródła

Allow a list to be detached, and then be able to test if an element is alone in the dark

Samuel Thibault 7 lat temu
rodzic
commit
02d5b8e557
1 zmienionych plików z 18 dodań i 5 usunięć
  1. 18 5
      src/common/list.h

+ 18 - 5
src/common/list.h

@@ -349,6 +349,11 @@ LIST_INLINE int ENAME##_multilist_empty_##MEMBER(struct ENAME##_multilist_##MEMB
 	return head->next == head; \
 } \
 \
+/* Test whether the element is alone in a detached list.  */ \
+LIST_INLINE int ENAME##_multilist_alone_##MEMBER(TYPE *e) { \
+	return (e)->MEMBER.next == &e->MEMBER && (e)->MEMBER.prev == &(e)->MEMBER; \
+} \
+\
 /* Return the first element of the list.  */ \
 LIST_INLINE TYPE *ENAME##_multilist_begin_##MEMBER(struct ENAME##_multilist_##MEMBER *head) { \
 	return ENAME##_of_multilist_##MEMBER(head->next); \
@@ -362,15 +367,23 @@ LIST_INLINE TYPE *ENAME##_multilist_next_##MEMBER(TYPE *e) { \
 	return ENAME##_of_multilist_##MEMBER(e->MEMBER.next); \
 } \
 \
- /* Move a list from its head to another head.  */ \
+ /* Move a list from its head to another head. Passing newhead == NULL allows to detach the list from any head. */ \
 LIST_INLINE void ENAME##_multilist_move_##MEMBER(struct ENAME##_multilist_##MEMBER *head, struct ENAME##_multilist_##MEMBER *newhead) { \
 	if (ENAME##_multilist_empty_##MEMBER(head)) \
 		ENAME##_multilist_head_init_##MEMBER(newhead); \
 	else { \
-		newhead->next = head->next; \
-		newhead->next->prev = newhead; \
-		newhead->prev = head->prev; \
-		newhead->prev->next = newhead; \
+		if (newhead) { \
+			newhead->next = head->next; \
+			newhead->next->prev = newhead; \
+		} else { \
+			head->next->prev = head->prev; \
+		} \
+		if (newhead) { \
+			newhead->prev = head->prev; \
+			newhead->prev->next = newhead; \
+		} else { \
+			head->prev->next = head->next; \
+		} \
 		head->next = head; \
 		head->prev = head; \
 	} \