This one only makes one combined run through the list instead of two independent runs as does broadblues' variant above. And in contrast to that it does correct un/re-linking for all situations. Untested
EDIT: relinking neighbours was missing!
EDIT: special case direct neighbour swap!
EDIT: some redundancy removed.
EDIT: now it should work for all (still untested though ;) )
BOOL SwapListItems(struct List *List,uint32 Item1,uint32 Item2)
{
BOOL success=FALSE;
// catch special case of identical indices, return immediately with success
if(Item1!=Item2) {
// make sure Item1 is the smaller index
if(Item2<Item1) {
uint32 tmp=Item1;
Item1=Item2;
Item2=tmp;
}
// adjust Item2 index so that it becomes relativ to Item1
Item2-=Item1;
// walk to Item1
struct Node *a=IExec->GetHead(List);
while(a && Item1--) {
a=a->ln_Succ;
}
if(a) {
// walk to Item2, starting from Item1.
// we can do a do...while and pre-dec because we know that Item2 is > 0 ;)
struct Node *b=a;
do {
b=b->ln_Succ;
}while(b && --Item2);
if(b && b->ln_Succ) { // second check is to verify that we didn't tap into the "physical" tail (or use b=IExec->GetSucc(b) in the loop)
// the actual swap
struct Node *s=a->ln_Succ;
struct Node *p=a->ln_Pred;
a->ln_Succ=b->ln_Succ;
// b->ln_Pred=p; * bug, ouch, this one has to ... (see at bottom)
// special case: a is direct pred of b, then a std. link swap would cause interesting stuff, like a pointing to a etc. :P
if(s==b) {
a->ln_Pred=b;
b->ln_Succ=a;
} else {
a->ln_Pred=b->ln_Pred;
b->ln_Succ=s;
// don't forget to relink the surrounding items!
a->ln_Pred->ln_Succ=a;
b->ln_Succ->ln_Pred=b;
}
b->ln_Pred=p; // ... * go from above to here
// more relinking
a->ln_Succ->ln_Pred=a;
b->ln_Pred->ln_Succ=b;
success=TRUE;
}
}
} else success=TRUE;
return success;
}
Edited by Daytona675x on 2019/8/6 6:49:09
Edited by Daytona675x on 2019/8/6 8:58:16
Edited by Daytona675x on 2019/8/6 8:58:55
Edited by Daytona675x on 2019/8/6 9:49:01
Edited by Daytona675x on 2019/8/6 22:34:17
Edited by Daytona675x on 2019/8/6 22:40:55
Edited by Daytona675x on 2019/8/7 6:42:09
Edited by Daytona675x on 2019/8/7 7:12:29
Edited by Daytona675x on 2019/8/7 7:13:41