Loading...
Searching...
No Matches
ListOpsTemplates.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2015-2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
30
31template<class IntListType>
32IntListType Foam::renumber
33(
34 const labelUList& oldToNew,
35 const IntListType& input
36)
37{
38 const label len = input.size();
39
40 IntListType output(len);
41 output.resize(len); // Consistent sizing (eg, DynamicList)
42
43 for (label i=0; i < len; ++i)
44 {
45 if (input[i] >= 0)
46 {
47 output[i] = oldToNew[input[i]];
48 }
49 }
50
51 return output;
52}
53
54
55template<class IntListType>
57(
58 const labelUList& oldToNew,
59 IntListType& input
60)
61{
62 const label len = input.size();
63
64 for (label i=0; i < len; ++i)
65 {
66 if (input[i] >= 0)
67 {
68 input[i] = oldToNew[input[i]];
69 }
70 }
71}
72
73
74template<class IntListType>
76(
77 const Map<label>& oldToNew,
78 IntListType& input
79)
80{
81 const label len = input.size();
82
83 for (label i = 0; i < len; ++i)
84 {
85 const auto fnd = oldToNew.cfind(input[i]);
86
87 if (fnd.good())
88 {
89 input[i] = fnd.val();
90 }
91 }
92}
93
94
95template<class ListType>
96ListType Foam::reorder
97(
98 const labelUList& oldToNew,
99 const ListType& input,
100 const bool prune
101)
102{
103 const label len = input.size();
104
105 ListType output(len);
106 output.resize(len); // Consistent sizing (eg, DynamicList)
107
108 label maxIdx = -1; // For pruning: The new size = maxIdx+1
109 for (label i=0; i < len; ++i)
110 {
111 const label newIdx = oldToNew[i];
112 if (newIdx >= 0)
113 {
114 // Could enforce (newIdx < len)
115 // ... or just rely on FULLDEBUG from UList
116
117 output[newIdx] = input[i];
118
119 if (maxIdx < newIdx)
120 {
121 maxIdx = newIdx;
122 }
123 }
124 else if (!prune)
125 {
126 output[i] = input[i];
127 }
128 }
129
130 if (prune)
131 {
132 output.resize(maxIdx+1);
134
135 return output;
136}
137
138
139template<class ListType>
141(
142 const labelUList& oldToNew,
143 ListType& inputOutput,
144 const bool prune
145)
146{
147 // NOTE: cannot use std::move() since we have no guarantee that
148 // the oldToNew map is unique (ie, shuffle)
149
150 // Use const reference to ensure we obtain the proper operator[]
151 // on lazy lists (eg, List<bool>, PackedList)
152
153 const ListType& input = inputOutput;
154 const label len = input.size();
155
156 ListType output(len);
157 output.resize(len); // Consistent sizing (eg, DynamicList)
158
159 label maxIdx = -1; // For pruning: The new size = maxIdx+1
160 for (label i=0; i < len; ++i)
161 {
162 const label newIdx = oldToNew[i];
163 if (newIdx >= 0)
164 {
165 // Could enforce (newIdx < len)
166 // ... or just rely on FULLDEBUG from UList
167
168 output[newIdx] = input[i];
169
170 if (maxIdx < newIdx)
171 {
172 maxIdx = newIdx;
173 }
174 }
175 else if (!prune)
176 {
177 output[i] = input[i];
178 }
179 }
180
181 if (prune)
182 {
183 output.resize(maxIdx+1);
184 }
185
186 inputOutput.transfer(output);
187}
188
189
190template<unsigned Width>
192(
193 const labelUList& oldToNew,
194 const PackedList<Width>& input,
195 const bool prune
196)
197{
198 const label len = input.size();
199
200 PackedList<Width> output(len);
201
202 label maxIdx = -1; // For pruning: The new size = maxIdx+1
203 for (label i=0; i < len; ++i)
204 {
205 const auto& val = input.get(i);
206
207 const label newIdx = oldToNew[i];
208
209 if (newIdx >= 0)
210 {
211 // Could enforce (newIdx < len)
212 // ... or just rely on FULLDEBUG from UList
213
214 output.set(newIdx, val);
215
216 if (maxIdx < newIdx)
217 {
218 maxIdx = newIdx;
219 }
220 }
221 else if (!prune)
222 {
223 output.set(i, val);
224 }
225 }
226
227 if (prune)
228 {
229 output.resize(maxIdx+1);
230 }
231
232 // Verify addresses (for movable refs)
233 // Info<< "reordered in " << name(input.cdata()) << nl
234 // << "reordered out " << name(output.cdata()) << nl;
235
236 return output;
237}
238
239
240template<unsigned Width>
242(
243 const labelUList& oldToNew,
244 PackedList<Width>& input,
245 const bool prune
246)
247{
248 input = Foam::reorder(oldToNew, input, prune);
250 // Verify address (for movable refs)
251 // Info<< "now have " << name(input.cdata()) << nl;
252}
253
254
255template<class Container>
257(
258 const labelUList& oldToNew,
259 Container& input
260)
261{
262 Container output(input.capacity());
263
264 for (auto iter = input.begin(); iter != input.end(); ++iter)
265 {
266 const label oldIdx = iter.key();
267 if (oldIdx >= 0)
268 {
269 // Could enforce (oldIdx < oldToNew.size())
270 // ... or just rely on FULLDEBUG from UList
271
272 output.insert(oldToNew[oldIdx], iter.val());
273 }
274 }
275
276 input.transfer(output);
277}
278
279
280template<class Container>
281Foam::label Foam::inplaceMapValue
282(
283 const labelUList& oldToNew,
284 Container& input
285)
286{
287 label nChanged = 0;
288
289 for (auto iter = input.begin(); iter != input.end(); ++iter)
290 {
291 const label oldIdx = iter.val();
292 if (oldIdx >= 0)
293 {
294 // Could enforce (oldIdx < oldToNew.size())
295 // ... or just rely on FULLDEBUG from UList
296
297 const label newIdx = oldToNew[oldIdx];
298
299 if (oldIdx != newIdx)
300 {
301 iter.val() = newIdx;
302 ++nChanged;
303 }
304 }
305 }
306
307 return nChanged;
308}
309
310
311template<class Container>
312Foam::label Foam::inplaceMapValue
313(
314 const Map<label>& mapper,
315 Container& input
316)
317{
318 if (mapper.empty())
319 {
320 return 0;
321 }
322
323 label nChanged = 0;
324
325 for (auto iter = input.begin(); iter != input.end(); ++iter)
326 {
327 label& value = iter.val();
328
329 auto mapIter = mapper.find(value);
330 if (mapIter.good() && value != mapIter.val())
331 {
332 value = mapIter.val();
333 ++nChanged;
334 }
335 }
336
337 return nChanged;
338}
339
340
341template<class T>
343(
344 const UList<T>& input
345)
346{
348 duplicateOrder(input, order, typename UList<T>::less(input));
349 return order;
350}
351
352
353template<class T>
355(
356 const UList<T>& input,
357 labelList& order
359{
360 duplicateOrder(input, order, typename UList<T>::less(input));
361}
362
363
364template<class T, class ListComparePredicate>
366(
367 const UList<T>& input,
368 labelList& order,
369 const ListComparePredicate& comp
370)
371{
372 if (input.size() < 2)
373 {
374 order.clear();
375 return;
376 }
377
378 Foam::sortedOrder(input, order, comp);
379
380 const label last = (order.size()-1);
381 label count = 0;
382 for (label i = 0; i < last; ++i)
383 {
384 if (input[order[i]] == input[order[i+1]])
385 {
386 order[count] = order[i];
387 ++count;
388 }
389 }
390 order.resize(count);
391}
392
393
394template<class T>
396(
397 const UList<T>& input
398)
399{
401 uniqueOrder(input, order, typename UList<T>::less(input));
402 return order;
403}
404
405
406template<class T>
408(
409 const UList<T>& input,
410 labelList& order
412{
413 uniqueOrder(input, order, typename UList<T>::less(input));
414}
415
416
417template<class T, class ListComparePredicate>
419(
420 const UList<T>& input,
421 labelList& order,
422 const ListComparePredicate& comp
423)
424{
425 Foam::sortedOrder(input, order, comp);
426
427 if (order.size() > 1)
428 {
429 const label last = (order.size()-1);
430 label count = 0;
431 for (label i = 0; i < last; ++i)
432 {
433 if (input[order[i]] != input[order[i+1]])
434 {
435 order[count++] = order[i];
436 }
437 }
438 order[count++] = order[last];
439 order.resize(count);
440 }
441}
442
443
444template<class T>
445Foam::List<T> Foam::uniqueSort(const UList<T>& input)
446{
447 List<T> output(input);
448
449 const label len = output.size();
450
451 if (len > 1)
452 {
453 Foam::stableSort(output);
454
455 label count = 0;
456 for (label i = 1; i < len; ++i)
457 {
458 if (output[count] != output[i])
459 {
460 output[++count] = output[i];
461 }
462 }
463
464 output.resize(count+1);
466
467 return output;
468}
469
470
471template<class ListType>
472void Foam::inplaceUniqueSort(ListType& input)
473{
475 (
476 input,
478 );
479}
480
481
482template<class ListType, class ListComparePredicate>
484(
485 ListType& input,
486 const ListComparePredicate& comp
487)
488{
489 labelList order;
490 uniqueOrder(input, order, comp);
491
492 const label len = order.size();
493
494 ListType output(len);
495 output.resize(len); // Consistent sizing (eg, DynamicList)
496
497 for (label i=0; i < len; ++i)
498 {
499 output[i] = std::move(input[order[i]]);
500 }
501
502 input.transfer(output);
503}
504
505
506template<class BoolListType, class T>
508(
509 const BoolListType& select,
510 const UList<T>& input,
511 const bool invert
512)
513{
514 // Note: select can have a different size (eg, labelHashSet)
515
516 const label len = input.size();
517
518 List<T> output(len);
519
520 label count = 0;
521
522 for (label i=0; i < len; ++i)
523 {
524 if (select[i] ? !invert : invert)
525 {
526 output[count] = input[i];
527 ++count;
528 }
529 }
530
531 output.resize(count);
532
533 return output;
534}
535
536
537template<class T>
539(
540 const bitSet& select,
541 const UList<T>& input,
542 const bool invert
543)
544{
545 const label len = input.size();
546
547 List<T> output;
548
549 label count = 0;
550
551 if (!invert)
552 {
553 output.resize(select.count());
554
555 for (const label i : select)
556 {
557 if (i >= len) break; // Avoid out of bounds (when select is longer)
558
559 output[count] = input[i];
560 ++count;
561 }
562 }
563 else
564 {
565 const label outlen = (select.size() - select.count());
566 output.resize(outlen);
567
568 for (label i=0; i < len; ++i)
569 {
570 if (!select[i])
571 {
572 output[count] = input[i];
573 ++count;
574 if (count >= outlen) break; // terminate early
575 }
576 }
577 }
578
579 output.resize(count);
580
581 return output;
582}
583
584
585template<class BoolListType, class ListType>
587(
588 const BoolListType& select,
589 ListType& input,
590 const bool invert
591)
592{
593 // Note: select can have a different size (eg, labelHashSet)
594
595 const label len = input.size();
596
597 label count = 0;
598
599 for (label i=0; i < len; ++i)
600 {
601 if (select[i] ? !invert : invert)
602 {
603 if (count != i)
604 {
605 input[count] = std::move(input[i]);
606 }
607 ++count;
608 }
610
611 input.resize(count);
612}
613
614
615template<class ListType>
617(
618 const bitSet& select,
619 ListType& input,
620 const bool invert
621)
622{
623 label count = 0;
624
625 if (!invert)
626 {
627 // Normal selection
628
629 const label len = input.size();
630
631 for (const label i : select)
632 {
633 if (i >= len) break;
634
635 if (count != i)
636 {
637 input[count] = std::move(input[i]);
638 }
639 ++count;
640 }
641 }
642 else
643 {
644 // Inverted selection
645
646 const label outlen = (select.size() - select.count());
647
648 const label len = Foam::min(input.size(), select.size());
649
650 for (label i=0; i < len; ++i)
651 {
652 if (!select[i])
653 {
654 if (count != i)
655 {
656 input[count] = std::move(input[i]);
657 }
658 ++count;
659 if (count >= outlen) break; // terminate early
660 }
661 }
662 }
663
664 input.resize(count);
665}
666
667
668template<class T, class UnaryPredicate>
670(
671 const UList<T>& input,
672 const UnaryPredicate& pred,
673 const bool invert
674)
675{
676 const label len = input.size();
677
678 List<T> output(len);
679
680 label count = 0;
681 for (label i=0; i < len; ++i)
682 {
683 if (pred(input[i]) ? !invert : invert)
684 {
685 output[count] = input[i];
686 ++count;
687 }
688 }
689
690 output.resize(count);
691
692 return output;
693}
694
695
696template<class ListType, class UnaryPredicate>
698(
699 ListType& input,
700 const UnaryPredicate& pred,
701 const bool invert
702)
703{
704 const label len = input.size();
705
706 label count = 0;
707 for (label i=0; i < len; ++i)
708 {
709 if (pred(input[i]) ? !invert : invert)
710 {
711 if (count != i)
712 {
713 input[count] = std::move(input[i]);
714 }
715 ++count;
717 }
718 input.resize(count);
719}
720
721
722template<class InputIntListType, class OutputIntListType>
724(
725 const label len,
726 const UList<InputIntListType>& input,
727 List<OutputIntListType>& output
728)
729{
730 // The output list sizes
731 labelList sizes(len, Foam::zero{});
732
733 for (const InputIntListType& sublist : input)
734 {
735 forAll(sublist, idx)
736 {
737 sizes[sublist[idx]]++;
738 }
739 }
740
741 // Size output
742 output.resize(len);
743 forAll(sizes, outi)
744 {
745 output[outi].resize(sizes[outi]);
746 }
747
748 // Fill output
749 sizes = 0;
750 forAll(input, listi)
751 {
752 const InputIntListType& sublist = input[listi];
753
754 forAll(sublist, idx)
755 {
756 const label outi = sublist[idx];
757
758 output[outi][sizes[outi]++] = listi;
759 }
760 }
761}
762
763
764template<class ListType>
766(
767 const ListType& input,
768 typename ListType::const_reference val,
769 label start
770)
771{
772 const label len = input.size();
773
774 // Pass 1: count occurrences
775 label count = 0;
776
777 if (start >= 0)
778 {
779 for (label i = start; i < len; ++i)
780 {
781 if (input[i] == val)
782 {
783 if (!count) start = i; // adjust start for second pass
784 ++count;
785 }
786 }
787 }
788
789 labelList indices(count);
790
791 // Pass 2: fill content
792 if (count)
793 {
794 const label total = count;
795 count = 0;
796 for (label i = start; i < len; ++i)
797 {
798 if (input[i] == val)
799 {
800 indices[count] = i;
801 if (++count == total) // early termination
802 {
803 break;
804 }
805 }
806 }
807 }
808
809 return indices;
810}
811
812
813template<class ListType>
814Foam::label Foam::findMin
815(
816 const ListType& input,
817 label start
818)
819{
820 const label len = input.size();
821
822 if (start < 0 || start >= len)
823 {
824 return -1;
825 }
826
827 for (label i = start+1; i < len; ++i)
828 {
829 if (input[i] < input[start])
830 {
831 start = i;
832 }
833 }
834
835 return start;
836}
837
838
839template<class ListType>
840Foam::label Foam::findMax
841(
842 const ListType& input,
843 label start
844)
845{
846 const label len = input.size();
847
848 if (start < 0 || start >= len)
849 {
850 return -1;
851 }
852
853 for (label i = start+1; i < len; ++i)
854 {
855 if (input[start] < input[i])
856 {
857 start = i;
858 }
859 }
860
861 return start;
862}
863
864
865template<class ListType>
867(
868 const ListType& input,
869 label start
870)
871{
872 const label len = input.size();
873
874 if (start < 0 || start >= len)
875 {
876 return labelPair(-1,-1);
877 }
878
879 label minIdx = start;
880 label maxIdx = start;
881
882 for (label i = start+1; i < len; ++i)
883 {
884 if (input[i] < input[minIdx])
885 {
886 minIdx = i;
887 }
888 if (input[maxIdx] < input[i])
889 {
890 maxIdx = i;
891 }
892 }
893
894 return labelPair(minIdx, maxIdx);
895}
896
897
898template<class ListType>
899Foam::label Foam::findSortedIndex
900(
901 const ListType& input,
902 typename ListType::const_reference val,
903 const label start
904)
905{
906 label low = start;
907 label high = input.size() - 1;
908
909 if (start < 0 || start >= input.size())
910 {
911 return -1;
912 }
913
914 while (low <= high)
915 {
916 const label mid = (low + high)/2;
917
918 if (val < input[mid])
919 {
920 high = mid - 1;
921 }
922 else if (input[mid] < val)
923 {
924 low = mid + 1;
925 }
926 else
927 {
928 return mid;
929 }
930 }
931
932 return -1;
933}
934
935
936template<class ListType, class T, class ComparePredicate>
937Foam::label Foam::findLower
938(
939 const ListType& input,
940 const T& val,
941 const label start,
942 const ComparePredicate& comp
943)
944{
945 label low = start;
946 label high = input.size() - 1;
947
948 if (start < 0 || start >= input.size())
949 {
950 return -1;
951 }
952
953 while ((high - low) > 1)
954 {
955 const label mid = (low + high)/2;
956
957 if (comp(input[mid], val))
958 {
959 low = mid;
960 }
961 else
962 {
963 high = mid;
964 }
965 }
966
967 if (comp(input[high], val))
968 {
969 return high;
970 }
971 else if (comp(input[low], val))
972 {
973 return low;
974 }
975 else
976 {
977 return -1;
978 }
979}
980
981
982template<class ListType, class T>
983Foam::label Foam::findLower
984(
985 const ListType& input,
986 const T& val,
987 const label start
988)
989{
990 return findLower
991 (
992 input,
993 val,
994 start,
995 lessOp<T>()
996 );
997}
998
999
1000template<class ListType>
1001ListType Foam::reverseList(const ListType& input)
1002{
1003 const label len = input.size();
1004 const label last = (len - 1);
1005
1006 ListType output(len);
1007 output.resize(len); // Consistent sizing (eg, DynamicList)
1008
1009 for (label i=0; i < len; ++i)
1010 {
1011 output[i] = input[last - i];
1013
1014 return output;
1015}
1016
1017
1018template<class ListType>
1019void Foam::inplaceReverseList(ListType& input)
1020{
1021 const label len = input.size();
1022 const label last = (len - 1);
1023 const label n2 = len >> 1;
1024
1025 for (label i=0; i<n2; ++i)
1027 Foam::Swap(input[i], input[last - i]);
1028 }
1029}
1030
1031
1032template<class ListType>
1033ListType Foam::rotateList(const ListType& input, const label n)
1034{
1035 const label len = input.size();
1036
1037 ListType output(len);
1038 output.resize(len); // Consistent sizing (eg, DynamicList)
1039
1040 for (label i=0; i<len; ++i)
1041 {
1042 label index = (i - n) % len;
1043
1044 if (index < 0)
1045 {
1046 index += len;
1047 }
1048
1049 output[i] = input[index];
1051
1052 return output;
1053}
1054
1055
1056template<template<typename> class ListType, class DataType>
1057void Foam::inplaceRotateList(ListType<DataType>& input, label n)
1058{
1059 const label len = input.size();
1060
1061 n = (len - n) % len;
1062
1063 if (n < 0)
1064 {
1065 n += len;
1066 }
1067
1068 SubList<DataType> firstHalf(input, n, 0);
1069 SubList<DataType> secondHalf(input, len - n, n);
1070
1071 inplaceReverseList(firstHalf);
1072 inplaceReverseList(secondHalf);
1073
1075}
1076
1077
1078// * * * * * * * * * * * * * * * * * ListOps * * * * * * * * * * * * * * * * //
1079
1080template<class T>
1082(
1083 List<T>& x,
1084 const UList<T>& y
1085) const
1086{
1087 if (y.size())
1088 {
1089 if (x.size())
1090 {
1091 x.push_back(y);
1092 }
1093 else
1094 {
1095 x = y;
1096 }
1097 }
1098}
1099
1100
1101template<class T>
1103(
1104 List<T>& x,
1105 const UList<T>& y
1106) const
1107{
1108 if (y.size())
1109 {
1110 if (x.size())
1111 {
1112 for (const T& val : y)
1113 {
1114 // Not very efficient
1115 x.push_uniq(val);
1116 }
1117 }
1118 else
1119 {
1120 x = y;
1121 }
1122 }
1123}
1124
1125
1126template<class Type1, class Type2>
1128(
1129 const UList<Type1>& a,
1130 const UList<Type2>& b
1131)
1132{
1133 return
1134 (
1135 (a.size() == b.size())
1136 && std::equal(a.cbegin(), a.cend(), b.cbegin())
1137 );
1138}
1139
1140
1141template<class Type1, class Type2, class BinaryPredicate>
1143(
1144 const UList<Type1>& a,
1145 const UList<Type2>& b,
1146 BinaryPredicate pred
1147)
1148{
1149 return
1150 (
1151 (a.size() == b.size())
1152 && std::equal(a.cbegin(), a.cend(), b.cbegin(), pred)
1153 );
1154}
1155
1156
1157template<class ListType>
1158Foam::label Foam::ListOps::count
1159(
1160 const ListType& input,
1161 typename ListType::const_reference val,
1162 const label start
1163)
1164{
1165 label num = 0;
1166
1167 const label len = input.size();
1168
1169 if (start >= 0)
1170 {
1171 for (label i = start; i < len; ++i)
1172 {
1173 if (val == input[i])
1174 {
1175 ++num;
1176 }
1177 }
1178 }
1179
1180 return num;
1181}
1182
1183
1184template<class ListType, class UnaryPredicate>
1185Foam::label Foam::ListOps::count_if
1186(
1187 const ListType& input,
1188 const UnaryPredicate& pred,
1189 const label start
1190)
1191{
1192 label num = 0;
1193
1194 const label len = input.size();
1195
1196 if (start >= 0)
1197 {
1198 for (label i = start; i < len; ++i)
1199 {
1200 if (pred(input[i]))
1201 {
1202 ++num;
1203 }
1204 }
1205 }
1206
1207 return num;
1208}
1209
1210
1211template<class ListType, class UnaryPredicate>
1212Foam::label Foam::ListOps::find_if
1213(
1214 const ListType& input,
1215 const UnaryPredicate& pred,
1216 const label start
1217)
1218{
1219 const label len = input.size();
1220
1221 if (start >= 0)
1222 {
1223 for (label i = start; i < len; ++i)
1224 {
1225 if (pred(input[i]))
1226 {
1227 return i;
1228 }
1229 }
1231
1232 return -1;
1233}
1234
1235
1236template<class ListType, class UnaryPredicate>
1238(
1239 const ListType& input,
1240 const UnaryPredicate& pred,
1241 const label start
1242)
1243{
1244 return (ListOps::find_if(input, pred, start) >= 0);
1245}
1246
1247
1248template<class ListType, class UnaryPredicate>
1250(
1251 const ListType& input,
1252 const UnaryPredicate& pred,
1253 label start
1254)
1255{
1256 const label len = input.size();
1257
1258 // Pass 1: count occurrences where pred is true. ie, count_if()
1259 label count = 0;
1260
1261 if (start >= 0)
1262 {
1263 for (label i = start; i < len; ++i)
1264 {
1265 if (pred(input[i]))
1266 {
1267 if (!count) start = i; // adjust start for second pass
1268 ++count;
1269 }
1270 }
1271 }
1272
1273 labelList indices(count);
1274
1275 // Pass 2: fill content
1276 if (count)
1277 {
1278 const label total = count;
1279 count = 0;
1280 for (label i = start; i < len; ++i)
1281 {
1282 if (pred(input[i]))
1283 {
1284 indices[count] = i;
1285 if (++count == total) // early termination
1286 {
1287 break;
1288 }
1289 }
1290 }
1292
1293 return indices;
1294}
1295
1296
1297template<class T>
1299(
1300 UList<T>& list,
1301 const labelUList& locations,
1302 const T& val
1303)
1304{
1305 const label len = list.size();
1306
1307 for (const label index : locations)
1308 {
1309 // Range-checked
1310 if (index >= 0 && index < len)
1311 {
1312 list[index] = val;
1313 }
1314 }
1315}
1316
1317
1318template<class T>
1320(
1321 UList<T>& list,
1322 const labelHashSet& locations,
1323 const T& val
1324)
1325{
1326 const label len = list.size();
1327
1328 for (const label index : locations)
1329 {
1330 // Range-checked
1331 if (index >= 0 && index < len)
1332 {
1333 list[index] = val;
1334 }
1335 }
1336}
1337
1338
1339template<class T>
1341(
1342 UList<T>& list,
1343 const UList<bool>& locations,
1344 const T& val
1345)
1346{
1347 const label end = Foam::min(list.size(), locations.size());
1348
1349 // The efficiency is modest
1350 for (label index = 0; index < end; ++index)
1351 {
1352 if (locations[index])
1353 {
1354 list[index] = val;
1355 }
1356 }
1357}
1358
1359
1360template<class T>
1362(
1363 UList<T>& list,
1364 const bitSet& locations,
1365 const T& val
1366)
1367{
1368 const label len = list.size();
1369
1370 for
1371 (
1372 label pos = locations.find_first();
1373 pos >= 0 && pos < len;
1374 pos = locations.find_next(pos)
1375 )
1376 {
1377 list[pos] = val;
1378 }
1379}
1380
1381
1382template<class T, class T2, class UnaryOperation>
1384(
1385 const UList<T2>& input,
1386 const UnaryOperation& op
1387)
1388{
1389 const label len = input.size();
1390
1391 List<T> output(len);
1392
1393 // ie, std::transform(input.begin(), input.end(), output.begin(), op);
1394
1395 const T2* in = input.begin();
1396 T* out = output.begin();
1397
1398 for (label i = 0; i < len; ++i)
1399 {
1400 out[i] = op(in[i]);
1401 }
1402
1403 return output;
1404}
1405
1406
1407template<class T, class InputIterator, class UnaryOperation>
1409(
1410 InputIterator first,
1411 InputIterator last,
1412 const UnaryOperation& op
1413)
1414{
1415 const label len = std::distance(first, last);
1416
1417 List<T> output(len);
1418
1419 // ie, std::transform(first, last, output.begin(), op);
1420
1421 T* out = output.begin();
1422
1423 while (first != last)
1424 {
1425 *out = op(*first);
1426 ++first;
1427 ++out;
1428 }
1429
1430 return output;
1431}
1432
1433
1434template<class T>
1436(
1437 const label len,
1438 const labelUList& locations,
1439 const T& val,
1440 const T& deflt
1441)
1442{
1443 List<T> list(len, deflt);
1444 ListOps::setValue(list, locations, val);
1445
1446 return list;
1447}
1448
1449
1450template<class T>
1452(
1453 const label len,
1454 const labelHashSet& locations,
1455 const T& val,
1456 const T& deflt
1457)
1458{
1459 List<T> list(len, deflt);
1460 ListOps::setValue(list, locations, val);
1461
1462 return list;
1463}
1464
1465
1466template<class T>
1468(
1469 const label len,
1470 const UList<bool>& locations,
1471 const T& val,
1472 const T& deflt
1473)
1474{
1475 List<T> list(len, deflt);
1476 ListOps::setValue(list, locations, val);
1477
1478 return list;
1479}
1480
1481
1482template<class T>
1484(
1485 const label len,
1486 const bitSet& locations,
1487 const T& val,
1488 const T& deflt
1489)
1490{
1491 List<T> list(len, deflt);
1492 ListOps::setValue(list, locations, val);
1493
1494 return list;
1495}
1496
1497
1498template<class T>
1500(
1501 const label len,
1502 const label index,
1503 const T& val,
1504 const T& deflt
1505)
1506{
1507 List<T> list(len, deflt);
1508
1509 // Range-checked
1510 if (index >= 0 && index < len)
1511 {
1512 list[index] = val;
1513 }
1514
1515 return list;
1516}
1517
1518
1519template<class T>
1521(
1522 const label len,
1523 const label index,
1524 T&& val,
1525 const T& deflt
1526)
1527{
1528 List<T> list(len, deflt);
1529
1530 // Range-checked
1531 if (index >= 0 && index < len)
1532 {
1533 list[index] = std::move(val);
1534 }
1535
1536 return list;
1537}
1538
1539
1540// ************************************************************************* //
scalar y
label n
static constexpr label size() noexcept
Return the number of elements in the FixedList.
Definition FixedList.H:619
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
Definition HashTableI.H:113
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
void resize(const label len)
Adjust allocated size of list.
Definition ListI.H:153
void clear()
Clear the list, i.e. set size to zero.
Definition ListI.H:133
A HashTable to objects of type <T> with a label key.
Definition Map.H:54
A dynamic list of packed unsigned integers, with the number of bits per item specified by the <Width>...
Definition PackedList.H:146
label size() const noexcept
Number of entries.
Definition PackedList.H:392
A non-owning sub-view of a List (allocated or unallocated storage).
Definition SubList.H:61
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition UListI.H:410
const_iterator cend() const noexcept
Return const_iterator to end traversing the constant UList.
Definition UListI.H:468
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant UList.
Definition UListI.H:424
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition bitSet.H:61
label find_next(label pos) const
Locate the next bit set, starting one beyond the specified position.
Definition bitSetI.H:347
label find_first() const
Locate the first bit that is set.
Definition bitSetI.H:260
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition zero.H:58
const volScalarField & T
List< bool > select(const label n, const labelUList &locations)
Construct a selection list of bools (all false) with the given pre-size, subsequently add specified l...
Definition BitOps.C:139
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition BitOps.H:73
labelList findIndices(const ListType &input, const UnaryPredicate &pred, label start=0)
Linear search to find all occurences of given element.
label count_if(const ListType &input, const UnaryPredicate &pred, const label start=0)
Count the number of matching entries.
label find_if(const ListType &input, const UnaryPredicate &pred, const label start=0)
Find index of the first occurrence that satisfies the predicate.
label count(const ListType &input, typename ListType::const_reference val, const label start=0)
Count the occurrences of the given element.
void setValue(UList< T > &list, const labelUList &locations, const T &val)
Set various locations of the list with a specified value.
List< T > create(const UList< T2 > &input, const UnaryOperation &op)
Create a List from a List of a dissimilar type, using the entire list.
bool equal(const UList< Type1 > &a, const UList< Type2 > &b)
Test for list equality with different but compatible data types. Eg, int32 and int64.
List< T > createWithValue(const label len, const labelUList &locations, const T &val, const T &deflt=T())
Create a List filled with default values and various locations with another specified value.
bool found_if(const ListType &input, const UnaryPredicate &pred, const label start=0)
True if there is a value in the list that satisfies the predicate.
const char * end
Definition SVGTools.H:223
void invertManyToMany(const label len, const UList< InputIntListType > &input, List< OutputIntListType > &output)
Invert many-to-many.
List< T > uniqueSort(const UList< T > &input)
Return sorted list with removal of duplicates.
dimensionedScalar pos(const dimensionedScalar &ds)
Pair< label > labelPair
A pair of labels.
Definition Pair.H:54
void inplaceSubset(const BoolListType &select, ListType &input, const bool invert=false)
Inplace extract elements of the input list when select is true.
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values within a list.
List< label > labelList
A List of labels.
Definition List.H:62
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition HashSet.H:85
label findMin(const ListType &input, label start=0)
Linear search for the index of the min element, similar to std::min_element but for lists and returns...
ListType rotateList(const ListType &list, const label n)
Rotate a list by n places.
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values within a list.
void inplaceRotateList(ListType< DataType > &list, label n)
Inplace reversal of a list using the Reversal Block Swapping algorithm.
List< T > subset(const BoolListType &select, const UList< T > &input, const bool invert=false)
Extract elements of the input list when select is true.
labelList duplicateOrder(const UList< T > &input)
Return (sorted) indices corresponding to duplicate list values.
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Binary search to find the index of the last element in a sorted list that is less than value.
void inplaceReverseList(ListType &input)
Inplace reversal of a list using Swap.
List< T > subsetList(const UList< T > &input, const UnaryPredicate &pred, const bool invert=false)
Copy a subset of the input list when predicate is true.
labelPair findMinMax(const ListType &input, label start=0)
Linear search for the index of the min/max element, similar to std::minmax_element but for lists and ...
void Swap(DynamicList< T, SizeMinA > &a, DynamicList< T, SizeMinB > &b)
Exchange contents of lists - see DynamicList::swap().
void inplaceSubsetList(ListType &input, const UnaryPredicate &pred, const bool invert=false)
Inplace subset of the list when predicate is true.
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
label inplaceMapValue(const labelUList &oldToNew, Container &input)
Map values. Ignore negative values.
void inplaceMapKey(const labelUList &oldToNew, Container &input)
Rewrite with mapped keys. Ignore elements with negative key.
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
void inplaceUniqueSort(ListType &input)
Inplace sorting and removal of duplicates.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:26
ListType reverseList(const ListType &input)
Reverse a list. First element becomes last element etc.
labelList uniqueOrder(const UList< T > &input)
Return (sorted) indices corresponding to unique list values.
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition ListOps.C:28
label findSortedIndex(const ListType &input, typename ListType::const_reference val, const label start=0)
Binary search to find the index of the last element in a sorted list that is less than value.
label findMax(const ListType &input, label start=0)
Linear search for the index of the max element, similar to std::max_element but for lists and returns...
labelList findIndices(const ListType &input, typename ListType::const_reference val, label start=0)
Linear search to find all occurrences of given element.
UList< label > labelUList
A UList of labels.
Definition UList.H:75
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
ListType reorder(const labelUList &oldToNew, const ListType &input, const bool prune=false)
Reorder the elements of a list.
void stableSort(UList< T > &list)
Stable sort the list.
Definition UList.C:299
volScalarField & b
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
List helper to append y elements onto the end of x.
Definition ListOps.H:712
List helper to append y unique elements onto the end of x.
Definition ListOps.H:721
A list compare binary predicate for normal sort.
Definition UList.H:237