summaryrefslogtreecommitdiff
path: root/core/list.h
diff options
context:
space:
mode:
authorAndrii Doroshenko (Xrayez) <xrayez@gmail.com>2020-09-12 23:58:56 +0300
committerAndrii Doroshenko (Xrayez) <xrayez@gmail.com>2020-09-12 23:58:56 +0300
commitac69f092fc9d841dc575afdd20dcfbcca3afd946 (patch)
tree6f1b07a93ce39059f947cb5e282dd9aa546e30cf /core/list.h
parent463879db56cc1e2417a02696e41ae3c40324ac24 (diff)
Fix `List` swap behavior on front, back and adjacent elements
- immediately return if A == B; - first and last elements (front, back) are updated upon relinking; - handles a special case of forward and backward adjacent elements.
Diffstat (limited to 'core/list.h')
-rw-r--r--core/list.h40
1 files changed, 25 insertions, 15 deletions
diff --git a/core/list.h b/core/list.h
index f850db5241..1cef3c484d 100644
--- a/core/list.h
+++ b/core/list.h
@@ -395,28 +395,38 @@ public:
ERR_FAIL_COND(p_A->data != _data);
ERR_FAIL_COND(p_B->data != _data);
+ if (p_A == p_B) {
+ return;
+ }
Element *A_prev = p_A->prev_ptr;
Element *A_next = p_A->next_ptr;
+ Element *B_prev = p_B->prev_ptr;
+ Element *B_next = p_B->next_ptr;
- p_A->next_ptr = p_B->next_ptr;
- p_A->prev_ptr = p_B->prev_ptr;
-
- p_B->next_ptr = A_next;
- p_B->prev_ptr = A_prev;
-
- if (p_A->prev_ptr) {
- p_A->prev_ptr->next_ptr = p_A;
+ if (A_prev) {
+ A_prev->next_ptr = p_B;
+ } else {
+ _data->first = p_B;
}
- if (p_A->next_ptr) {
- p_A->next_ptr->prev_ptr = p_A;
+ if (B_prev) {
+ B_prev->next_ptr = p_A;
+ } else {
+ _data->first = p_A;
}
-
- if (p_B->prev_ptr) {
- p_B->prev_ptr->next_ptr = p_B;
+ if (A_next) {
+ A_next->prev_ptr = p_B;
+ } else {
+ _data->last = p_B;
}
- if (p_B->next_ptr) {
- p_B->next_ptr->prev_ptr = p_B;
+ if (B_next) {
+ B_next->prev_ptr = p_A;
+ } else {
+ _data->last = p_A;
}
+ p_A->prev_ptr = A_next == p_B ? p_B : B_prev;
+ p_A->next_ptr = B_next == p_A ? p_B : B_next;
+ p_B->prev_ptr = B_next == p_A ? p_A : A_prev;
+ p_B->next_ptr = A_next == p_B ? p_A : A_next;
}
/**
* copy the list