| 
									
										
										
										
											2012-04-27 07:26:28 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup bli | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-01-19 21:39:18 +11:00
										 |  |  |  * Manipulations on double-linked list (#ListBase structs). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * For single linked lists see 'BLI_linklist.h' | 
					
						
							| 
									
										
										
										
											2011-02-27 20:37:56 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_listBase.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_listbase.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 15:13:06 +10:00
										 |  |  | #include "BLI_strict_flags.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | /* implementation */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * moves the entire contents of \a src onto the end of \a dst. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-12-21 14:49:34 +00:00
										 |  |  | void BLI_movelisttolist(ListBase *dst, ListBase *src) | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (src->first == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   if (dst->first == NULL) { | 
					
						
							|  |  |  |     dst->first = src->first; | 
					
						
							|  |  |  |     dst->last = src->last; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     ((Link *)dst->last)->next = src->first; | 
					
						
							|  |  |  |     ((Link *)src->first)->prev = dst->last; | 
					
						
							|  |  |  |     dst->last = src->last; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   src->first = src->last = NULL; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-29 16:39:45 +02:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2019-04-10 00:06:53 +10:00
										 |  |  |  * moves the entire contents of \a src at the beginning of \a dst. | 
					
						
							| 
									
										
										
										
											2018-09-29 16:39:45 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | void BLI_movelisttolist_reverse(ListBase *dst, ListBase *src) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (src->first == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-09-29 16:39:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (dst->first == NULL) { | 
					
						
							|  |  |  |     dst->first = src->first; | 
					
						
							|  |  |  |     dst->last = src->last; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     ((Link *)src->last)->next = dst->first; | 
					
						
							|  |  |  |     ((Link *)dst->first)->prev = src->last; | 
					
						
							|  |  |  |     dst->first = src->first; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   src->first = src->last = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Prepends \a vlink (assumed to begin with a Link) onto listbase. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | void BLI_addhead(ListBase *listbase, void *vlink) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *link = vlink; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (link == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   link->next = listbase->first; | 
					
						
							|  |  |  |   link->prev = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (listbase->first) { | 
					
						
							|  |  |  |     ((Link *)listbase->first)->prev = link; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (listbase->last == NULL) { | 
					
						
							|  |  |  |     listbase->last = link; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   listbase->first = link; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Appends \a vlink (assumed to begin with a Link) onto listbase. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | void BLI_addtail(ListBase *listbase, void *vlink) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *link = vlink; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (link == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   link->next = NULL; | 
					
						
							|  |  |  |   link->prev = listbase->last; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (listbase->last) { | 
					
						
							|  |  |  |     ((Link *)listbase->last)->next = link; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (listbase->first == NULL) { | 
					
						
							|  |  |  |     listbase->first = link; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   listbase->last = link; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Removes \a vlink from \a listbase. Assumes it is linked into there! | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | void BLI_remlink(ListBase *listbase, void *vlink) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *link = vlink; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (link == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (link->next) { | 
					
						
							|  |  |  |     link->next->prev = link->prev; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (link->prev) { | 
					
						
							|  |  |  |     link->prev->next = link->next; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (listbase->last == link) { | 
					
						
							|  |  |  |     listbase->last = link->prev; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (listbase->first == link) { | 
					
						
							|  |  |  |     listbase->first = link->next; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Checks that \a vlink is linked into listbase, removing it from there if so. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | bool BLI_remlink_safe(ListBase *listbase, void *vlink) | 
					
						
							| 
									
										
										
											
												merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
											
										 
											2010-03-20 16:41:01 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  |   if (BLI_findindex(listbase, vlink) != -1) { | 
					
						
							| 
									
										
										
											
												merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
											
										 
											2010-03-20 16:41:01 +00:00
										 |  |  |     BLI_remlink(listbase, vlink); | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |     return true; | 
					
						
							| 
									
										
										
											
												merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
											
										 
											2010-03-20 16:41:01 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-07 11:23:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return false; | 
					
						
							| 
									
										
										
											
												merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
											
										 
											2010-03-20 16:41:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-21 11:56:46 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Swaps \a vlinka and \a vlinkb in the list. Assumes they are both already in the list! | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-10-21 14:06:16 +02:00
										 |  |  | void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) | 
					
						
							| 
									
										
										
										
											2014-10-21 11:56:46 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   Link *linka = vlinka; | 
					
						
							|  |  |  |   Link *linkb = vlinkb; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (!linka || !linkb) { | 
					
						
							| 
									
										
										
										
											2014-10-21 11:56:46 +02:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-21 11:56:46 +02:00
										 |  |  |   if (linkb->next == linka) { | 
					
						
							|  |  |  |     SWAP(Link *, linka, linkb); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-21 11:56:46 +02:00
										 |  |  |   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); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-21 11:56:46 +02:00
										 |  |  |   /* Update neighbors of linka and linkb. */ | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   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; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (listbase->last == linka) { | 
					
						
							|  |  |  |     listbase->last = linkb; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (listbase->last == linkb) { | 
					
						
							|  |  |  |     listbase->last = linka; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (listbase->first == linka) { | 
					
						
							|  |  |  |     listbase->first = linkb; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (listbase->first == linkb) { | 
					
						
							|  |  |  |     listbase->first = linka; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-10-21 11:56:46 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-14 16:10:48 +11:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2019-04-22 00:54:27 +10:00
										 |  |  |  * Swaps \a vlinka and \a vlinkb from their respective lists. | 
					
						
							| 
									
										
										
										
											2020-09-07 15:57:12 +10:00
										 |  |  |  * Assumes they are both already in their \a listbasea! | 
					
						
							| 
									
										
										
										
											2017-11-14 16:10:48 +11:00
										 |  |  |  */ | 
					
						
							|  |  |  | void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vlinka, void *vlinkb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *linka = vlinka; | 
					
						
							|  |  |  |   Link *linkb = vlinkb; | 
					
						
							|  |  |  |   Link linkc = {NULL}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!linka || !linkb) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Temporary link to use as placeholder of the links positions */ | 
					
						
							|  |  |  |   BLI_insertlinkafter(listbasea, linka, &linkc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Bring linka into linkb position */ | 
					
						
							|  |  |  |   BLI_remlink(listbasea, linka); | 
					
						
							|  |  |  |   BLI_insertlinkafter(listbaseb, linkb, linka); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Bring linkb into linka position */ | 
					
						
							|  |  |  |   BLI_remlink(listbaseb, linkb); | 
					
						
							|  |  |  |   BLI_insertlinkafter(listbasea, &linkc, linkb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Remove temporary link */ | 
					
						
							|  |  |  |   BLI_remlink(listbasea, &linkc); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-26 23:37:08 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Removes the head from \a listbase and returns it. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void *BLI_pophead(ListBase *listbase) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *link; | 
					
						
							|  |  |  |   if ((link = listbase->first)) { | 
					
						
							|  |  |  |     BLI_remlink(listbase, link); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return link; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Removes the tail from \a listbase and returns it. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void *BLI_poptail(ListBase *listbase) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *link; | 
					
						
							|  |  |  |   if ((link = listbase->last)) { | 
					
						
							|  |  |  |     BLI_remlink(listbase, link); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return link; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Removes \a vlink from listbase and disposes of it. Assumes it is linked into there! | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | void BLI_freelinkN(ListBase *listbase, void *vlink) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *link = vlink; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (link == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-29 15:47:02 +00:00
										 |  |  |   BLI_remlink(listbase, link); | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   MEM_freeN(link); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 15:13:06 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Assigns all #Link.prev pointers from #Link.next | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void listbase_double_from_single(Link *iter, ListBase *listbase) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *prev = NULL; | 
					
						
							|  |  |  |   listbase->first = iter; | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     iter->prev = prev; | 
					
						
							|  |  |  |     prev = iter; | 
					
						
							|  |  |  |   } while ((iter = iter->next)); | 
					
						
							|  |  |  |   listbase->last = prev; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define SORT_IMPL_LINKTYPE Link
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* regular call */ | 
					
						
							|  |  |  | #define SORT_IMPL_FUNC listbase_sort_fn
 | 
					
						
							|  |  |  | #include "list_sort_impl.h"
 | 
					
						
							|  |  |  | #undef SORT_IMPL_FUNC
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-30 17:06:28 +10:00
										 |  |  | /* re-entrant call */ | 
					
						
							| 
									
										
										
										
											2015-06-11 15:13:06 +10:00
										 |  |  | #define SORT_IMPL_USE_THUNK
 | 
					
						
							|  |  |  | #define SORT_IMPL_FUNC listbase_sort_fn_r
 | 
					
						
							|  |  |  | #include "list_sort_impl.h"
 | 
					
						
							|  |  |  | #undef SORT_IMPL_FUNC
 | 
					
						
							|  |  |  | #undef SORT_IMPL_USE_THUNK
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef SORT_IMPL_LINKTYPE
 | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Sorts the elements of listbase into the order defined by cmp | 
					
						
							| 
									
										
										
										
											2015-05-23 22:02:03 +10:00
										 |  |  |  * (which should return 1 if its first arg should come after its second arg). | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |  * This uses insertion sort, so NOT ok for large list. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-16 13:57:58 +01:00
										 |  |  | void BLI_listbase_sort(ListBase *listbase, int (*cmp)(const void *, const void *)) | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-06 18:40:15 +00:00
										 |  |  |   if (listbase->first != listbase->last) { | 
					
						
							| 
									
										
										
										
											2015-06-11 15:13:06 +10:00
										 |  |  |     Link *head = listbase->first; | 
					
						
							|  |  |  |     head = listbase_sort_fn(head, cmp); | 
					
						
							|  |  |  |     listbase_double_from_single(head, listbase); | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 15:07:14 +10:00
										 |  |  | void BLI_listbase_sort_r(ListBase *listbase, | 
					
						
							|  |  |  |                          int (*cmp)(void *, const void *, const void *), | 
					
						
							|  |  |  |                          void *thunk) | 
					
						
							| 
									
										
										
										
											2014-02-13 13:08:05 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   if (listbase->first != listbase->last) { | 
					
						
							| 
									
										
										
										
											2015-06-11 15:13:06 +10:00
										 |  |  |     Link *head = listbase->first; | 
					
						
							|  |  |  |     head = listbase_sort_fn_r(head, cmp, thunk); | 
					
						
							|  |  |  |     listbase_double_from_single(head, listbase); | 
					
						
							| 
									
										
										
										
											2014-02-13 13:08:05 +11:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Inserts \a vnewlink immediately following \a vprevlink in \a listbase. | 
					
						
							|  |  |  |  * Or, if \a vprevlink is NULL, puts \a vnewlink at the front of the list. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *prevlink = vprevlink; | 
					
						
							|  |  |  |   Link *newlink = vnewlink; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* newlink before nextlink */ | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (newlink == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* empty list */ | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  |   if (listbase->first == NULL) { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     listbase->first = newlink; | 
					
						
							|  |  |  |     listbase->last = newlink; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-06-17 16:32:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   /* insert at head of list */ | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  |   if (prevlink == NULL) { | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |     newlink->prev = NULL; | 
					
						
							|  |  |  |     newlink->next = listbase->first; | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |     newlink->next->prev = newlink; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |     listbase->first = newlink; | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* at end of list */ | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |   if (listbase->last == prevlink) { | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |     listbase->last = newlink; | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   newlink->next = prevlink->next; | 
					
						
							|  |  |  |   newlink->prev = prevlink; | 
					
						
							|  |  |  |   prevlink->next = newlink; | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |   if (newlink->next) { | 
					
						
							|  |  |  |     newlink->next->prev = newlink; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Inserts \a vnewlink immediately preceding \a vnextlink in listbase. | 
					
						
							|  |  |  |  * Or, if \a vnextlink is NULL, puts \a vnewlink at the end of the list. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *nextlink = vnextlink; | 
					
						
							|  |  |  |   Link *newlink = vnewlink; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* newlink before nextlink */ | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (newlink == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* empty list */ | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  |   if (listbase->first == NULL) { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     listbase->first = newlink; | 
					
						
							|  |  |  |     listbase->last = newlink; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-06-17 16:32:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   /* insert at end of list */ | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  |   if (nextlink == NULL) { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     newlink->prev = listbase->last; | 
					
						
							|  |  |  |     newlink->next = NULL; | 
					
						
							|  |  |  |     ((Link *)listbase->last)->next = newlink; | 
					
						
							|  |  |  |     listbase->last = newlink; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* at beginning of list */ | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |   if (listbase->first == nextlink) { | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |     listbase->first = newlink; | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   newlink->next = nextlink; | 
					
						
							|  |  |  |   newlink->prev = nextlink->prev; | 
					
						
							|  |  |  |   nextlink->prev = newlink; | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |   if (newlink->prev) { | 
					
						
							|  |  |  |     newlink->prev->next = newlink; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-09 16:07:09 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Insert a link in place of another, without changing its position in the list. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Puts `vnewlink` in the position of `vreplacelink`, removing `vreplacelink`. | 
					
						
							|  |  |  |  * - `vreplacelink` *must* be in the list. | 
					
						
							|  |  |  |  * - `vnewlink` *must not* be in the list. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *l_old = vreplacelink; | 
					
						
							|  |  |  |   Link *l_new = vnewlink; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* update adjacent links */ | 
					
						
							|  |  |  |   if (l_old->next != NULL) { | 
					
						
							|  |  |  |     l_old->next->prev = l_new; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (l_old->prev != NULL) { | 
					
						
							|  |  |  |     l_old->prev->next = l_new; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* set direct links */ | 
					
						
							|  |  |  |   l_new->next = l_old->next; | 
					
						
							|  |  |  |   l_new->prev = l_old->prev; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* update list */ | 
					
						
							|  |  |  |   if (listbase->first == l_old) { | 
					
						
							|  |  |  |     listbase->first = l_new; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (listbase->last == l_old) { | 
					
						
							|  |  |  |     listbase->last = l_new; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 21:36:34 +02:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2016-09-18 21:54:24 +02:00
										 |  |  |  * Reinsert \a vlink relative to its current position but offset by \a step. Doesn't move | 
					
						
							| 
									
										
										
										
											2016-09-18 21:36:34 +02:00
										 |  |  |  * item if new position would exceed list (could optionally move to head/tail). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \param step: Absolute value defines step size, sign defines direction. E.g pass -1 | 
					
						
							| 
									
										
										
										
											2016-09-18 21:54:24 +02:00
										 |  |  |  *              to move \a vlink before previous, or 1 to move behind next. | 
					
						
							|  |  |  |  * \return If position of \a vlink has changed. | 
					
						
							| 
									
										
										
										
											2016-09-18 21:36:34 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *link = vlink; | 
					
						
							|  |  |  |   Link *hook = link; | 
					
						
							|  |  |  |   const bool is_up = step < 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-19 10:18:10 +02:00
										 |  |  |   if (step == 0) { | 
					
						
							| 
									
										
										
										
											2016-09-18 21:36:34 +02:00
										 |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   BLI_assert(BLI_findindex(listbase, link) != -1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* find link to insert before/after */ | 
					
						
							| 
									
										
										
										
											2020-03-06 17:18:10 +01:00
										 |  |  |   const int abs_step = abs(step); | 
					
						
							|  |  |  |   for (int i = 0; i < abs_step; i++) { | 
					
						
							| 
									
										
										
										
											2016-09-18 21:36:34 +02:00
										 |  |  |     hook = is_up ? hook->prev : hook->next; | 
					
						
							|  |  |  |     if (!hook) { | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* reinsert link */ | 
					
						
							|  |  |  |   BLI_remlink(listbase, vlink); | 
					
						
							|  |  |  |   if (is_up) { | 
					
						
							|  |  |  |     BLI_insertlinkbefore(listbase, hook, vlink); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     BLI_insertlinkafter(listbase, hook, vlink); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 22:09:57 +03:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Move the link at the index \a from to the position at index \a to. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-09-05 12:56:55 +10:00
										 |  |  |  * \return If the move was successful. | 
					
						
							| 
									
										
										
										
											2019-09-04 22:09:57 +03:00
										 |  |  |  */ | 
					
						
							|  |  |  | bool BLI_listbase_move_index(ListBase *listbase, int from, int to) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (from == to) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Find the link to move. */ | 
					
						
							|  |  |  |   void *link = BLI_findlink(listbase, from); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!link) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return BLI_listbase_link_move(listbase, link, to - from); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Removes and disposes of the entire contents of listbase using direct free(3). | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | void BLI_freelist(ListBase *listbase) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *link, *next; | 
					
						
							| 
									
										
										
										
											2018-06-17 16:32:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   link = listbase->first; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   while (link) { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     next = link->next; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |     free(link); | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     link = next; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-05-19 00:24:45 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   BLI_listbase_clear(listbase); | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Removes and disposes of the entire contents of \a listbase using guardedalloc. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | void BLI_freelistN(ListBase *listbase) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *link, *next; | 
					
						
							| 
									
										
										
										
											2018-06-17 16:32:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   link = listbase->first; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   while (link) { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     next = link->next; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |     MEM_freeN(link); | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     link = next; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-05-19 00:24:45 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   BLI_listbase_clear(listbase); | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-16 14:23:37 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the number of elements in \a listbase, up until (and including count_max) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \note Use to avoid redundant looping. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-04-03 17:05:21 +02:00
										 |  |  | int BLI_listbase_count_at_most(const ListBase *listbase, const int count_max) | 
					
						
							| 
									
										
										
										
											2014-11-16 14:02:18 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   Link *link; | 
					
						
							|  |  |  |   int count = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (link = listbase->first; link && count != count_max; link = link->next) { | 
					
						
							|  |  |  |     count++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return count; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the number of elements in \a listbase. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-16 13:57:58 +01:00
										 |  |  | int BLI_listbase_count(const ListBase *listbase) | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Link *link; | 
					
						
							|  |  |  |   int count = 0; | 
					
						
							| 
									
										
										
										
											2014-11-16 14:02:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   for (link = listbase->first; link; link = link->next) { | 
					
						
							|  |  |  |     count++; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-11-16 14:02:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   return count; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-08-05 10:33:24 -04:00
										 |  |  |  * Returns the nth element of \a listbase, numbering from 0. | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-12-21 14:49:34 +00:00
										 |  |  | void *BLI_findlink(const ListBase *listbase, int number) | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Link *link = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (number >= 0) { | 
					
						
							|  |  |  |     link = listbase->first; | 
					
						
							|  |  |  |     while (link != NULL && number != 0) { | 
					
						
							|  |  |  |       number--; | 
					
						
							|  |  |  |       link = link->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return link; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-08-05 10:33:24 -04:00
										 |  |  |  * Returns the nth-last element of \a listbase, numbering from 0. | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2012-03-03 22:07:58 +00:00
										 |  |  | void *BLI_rfindlink(const ListBase *listbase, int number) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *link = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (number >= 0) { | 
					
						
							|  |  |  |     link = listbase->last; | 
					
						
							|  |  |  |     while (link != NULL && number != 0) { | 
					
						
							|  |  |  |       number--; | 
					
						
							|  |  |  |       link = link->prev; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return link; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-08-05 10:33:24 -04:00
										 |  |  |  * Returns the position of \a vlink within \a listbase, numbering from 0, or -1 if not found. | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2012-12-15 04:44:10 +00:00
										 |  |  | int BLI_findindex(const ListBase *listbase, const void *vlink) | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *link = NULL; | 
					
						
							|  |  |  |   int number = 0; | 
					
						
							| 
									
										
										
										
											2013-05-30 19:05:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (vlink == NULL) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-06-17 16:32:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   link = listbase->first; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   while (link) { | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |     if (link == vlink) { | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |       return number; | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-06-17 16:32:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |     number++; | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     link = link->next; | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-06-17 16:32:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  |   return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Finds the first element of \a listbase which contains the null-terminated | 
					
						
							|  |  |  |  * string \a id at the specified offset, returning NULL if not found. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-12-21 14:49:34 +00:00
										 |  |  | void *BLI_findstring(const ListBase *listbase, const char *id, const int offset) | 
					
						
							| 
									
										
										
										
											2009-12-29 15:40:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *link = NULL; | 
					
						
							| 
									
										
										
										
											2009-12-29 15:40:26 +00:00
										 |  |  |   const char *id_iter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (id == NULL) { | 
					
						
							| 
									
										
										
										
											2018-07-31 10:22:19 +02:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-31 10:22:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   for (link = listbase->first; link; link = link->next) { | 
					
						
							|  |  |  |     id_iter = ((const char *)link) + offset; | 
					
						
							| 
									
										
										
										
											2009-12-29 15:47:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  |     if (id[0] == id_iter[0] && STREQ(id, id_iter)) { | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  |       return link; | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* same as above but find reverse */ | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Finds the last element of \a listbase which contains the | 
					
						
							|  |  |  |  * null-terminated string \a id at the specified offset, returning NULL if not found. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  | void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *link = NULL; | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  |   const char *id_iter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   for (link = listbase->last; link; link = link->prev) { | 
					
						
							|  |  |  |     id_iter = ((const char *)link) + offset; | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  |     if (id[0] == id_iter[0] && STREQ(id, id_iter)) { | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  |       return link; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Finds the first element of \a listbase which contains a pointer to the | 
					
						
							|  |  |  |  * null-terminated string \a id at the specified offset, returning NULL if not found. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-12-21 14:49:34 +00:00
										 |  |  | void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int offset) | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *link = NULL; | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  |   const char *id_iter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   for (link = listbase->first; link; link = link->next) { | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  |     /* exact copy of BLI_findstring(), except for this line */ | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     id_iter = *((const char **)(((const char *)link) + offset)); | 
					
						
							| 
									
										
										
										
											2010-08-13 06:30:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  |     if (id[0] == id_iter[0] && STREQ(id, id_iter)) { | 
					
						
							| 
									
										
										
										
											2009-12-29 15:40:26 +00:00
										 |  |  |       return link; | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-12-29 15:40:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* same as above but find reverse */ | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Finds the last element of \a listbase which contains a pointer to the | 
					
						
							|  |  |  |  * null-terminated string \a id at the specified offset, returning NULL if not found. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  | void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int offset) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *link = NULL; | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  |   const char *id_iter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   for (link = listbase->last; link; link = link->prev) { | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  |     /* exact copy of BLI_rfindstring(), except for this line */ | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     id_iter = *((const char **)(((const char *)link) + offset)); | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  |     if (id[0] == id_iter[0] && STREQ(id, id_iter)) { | 
					
						
							| 
									
										
										
										
											2011-05-02 13:35:04 +00:00
										 |  |  |       return link; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-12-29 15:40:26 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-18 16:16:13 +00:00
										 |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-08 04:39:09 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Finds the first element of listbase which contains the specified pointer value | 
					
						
							|  |  |  |  * at the specified offset, returning NULL if not found. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2012-08-18 16:16:13 +00:00
										 |  |  | void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *link = NULL; | 
					
						
							|  |  |  |   const void *ptr_iter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (link = listbase->first; link; link = link->next) { | 
					
						
							|  |  |  |     /* exact copy of BLI_findstring(), except for this line */ | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |     ptr_iter = *((const void **)(((const char *)link) + offset)); | 
					
						
							| 
									
										
										
										
											2012-08-18 16:16:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (ptr == ptr_iter) { | 
					
						
							|  |  |  |       return link; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* same as above but find reverse */ | 
					
						
							| 
									
										
										
										
											2013-04-08 04:39:09 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Finds the last element of listbase which contains the specified pointer value | 
					
						
							|  |  |  |  * at the specified offset, returning NULL if not found. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2012-08-18 16:16:13 +00:00
										 |  |  | void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *link = NULL; | 
					
						
							|  |  |  |   const void *ptr_iter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (link = listbase->last; link; link = link->prev) { | 
					
						
							|  |  |  |     /* exact copy of BLI_rfindstring(), except for this line */ | 
					
						
							| 
									
										
										
										
											2013-02-22 14:12:55 +00:00
										 |  |  |     ptr_iter = *((const void **)(((const char *)link) + offset)); | 
					
						
							| 
									
										
										
										
											2012-08-18 16:16:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (ptr == ptr_iter) { | 
					
						
							|  |  |  |       return link; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-29 15:40:26 +00:00
										 |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-16 12:49:31 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Finds the first element of listbase which contains the specified bytes | 
					
						
							|  |  |  |  * at the specified offset, returning NULL if not found. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void *BLI_listbase_bytes_find(const ListBase *listbase, | 
					
						
							|  |  |  |                               const void *bytes, | 
					
						
							|  |  |  |                               const size_t bytes_size, | 
					
						
							|  |  |  |                               const int offset) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *link = NULL; | 
					
						
							|  |  |  |   const void *ptr_iter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (link = listbase->first; link; link = link->next) { | 
					
						
							|  |  |  |     ptr_iter = (const void *)(((const char *)link) + offset); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (memcmp(bytes, ptr_iter, bytes_size) == 0) { | 
					
						
							|  |  |  |       return link; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* same as above but find reverse */ | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Finds the last element of listbase which contains the specified bytes | 
					
						
							|  |  |  |  * at the specified offset, returning NULL if not found. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void *BLI_listbase_bytes_rfind(const ListBase *listbase, | 
					
						
							|  |  |  |                                const void *bytes, | 
					
						
							|  |  |  |                                const size_t bytes_size, | 
					
						
							|  |  |  |                                const int offset) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Link *link = NULL; | 
					
						
							|  |  |  |   const void *ptr_iter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (link = listbase->last; link; link = link->prev) { | 
					
						
							|  |  |  |     ptr_iter = (const void *)(((const char *)link) + offset); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (memcmp(bytes, ptr_iter, bytes_size) == 0) { | 
					
						
							|  |  |  |       return link; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-08 04:39:09 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2017-05-22 16:13:33 +02:00
										 |  |  |  * Returns the 0-based index of the first element of listbase which contains the specified | 
					
						
							| 
									
										
										
										
											2013-04-08 04:39:09 +00:00
										 |  |  |  * null-terminated string at the specified offset, or -1 if not found. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-12-21 14:49:34 +00:00
										 |  |  | int BLI_findstringindex(const ListBase *listbase, const char *id, const int offset) | 
					
						
							| 
									
										
										
										
											2010-02-02 21:43:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   Link *link = NULL; | 
					
						
							| 
									
										
										
										
											2010-02-02 21:43:26 +00:00
										 |  |  |   const char *id_iter; | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   int i = 0; | 
					
						
							| 
									
										
										
										
											2010-02-02 21:43:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   link = listbase->first; | 
					
						
							| 
									
										
										
										
											2010-02-02 21:43:26 +00:00
										 |  |  |   while (link) { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     id_iter = ((const char *)link) + offset; | 
					
						
							| 
									
										
										
										
											2010-02-02 21:43:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |     if (id[0] == id_iter[0] && STREQ(id, id_iter)) { | 
					
						
							| 
									
										
										
										
											2010-02-02 21:43:26 +00:00
										 |  |  |       return i; | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-02-02 21:43:26 +00:00
										 |  |  |     i++; | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     link = link->next; | 
					
						
							| 
									
										
										
										
											2010-02-02 21:43:26 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 12:18:12 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Sets dst to a duplicate of the entire contents of src. dst may be the same as src. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-12-21 14:49:34 +00:00
										 |  |  | void BLI_duplicatelist(ListBase *dst, const ListBase *src) | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-21 14:49:34 +00:00
										 |  |  |   struct Link *dst_link, *src_link; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* in this order, to ensure it works if dst == src */ | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   src_link = src->first; | 
					
						
							|  |  |  |   dst->first = dst->last = NULL; | 
					
						
							| 
									
										
										
										
											2010-12-21 14:49:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  |   while (src_link) { | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     dst_link = MEM_dupallocN(src_link); | 
					
						
							| 
									
										
										
										
											2010-12-21 14:49:34 +00:00
										 |  |  |     BLI_addtail(dst, dst_link); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |     src_link = src_link->next; | 
					
						
							| 
									
										
										
										
											2010-12-21 14:49:34 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-20 10:02:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 19:33:35 +10:00
										 |  |  | void BLI_listbase_reverse(ListBase *lb) | 
					
						
							| 
									
										
										
										
											2013-05-11 12:18:12 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   struct Link *curr = lb->first; | 
					
						
							|  |  |  |   struct Link *prev = NULL; | 
					
						
							|  |  |  |   struct Link *next = NULL; | 
					
						
							| 
									
										
										
										
											2013-05-14 06:58:35 +00:00
										 |  |  |   while (curr) { | 
					
						
							| 
									
										
										
										
											2013-05-11 12:18:12 +00:00
										 |  |  |     next = curr->next; | 
					
						
							|  |  |  |     curr->next = prev; | 
					
						
							|  |  |  |     curr->prev = next; | 
					
						
							|  |  |  |     prev = curr; | 
					
						
							|  |  |  |     curr = next; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* swap first/last */ | 
					
						
							|  |  |  |   curr = lb->first; | 
					
						
							|  |  |  |   lb->first = lb->last; | 
					
						
							|  |  |  |   lb->last = curr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2018-12-12 12:50:58 +11:00
										 |  |  |  * \param vlink: Link to make first. | 
					
						
							| 
									
										
										
										
											2013-05-11 12:18:12 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-07-30 15:01:16 +10:00
										 |  |  | void BLI_listbase_rotate_first(ListBase *lb, void *vlink) | 
					
						
							| 
									
										
										
										
											2013-05-11 12:18:12 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   /* make circular */ | 
					
						
							| 
									
										
										
										
											2013-09-05 11:40:38 +00:00
										 |  |  |   ((Link *)lb->first)->prev = lb->last; | 
					
						
							|  |  |  |   ((Link *)lb->last)->next = lb->first; | 
					
						
							| 
									
										
										
										
											2013-05-11 12:18:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   lb->first = vlink; | 
					
						
							| 
									
										
										
										
											2013-09-05 11:40:38 +00:00
										 |  |  |   lb->last = ((Link *)vlink)->prev; | 
					
						
							| 
									
										
										
										
											2013-05-11 12:18:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-05 11:40:38 +00:00
										 |  |  |   ((Link *)lb->first)->prev = NULL; | 
					
						
							|  |  |  |   ((Link *)lb->last)->next = NULL; | 
					
						
							| 
									
										
										
										
											2013-05-11 12:18:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-05 11:40:38 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2018-12-12 12:50:58 +11:00
										 |  |  |  * \param vlink: Link to make last. | 
					
						
							| 
									
										
										
										
											2013-09-05 11:40:38 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-07-30 15:01:16 +10:00
										 |  |  | void BLI_listbase_rotate_last(ListBase *lb, void *vlink) | 
					
						
							| 
									
										
										
										
											2013-09-05 11:40:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   /* make circular */ | 
					
						
							|  |  |  |   ((Link *)lb->first)->prev = lb->last; | 
					
						
							|  |  |  |   ((Link *)lb->last)->next = lb->first; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   lb->first = ((Link *)vlink)->next; | 
					
						
							|  |  |  |   lb->last = vlink; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ((Link *)lb->first)->prev = NULL; | 
					
						
							|  |  |  |   ((Link *)lb->last)->next = NULL; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-05-11 12:18:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-17 10:14:56 +00:00
										 |  |  | /* create a generic list node containing link to provided data */ | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  | LinkData *BLI_genericNodeN(void *data) | 
					
						
							| 
									
										
										
										
											2009-09-17 10:14:56 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   LinkData *ld; | 
					
						
							| 
									
										
										
										
											2018-06-17 16:32:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   if (data == NULL) { | 
					
						
							| 
									
										
										
										
											2009-09-17 10:14:56 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-03-27 13:16:10 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-06-17 16:32:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-17 10:14:56 +00:00
										 |  |  |   /* create new link, and make it hold the given data */ | 
					
						
							| 
									
										
										
										
											2013-05-12 05:54:33 +00:00
										 |  |  |   ld = MEM_callocN(sizeof(LinkData), __func__); | 
					
						
							| 
									
										
										
										
											2012-05-12 15:13:06 +00:00
										 |  |  |   ld->data = data; | 
					
						
							| 
									
										
										
										
											2018-06-17 16:32:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-17 10:14:56 +00:00
										 |  |  |   return ld; | 
					
						
							| 
									
										
										
										
											2018-06-17 16:32:54 +02:00
										 |  |  | } |