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