diff options
author | Andrii Doroshenko (Xrayez) <xrayez@gmail.com> | 2020-09-12 23:58:56 +0300 |
---|---|---|
committer | Andrii Doroshenko (Xrayez) <xrayez@gmail.com> | 2020-09-12 23:58:56 +0300 |
commit | ac69f092fc9d841dc575afdd20dcfbcca3afd946 (patch) | |
tree | 6f1b07a93ce39059f947cb5e282dd9aa546e30cf | |
parent | 463879db56cc1e2417a02696e41ae3c40324ac24 (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.
-rw-r--r-- | core/list.h | 40 |
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 |