BLI_listbase: add `BLI_swaplinks` which swaps given links' positions in given list.

Can be much simpler and quicker than using remlink/insert functions.
This commit is contained in:
Bastien Montagne 2014-10-21 11:56:46 +02:00
parent 62ceada48f
commit be4b2e42c6
2 changed files with 40 additions and 0 deletions

View File

@ -73,6 +73,8 @@ void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1);
int BLI_countlist(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1);
void BLI_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1, 2);
void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1, 2);
void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1, 2);
void BLI_listbase_reverse(struct ListBase *lb) ATTR_NONNULL(1);

View File

@ -129,6 +129,44 @@ bool BLI_remlink_safe(ListBase *listbase, void *vlink)
}
}
/**
* Swaps \a vlinka and \a vlinkb in the list. Assumes they are both already in the list!
*/
void BLI_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb)
{
Link *linka = vlinka;
Link *linkb = vlinkb;
if (!linka || !linkb)
return;
if (linkb->next == linka) {
SWAP(Link *, linka, linkb);
}
if (linka->next == linkb) {
linka->next = linkb->next;
linkb->prev = linka->prev;
linka->prev = linkb;
linkb->next = linka;
}
else { /* Non-contiguous items, we can safely swap. */
SWAP(Link *, linka->prev, linkb->prev);
SWAP(Link *, linka->next, linkb->next);
}
/* Update neighbors of linka and linkb. */
if (linka->prev) linka->prev->next = linka;
if (linka->next) linka->next->prev = linka;
if (linkb->prev) linkb->prev->next = linkb;
if (linkb->next) linkb->next->prev = linkb;
if (listbase->last == linka) listbase->last = linkb;
else if (listbase->last == linkb) listbase->last = linka;
if (listbase->first == linka) listbase->first = linkb;
else if (listbase->first == linkb) listbase->first = linka;
}
/**
* Removes the head from \a listbase and returns it.
*/