Blender V5.0
listbase.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12
13#include <cstdlib>
14#include <cstring>
15
16#include "MEM_guardedalloc.h"
17
18#include "DNA_listBase.h"
19
20#include "BLI_assert.h"
21#include "BLI_listbase.h"
22
23#include "BLI_strict_flags.h" /* IWYU pragma: keep. Keep last. */
24
26{
27 if (src->first == nullptr) {
28 return;
29 }
30
31 if (dst->first == nullptr) {
32 dst->first = src->first;
33 dst->last = src->last;
34 }
35 else {
36 ((Link *)dst->last)->next = static_cast<Link *>(src->first);
37 ((Link *)src->first)->prev = static_cast<Link *>(dst->last);
38 dst->last = src->last;
39 }
40 src->first = src->last = nullptr;
41}
42
44{
45 if (src->first == nullptr) {
46 return;
47 }
48
49 if (dst->first == nullptr) {
50 dst->first = src->first;
51 dst->last = src->last;
52 }
53 else {
54 ((Link *)src->last)->next = static_cast<Link *>(dst->first);
55 ((Link *)dst->first)->prev = static_cast<Link *>(src->last);
56 dst->first = src->first;
57 }
58
59 src->first = src->last = nullptr;
60}
61
62void BLI_listbase_split_after(ListBase *original_listbase, ListBase *split_listbase, void *vlink)
63{
64 BLI_assert(BLI_listbase_is_empty(split_listbase));
65 BLI_assert(vlink == nullptr || BLI_findindex(original_listbase, vlink) >= 0);
66
67 if (vlink == original_listbase->last) {
68 /* Nothing to split, and `split_listbase` is assumed already empty (see assert above). */
69 return;
70 }
71
72 if (vlink == nullptr) {
73 /* Move everything into `split_listbase`. */
74 std::swap(*original_listbase, *split_listbase);
75 return;
76 }
77
78 Link *link = static_cast<Link *>(vlink);
79 Link *next_link = link->next;
80 BLI_assert(next_link != nullptr);
81 Link *last_link = static_cast<Link *>(original_listbase->last);
82
83 original_listbase->last = link;
84 split_listbase->first = next_link;
85 split_listbase->last = last_link;
86
87 link->next = nullptr;
88 next_link->prev = nullptr;
89}
90
91void BLI_addhead(ListBase *listbase, void *vlink)
92{
93 Link *link = static_cast<Link *>(vlink);
94
95 if (link == nullptr) {
96 return;
97 }
98
99 link->next = static_cast<Link *>(listbase->first);
100 link->prev = nullptr;
101
102 if (listbase->first) {
103 ((Link *)listbase->first)->prev = link;
104 }
105 if (listbase->last == nullptr) {
106 listbase->last = link;
107 }
108 listbase->first = link;
109}
110
111void BLI_addtail(ListBase *listbase, void *vlink)
112{
113 Link *link = static_cast<Link *>(vlink);
114
115 if (link == nullptr) {
116 return;
117 }
118
119 link->next = nullptr;
120 link->prev = static_cast<Link *>(listbase->last);
121
122 if (listbase->last) {
123 ((Link *)listbase->last)->next = link;
124 }
125 if (listbase->first == nullptr) {
126 listbase->first = link;
127 }
128 listbase->last = link;
129}
130
131void BLI_remlink(ListBase *listbase, void *vlink)
132{
133 Link *link = static_cast<Link *>(vlink);
134
135 if (link == nullptr) {
136 return;
137 }
138
139 if (link->next) {
140 link->next->prev = link->prev;
141 }
142 if (link->prev) {
143 link->prev->next = link->next;
144 }
145
146 if (listbase->last == link) {
147 listbase->last = link->prev;
148 }
149 if (listbase->first == link) {
150 listbase->first = link->next;
151 }
152}
153
154bool BLI_remlink_safe(ListBase *listbase, void *vlink)
155{
156 if (BLI_findindex(listbase, vlink) != -1) {
157 BLI_remlink(listbase, vlink);
158 return true;
159 }
160
161 return false;
162}
163
164void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb)
165{
166 Link *linka = static_cast<Link *>(vlinka);
167 Link *linkb = static_cast<Link *>(vlinkb);
168
169 if (!linka || !linkb) {
170 return;
171 }
172
173 if (linkb->next == linka) {
174 std::swap(linka, linkb);
175 }
176
177 if (linka->next == linkb) {
178 linka->next = linkb->next;
179 linkb->prev = linka->prev;
180 linka->prev = linkb;
181 linkb->next = linka;
182 }
183 else { /* Non-contiguous items, we can safely swap. */
184 std::swap(linka->prev, linkb->prev);
185 std::swap(linka->next, linkb->next);
186 }
187
188 /* Update neighbors of linka and linkb. */
189 if (linka->prev) {
190 linka->prev->next = linka;
191 }
192 if (linka->next) {
193 linka->next->prev = linka;
194 }
195 if (linkb->prev) {
196 linkb->prev->next = linkb;
197 }
198 if (linkb->next) {
199 linkb->next->prev = linkb;
200 }
201
202 if (listbase->last == linka) {
203 listbase->last = linkb;
204 }
205 else if (listbase->last == linkb) {
206 listbase->last = linka;
207 }
208
209 if (listbase->first == linka) {
210 listbase->first = linkb;
211 }
212 else if (listbase->first == linkb) {
213 listbase->first = linka;
214 }
215}
216
217void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vlinka, void *vlinkb)
218{
219 Link *linka = static_cast<Link *>(vlinka);
220 Link *linkb = static_cast<Link *>(vlinkb);
221 Link linkc = {nullptr};
222
223 if (!linka || !linkb) {
224 return;
225 }
226
227 /* The reference to `linkc` assigns nullptr, not a dangling pointer so it can be ignored. */
228#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 1201 /* gcc12.1+ only */
229# pragma GCC diagnostic push
230# pragma GCC diagnostic ignored "-Wdangling-pointer"
231#endif
232
233 /* Temporary link to use as placeholder of the links positions */
234 BLI_insertlinkafter(listbasea, linka, &linkc);
235
236#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 1201 /* gcc12.1+ only */
237# pragma GCC diagnostic pop
238#endif
239
240 /* Bring linka into linkb position */
241 BLI_remlink(listbasea, linka);
242 BLI_insertlinkafter(listbaseb, linkb, linka);
243
244 /* Bring linkb into linka position */
245 BLI_remlink(listbaseb, linkb);
246 BLI_insertlinkafter(listbasea, &linkc, linkb);
247
248 /* Remove temporary link */
249 BLI_remlink(listbasea, &linkc);
250}
251
252void *BLI_pophead(ListBase *listbase)
253{
254 Link *link = static_cast<Link *>(listbase->first);
255 if (link) {
256 BLI_remlink(listbase, link);
257 }
258 return link;
259}
260
261void *BLI_poptail(ListBase *listbase)
262{
263 Link *link = static_cast<Link *>(listbase->last);
264 if (link) {
265 BLI_remlink(listbase, link);
266 }
267 return link;
268}
269
270void BLI_freelinkN(ListBase *listbase, void *vlink)
271{
272 Link *link = static_cast<Link *>(vlink);
273
274 if (link == nullptr) {
275 return;
276 }
277
278 BLI_remlink(listbase, link);
279 MEM_freeN(link);
280}
281
285static void listbase_double_from_single(Link *iter, ListBase *listbase)
286{
287 Link *prev = nullptr;
288 listbase->first = iter;
289 do {
290 iter->prev = prev;
291 prev = iter;
292 } while ((iter = iter->next));
293 listbase->last = prev;
294}
295
296#define SORT_IMPL_LINKTYPE Link
297
298/* regular call */
299#define SORT_IMPL_FUNC listbase_sort_fn
300#include "list_sort_impl.h"
301#undef SORT_IMPL_FUNC
302
303/* re-entrant call */
304#define SORT_IMPL_USE_THUNK
305#define SORT_IMPL_FUNC listbase_sort_fn_r
306#include "list_sort_impl.h"
307#undef SORT_IMPL_FUNC
308#undef SORT_IMPL_USE_THUNK
309
310#undef SORT_IMPL_LINKTYPE
311
312void BLI_listbase_sort(ListBase *listbase, int (*cmp)(const void *, const void *))
313{
314 if (listbase->first != listbase->last) {
315 Link *head = static_cast<Link *>(listbase->first);
316 head = listbase_sort_fn(head, cmp);
317 listbase_double_from_single(head, listbase);
318 }
319}
320
322 int (*cmp)(void *, const void *, const void *),
323 void *thunk)
324{
325 if (listbase->first != listbase->last) {
326 Link *head = static_cast<Link *>(listbase->first);
327 head = listbase_sort_fn_r(head, cmp, thunk);
328 listbase_double_from_single(head, listbase);
329 }
330}
331
332void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink)
333{
334 Link *prevlink = static_cast<Link *>(vprevlink);
335 Link *newlink = static_cast<Link *>(vnewlink);
336
337 /* newlink before nextlink */
338 if (newlink == nullptr) {
339 return;
340 }
341
342 /* empty list */
343 if (listbase->first == nullptr) {
344 listbase->first = newlink;
345 listbase->last = newlink;
346 return;
347 }
348
349 /* insert at head of list */
350 if (prevlink == nullptr) {
351 newlink->prev = nullptr;
352 newlink->next = static_cast<Link *>(listbase->first);
353 newlink->next->prev = newlink;
354 listbase->first = newlink;
355 return;
356 }
357
358 /* at end of list */
359 if (listbase->last == prevlink) {
360 listbase->last = newlink;
361 }
362
363 newlink->next = prevlink->next;
364 newlink->prev = prevlink;
365 prevlink->next = newlink;
366 if (newlink->next) {
367 newlink->next->prev = newlink;
368 }
369}
370
371void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
372{
373 Link *nextlink = static_cast<Link *>(vnextlink);
374 Link *newlink = static_cast<Link *>(vnewlink);
375
376 /* newlink before nextlink */
377 if (newlink == nullptr) {
378 return;
379 }
380
381 /* empty list */
382 if (listbase->first == nullptr) {
383 listbase->first = newlink;
384 listbase->last = newlink;
385 return;
386 }
387
388 /* insert at end of list */
389 if (nextlink == nullptr) {
390 newlink->prev = static_cast<Link *>(listbase->last);
391 newlink->next = nullptr;
392 ((Link *)listbase->last)->next = newlink;
393 listbase->last = newlink;
394 return;
395 }
396
397 /* at beginning of list */
398 if (listbase->first == nextlink) {
399 listbase->first = newlink;
400 }
401
402 newlink->next = nextlink;
403 newlink->prev = nextlink->prev;
404 nextlink->prev = newlink;
405 if (newlink->prev) {
406 newlink->prev->next = newlink;
407 }
408}
409
410void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink)
411{
412 Link *l_old = static_cast<Link *>(vreplacelink);
413 Link *l_new = static_cast<Link *>(vnewlink);
414
415 /* update adjacent links */
416 if (l_old->next != nullptr) {
417 l_old->next->prev = l_new;
418 }
419 if (l_old->prev != nullptr) {
420 l_old->prev->next = l_new;
421 }
422
423 /* set direct links */
424 l_new->next = l_old->next;
425 l_new->prev = l_old->prev;
426
427 /* update list */
428 if (listbase->first == l_old) {
429 listbase->first = l_new;
430 }
431 if (listbase->last == l_old) {
432 listbase->last = l_new;
433 }
434}
435
436bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step)
437{
438 Link *link = static_cast<Link *>(vlink);
439 Link *hook = link;
440 const bool is_up = step < 0;
441
442 if (step == 0) {
443 return false;
444 }
445 BLI_assert(BLI_findindex(listbase, link) != -1);
446
447 /* find link to insert before/after */
448 const int abs_step = abs(step);
449 for (int i = 0; i < abs_step; i++) {
450 hook = is_up ? hook->prev : hook->next;
451 if (!hook) {
452 return false;
453 }
454 }
455
456 /* reinsert link */
457 BLI_remlink(listbase, vlink);
458 if (is_up) {
459 BLI_insertlinkbefore(listbase, hook, vlink);
460 }
461 else {
462 BLI_insertlinkafter(listbase, hook, vlink);
463 }
464 return true;
465}
466
467bool BLI_listbase_move_index(ListBase *listbase, int from, int to)
468{
469 if (from == to) {
470 return false;
471 }
472
473 /* Find the link to move. */
474 void *link = BLI_findlink(listbase, from);
475
476 if (!link) {
477 return false;
478 }
479
480 return BLI_listbase_link_move(listbase, link, to - from);
481}
482
483void BLI_freelist(ListBase *listbase)
484{
485 Link *link, *next;
486
487 link = static_cast<Link *>(listbase->first);
488 while (link) {
489 next = link->next;
490 free(link);
491 link = next;
492 }
493
494 BLI_listbase_clear(listbase);
495}
496
497void BLI_freelistN(ListBase *listbase)
498{
499 Link *link, *next;
500
501 link = static_cast<Link *>(listbase->first);
502 while (link) {
503 next = link->next;
504 MEM_freeN(link);
505 link = next;
506 }
507
508 BLI_listbase_clear(listbase);
509}
510
511int BLI_listbase_count_at_most(const ListBase *listbase, const int count_max)
512{
513 Link *link;
514 int count = 0;
515
516 for (link = static_cast<Link *>(listbase->first); link && count != count_max; link = link->next)
517 {
518 count++;
519 }
520
521 return count;
522}
523
524int BLI_listbase_count(const ListBase *listbase)
525{
526 int count = 0;
527 LISTBASE_FOREACH (Link *, link, listbase) {
528 count++;
529 }
530
531 return count;
532}
533
534void *BLI_findlink(const ListBase *listbase, int number)
535{
536 Link *link = nullptr;
537
538 if (number >= 0) {
539 link = static_cast<Link *>(listbase->first);
540 while (link != nullptr && number != 0) {
541 number--;
542 link = link->next;
543 }
544 }
545
546 return link;
547}
548
549void *BLI_rfindlink(const ListBase *listbase, int number)
550{
551 Link *link = nullptr;
552
553 if (number >= 0) {
554 link = static_cast<Link *>(listbase->last);
555 while (link != nullptr && number != 0) {
556 number--;
557 link = link->prev;
558 }
559 }
560
561 return link;
562}
563
564void *BLI_findlinkfrom(Link *start, int step)
565{
566 Link *link = nullptr;
567
568 if (step >= 0) {
569 link = start;
570 while (link != nullptr && step != 0) {
571 step--;
572 link = link->next;
573 }
574 }
575 else {
576 link = start;
577 while (link != nullptr && step != 0) {
578 step++;
579 link = link->prev;
580 }
581 }
582
583 return link;
584}
585
586int BLI_findindex(const ListBase *listbase, const void *vlink)
587{
588 Link *link = nullptr;
589 int number = 0;
590
591 if (vlink == nullptr) {
592 return -1;
593 }
594
595 link = static_cast<Link *>(listbase->first);
596 while (link) {
597 if (link == vlink) {
598 return number;
599 }
600
601 number++;
602 link = link->next;
603 }
604
605 return -1;
606}
607
608void *BLI_findstring(const ListBase *listbase, const char *id, const int offset)
609{
610 const char *id_iter;
611
612 if (id == nullptr) {
613 return nullptr;
614 }
615
616 LISTBASE_FOREACH (Link *, link, listbase) {
617 id_iter = ((const char *)link) + offset;
618
619 if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
620 return link;
621 }
622 }
623
624 return nullptr;
625}
626void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset)
627{
628 /* Same as #BLI_findstring but find reverse. */
629 LISTBASE_FOREACH_BACKWARD (Link *, link, listbase) {
630 const char *id_iter = ((const char *)link) + offset;
631 if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
632 return link;
633 }
634 }
635
636 return nullptr;
637}
638void *BLI_listbase_findafter_string(Link *link, const char *id, const int offset)
639{
640 /* Same as #BLI_findstring but start searching after given link. */
641 for (link = link->next; link; link = link->next) {
642 const char *id_iter = ((const char *)link) + offset;
643 if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
644 return link;
645 }
646 }
647
648 return nullptr;
649}
650
651void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int offset)
652{
653 const char *id_iter;
654
655 LISTBASE_FOREACH (Link *, link, listbase) {
656 /* Exact copy of BLI_findstring(), except for this line, and the check for potential nullptr
657 * below. */
658 id_iter = *((const char **)(((const char *)link) + offset));
659 if (id_iter && id[0] == id_iter[0] && STREQ(id, id_iter)) {
660 return link;
661 }
662 }
663
664 return nullptr;
665}
666void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int offset)
667{
668 /* Same as #BLI_findstring_ptr but find reverse. */
669
670 const char *id_iter;
671
672 LISTBASE_FOREACH_BACKWARD (Link *, link, listbase) {
673 /* Exact copy of BLI_rfindstring(), except for this line, and the check for potential nullptr
674 * below. */
675 id_iter = *((const char **)(((const char *)link) + offset));
676 if (id_iter && id[0] == id_iter[0] && STREQ(id, id_iter)) {
677 return link;
678 }
679 }
680
681 return nullptr;
682}
683
684void *BLI_listbase_findafter_string_ptr(Link *link, const char *id, const int offset)
685{
686 const char *id_iter;
687
688 for (link = link->next; link; link = link->next) {
689 /* Exact copy of BLI_findstring(), except for this line, and the check for potential nullptr
690 * below. */
691 id_iter = *((const char **)(((const char *)link) + offset));
692 if (id_iter && id[0] == id_iter[0] && STREQ(id, id_iter)) {
693 return link;
694 }
695 }
696
697 return nullptr;
698}
699
700void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset)
701{
702 LISTBASE_FOREACH (Link *, link, listbase) {
703 /* Exact copy of #BLI_findstring(), except for this line. */
704 const void *ptr_iter = *((const void **)(((const char *)link) + offset));
705 if (ptr == ptr_iter) {
706 return link;
707 }
708 }
709 return nullptr;
710}
711void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset)
712{
713 /* Same as #BLI_findptr but find reverse. */
714 LISTBASE_FOREACH_BACKWARD (Link *, link, listbase) {
715 /* Exact copy of #BLI_rfindstring(), except for this line. */
716 const void *ptr_iter = *((const void **)(((const char *)link) + offset));
717
718 if (ptr == ptr_iter) {
719 return link;
720 }
721 }
722 return nullptr;
723}
724
725void *BLI_listbase_bytes_find(const ListBase *listbase,
726 const void *bytes,
727 const size_t bytes_size,
728 const int offset)
729{
730 LISTBASE_FOREACH (Link *, link, listbase) {
731 const void *ptr_iter = (const void *)(((const char *)link) + offset);
732 if (memcmp(bytes, ptr_iter, bytes_size) == 0) {
733 return link;
734 }
735 }
736
737 return nullptr;
738}
739void *BLI_listbase_bytes_rfind(const ListBase *listbase,
740 const void *bytes,
741 const size_t bytes_size,
742 const int offset)
743{
744 /* Same as #BLI_listbase_bytes_find but find reverse. */
745 LISTBASE_FOREACH_BACKWARD (Link *, link, listbase) {
746 const void *ptr_iter = (const void *)(((const char *)link) + offset);
747 if (memcmp(bytes, ptr_iter, bytes_size) == 0) {
748 return link;
749 }
750 }
751 return nullptr;
752}
753
755 const char *string,
756 const size_t string_offset,
757 const int index)
758{
759 Link *link = nullptr;
760 Link *link_at_index = nullptr;
761
762 int index_iter;
763 for (link = static_cast<Link *>(listbase->first), index_iter = 0; link;
764 link = link->next, index_iter++)
765 {
766 if (string != nullptr && string[0] != '\0') {
767 const char *string_iter = ((const char *)link) + string_offset;
768
769 if (string[0] == string_iter[0] && STREQ(string, string_iter)) {
770 return link;
771 }
772 }
773 if (index_iter == index) {
774 link_at_index = link;
775 }
776 }
777 return link_at_index;
778}
779
780int BLI_findstringindex(const ListBase *listbase, const char *id, const int offset)
781{
782 Link *link = nullptr;
783 const char *id_iter;
784 int i = 0;
785
786 link = static_cast<Link *>(listbase->first);
787 while (link) {
788 id_iter = ((const char *)link) + offset;
789
790 if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
791 return i;
792 }
793 i++;
794 link = link->next;
795 }
796
797 return -1;
798}
799
801{
802 ListBase list = {some_link, some_link};
803 if (some_link == nullptr) {
804 return list;
805 }
806
807 /* Find the first element. */
808 while (((Link *)list.first)->prev != nullptr) {
809 list.first = ((Link *)list.first)->prev;
810 }
811
812 /* Find the last element. */
813 while (((Link *)list.last)->next != nullptr) {
814 list.last = ((Link *)list.last)->next;
815 }
816
817 return list;
818}
819
820void BLI_duplicatelist(ListBase *dst, const ListBase *src)
821{
822 Link *dst_link, *src_link;
823
824 /* in this order, to ensure it works if dst == src */
825 src_link = static_cast<Link *>(src->first);
826 dst->first = dst->last = nullptr;
827
828 while (src_link) {
829 dst_link = static_cast<Link *>(MEM_dupallocN(src_link));
830 BLI_addtail(dst, dst_link);
831
832 src_link = src_link->next;
833 }
834}
835
837{
838 Link *curr = static_cast<Link *>(lb->first);
839 Link *prev = nullptr;
840 Link *next = nullptr;
841 while (curr) {
842 next = curr->next;
843 curr->next = prev;
844 curr->prev = next;
845 prev = curr;
846 curr = next;
847 }
848
849 /* swap first/last */
850 curr = static_cast<Link *>(lb->first);
851 lb->first = lb->last;
852 lb->last = curr;
853}
854
856{
857 /* make circular */
858 ((Link *)lb->first)->prev = static_cast<Link *>(lb->last);
859 ((Link *)lb->last)->next = static_cast<Link *>(lb->first);
860
861 lb->first = vlink;
862 lb->last = ((Link *)vlink)->prev;
863
864 ((Link *)lb->first)->prev = nullptr;
865 ((Link *)lb->last)->next = nullptr;
866}
867
868void BLI_listbase_rotate_last(ListBase *lb, void *vlink)
869{
870 /* make circular */
871 ((Link *)lb->first)->prev = static_cast<Link *>(lb->last);
872 ((Link *)lb->last)->next = static_cast<Link *>(lb->first);
873
874 lb->first = ((Link *)vlink)->next;
875 lb->last = vlink;
876
877 ((Link *)lb->first)->prev = nullptr;
878 ((Link *)lb->last)->next = nullptr;
879}
880
882{
883 if (lb->first == nullptr && lb->last == nullptr) {
884 /* Empty list. */
885 return true;
886 }
887 if (ELEM(nullptr, lb->first, lb->last)) {
888 /* If one of the pointer is null, but not this other, this is a corrupted listbase. */
889 return false;
890 }
891
892 /* Walk the list in bot directions to ensure all next & prev pointers are valid and consistent.
893 */
894 LISTBASE_FOREACH (Link *, lb_link, lb) {
895 if (lb_link == lb->first) {
896 if (lb_link->prev != nullptr) {
897 return false;
898 }
899 }
900 if (lb_link == lb->last) {
901 if (lb_link->next != nullptr) {
902 return false;
903 }
904 }
905 }
906 LISTBASE_FOREACH_BACKWARD (Link *, lb_link, lb) {
907 if (lb_link == lb->last) {
908 if (lb_link->next != nullptr) {
909 return false;
910 }
911 }
912 if (lb_link == lb->first) {
913 if (lb_link->prev != nullptr) {
914 return false;
915 }
916 }
917 }
918
919 return true;
920}
921
923{
924 LinkData *ld;
925
926 if (data == nullptr) {
927 return nullptr;
928 }
929
930 /* create new link, and make it hold the given data */
931 ld = MEM_callocN<LinkData>(__func__);
932 ld->data = data;
933
934 return ld;
935}
#define BLI_assert(a)
Definition BLI_assert.h:46
void BLI_kdtree_nd_ free(KDTree *tree)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
#define ELEM(...)
#define STREQ(a, b)
These structs are the foundation for all linked lists in the library system.
Read Guarded memory(de)allocation.
BMesh const char void * data
#define abs
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
int count
void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink)
Definition listbase.cc:332
void BLI_remlink(ListBase *listbase, void *vlink)
Definition listbase.cc:131
void * BLI_findlinkfrom(Link *start, int step)
Definition listbase.cc:564
void BLI_listbase_rotate_last(ListBase *lb, void *vlink)
Definition listbase.cc:868
bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step)
Definition listbase.cc:436
void BLI_listbase_reverse(ListBase *lb)
Definition listbase.cc:836
void BLI_movelisttolist_reverse(ListBase *dst, ListBase *src)
Definition listbase.cc:43
LinkData * BLI_genericNodeN(void *data)
Definition listbase.cc:922
void * BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset)
Definition listbase.cc:711
void BLI_freelist(ListBase *listbase)
Definition listbase.cc:483
void BLI_listbase_sort_r(ListBase *listbase, int(*cmp)(void *, const void *, const void *), void *thunk)
Definition listbase.cc:321
bool BLI_listbase_move_index(ListBase *listbase, int from, int to)
Definition listbase.cc:467
void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink)
Definition listbase.cc:410
void * BLI_listbase_bytes_find(const ListBase *listbase, const void *bytes, const size_t bytes_size, const int offset)
Definition listbase.cc:725
void BLI_addhead(ListBase *listbase, void *vlink)
Definition listbase.cc:91
void BLI_movelisttolist(ListBase *dst, ListBase *src)
Definition listbase.cc:25
void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
Definition listbase.cc:371
int BLI_findindex(const ListBase *listbase, const void *vlink)
Definition listbase.cc:586
void BLI_listbase_sort(ListBase *listbase, int(*cmp)(const void *, const void *))
Definition listbase.cc:312
void * BLI_poptail(ListBase *listbase)
Definition listbase.cc:261
void * BLI_listbase_findafter_string_ptr(Link *link, const char *id, const int offset)
Definition listbase.cc:684
void BLI_duplicatelist(ListBase *dst, const ListBase *src)
Definition listbase.cc:820
void * BLI_findstring(const ListBase *listbase, const char *id, const int offset)
Definition listbase.cc:608
void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb)
Definition listbase.cc:164
int BLI_listbase_count(const ListBase *listbase)
Definition listbase.cc:524
void * BLI_listbase_bytes_rfind(const ListBase *listbase, const void *bytes, const size_t bytes_size, const int offset)
Definition listbase.cc:739
void * BLI_findptr(const ListBase *listbase, const void *ptr, const int offset)
Definition listbase.cc:700
void * BLI_rfindstring(const ListBase *listbase, const char *id, const int offset)
Definition listbase.cc:626
void BLI_listbase_split_after(ListBase *original_listbase, ListBase *split_listbase, void *vlink)
Definition listbase.cc:62
void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vlinka, void *vlinkb)
Definition listbase.cc:217
void BLI_freelinkN(ListBase *listbase, void *vlink)
Definition listbase.cc:270
int BLI_findstringindex(const ListBase *listbase, const char *id, const int offset)
Definition listbase.cc:780
void BLI_freelistN(ListBase *listbase)
Definition listbase.cc:497
ListBase BLI_listbase_from_link(Link *some_link)
Definition listbase.cc:800
void * BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int offset)
Definition listbase.cc:666
void BLI_addtail(ListBase *listbase, void *vlink)
Definition listbase.cc:111
void * BLI_pophead(ListBase *listbase)
Definition listbase.cc:252
void * BLI_findlink(const ListBase *listbase, int number)
Definition listbase.cc:534
static void listbase_double_from_single(Link *iter, ListBase *listbase)
Definition listbase.cc:285
void * BLI_listbase_string_or_index_find(const ListBase *listbase, const char *string, const size_t string_offset, const int index)
Definition listbase.cc:754
void BLI_listbase_rotate_first(ListBase *lb, void *vlink)
Definition listbase.cc:855
void * BLI_rfindlink(const ListBase *listbase, int number)
Definition listbase.cc:549
bool BLI_remlink_safe(ListBase *listbase, void *vlink)
Definition listbase.cc:154
bool BLI_listbase_validate(ListBase *lb)
Definition listbase.cc:881
void * BLI_listbase_findafter_string(Link *link, const char *id, const int offset)
Definition listbase.cc:638
void * BLI_findstring_ptr(const ListBase *listbase, const char *id, const int offset)
Definition listbase.cc:651
int BLI_listbase_count_at_most(const ListBase *listbase, const int count_max)
Definition listbase.cc:511
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static ulong * next
void * data
void * last
void * first
i
Definition text_draw.cc:230
PointerRNA * ptr
Definition wm_files.cc:4238