forked from bartvdbraak/blender
BLI_linklist: Add a new helper to move an item (identified by its current index) to a new position in the list.
This commit is contained in:
parent
a9c5d0ba51
commit
bc218cf4d2
@ -54,6 +54,8 @@ struct LinkNode *BLI_linklist_find(struct LinkNode *list, int index);
|
||||
|
||||
void BLI_linklist_reverse(struct LinkNode **listp);
|
||||
|
||||
void BLI_linklist_move_item(struct LinkNode **listp, int curr_index, int new_index);
|
||||
|
||||
void BLI_linklist_prepend_nlink(struct LinkNode **listp, void *ptr, struct LinkNode *nlink);
|
||||
void BLI_linklist_prepend(struct LinkNode **listp, void *ptr);
|
||||
void BLI_linklist_prepend_arena(struct LinkNode **listp, void *ptr, struct MemArena *ma);
|
||||
|
@ -86,6 +86,77 @@ void BLI_linklist_reverse(LinkNode **listp)
|
||||
*listp = rhead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move an item from its current position to a new one inside a single-linked list.
|
||||
* Note *listp may be modified.
|
||||
*/
|
||||
void BLI_linklist_move_item(LinkNode **listp, int curr_index, int new_index)
|
||||
{
|
||||
LinkNode *lnk, *lnk_psrc = NULL, *lnk_pdst = NULL;
|
||||
int i;
|
||||
|
||||
if (new_index == curr_index) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_index < curr_index) {
|
||||
for (lnk = *listp, i = 0; lnk; lnk = lnk->next, i++) {
|
||||
if (i == new_index - 1) {
|
||||
lnk_pdst = lnk;
|
||||
}
|
||||
else if (i == curr_index - 1) {
|
||||
lnk_psrc = lnk;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(lnk_psrc && lnk_psrc->next && (!lnk_pdst || lnk_pdst->next))) {
|
||||
/* Invalid indices, abort. */
|
||||
return;
|
||||
}
|
||||
|
||||
lnk = lnk_psrc->next;
|
||||
lnk_psrc->next = lnk->next;
|
||||
if (lnk_pdst) {
|
||||
lnk->next = lnk_pdst->next;
|
||||
lnk_pdst->next = lnk;
|
||||
}
|
||||
else {
|
||||
/* destination is first element of the list... */
|
||||
lnk->next = *listp;
|
||||
*listp = lnk;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (lnk = *listp, i = 0; lnk; lnk = lnk->next, i++) {
|
||||
if (i == new_index) {
|
||||
lnk_pdst = lnk;
|
||||
break;
|
||||
}
|
||||
else if (i == curr_index - 1) {
|
||||
lnk_psrc = lnk;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(lnk_pdst && (!lnk_psrc || lnk_psrc->next))) {
|
||||
/* Invalid indices, abort. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (lnk_psrc) {
|
||||
lnk = lnk_psrc->next;
|
||||
lnk_psrc->next = lnk->next;
|
||||
}
|
||||
else {
|
||||
/* source is first element of the list... */
|
||||
lnk = *listp;
|
||||
*listp = lnk->next;
|
||||
}
|
||||
lnk->next = lnk_pdst->next;
|
||||
lnk_pdst->next = lnk;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A version of prepend that takes the allocated link.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user