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-2022 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#include <utility>
30#include "ListOps.H"
31#include "ListLoopM.H"
32
33// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
34
35template<class IntListType>
36IntListType Foam::renumber
37(
38 const labelUList& oldToNew,
39 const IntListType& input
40)
41{
42 const label len = input.size();
43
44 IntListType output(len);
45 output.resize(len); // Consistent sizing (eg, DynamicList)
46
47 for (label i=0; i < len; ++i)
48 {
49 if (input[i] >= 0)
50 {
51 output[i] = oldToNew[input[i]];
52 }
53 }
54
55 return output;
56}
57
58
59template<class IntListType>
61(
62 const labelUList& oldToNew,
63 IntListType& input
64)
65{
66 const label len = input.size();
67
68 for (label i=0; i < len; ++i)
69 {
70 if (input[i] >= 0)
71 {
72 input[i] = oldToNew[input[i]];
73 }
74 }
75}
76
77
78template<class ListType>
80(
81 const labelUList& oldToNew,
82 const ListType& input,
83 const bool prune
84)
85{
86 const label len = input.size();
87
88 ListType output(len);
89 output.resize(len); // Consistent sizing (eg, DynamicList)
90
91 label maxIdx = -1; // For pruning: The new size = maxIdx+1
92 for (label i=0; i < len; ++i)
93 {
94 const label newIdx = oldToNew[i];
95 if (newIdx >= 0)
96 {
97 // Could enforce (newIdx < len)
98 // ... or just rely on FULLDEBUG from UList
99
100 output[newIdx] = input[i];
101
102 if (maxIdx < newIdx)
103 {
104 maxIdx = newIdx;
105 }
106 }
107 else if (!prune)
108 {
109 output[i] = input[i];
110 }
111 }
112
113 if (prune)
114 {
115 output.resize(maxIdx+1);
116 }
117
118 return output;
119}
120
121
122template<class ListType>
124(
125 const labelUList& oldToNew,
126 ListType& inputOutput,
127 const bool prune
128)
129{
130 // NOTE: cannot use std::move() since we have no guarantee that
131 // the oldToNew map is unique (ie, shuffle)
132
133 // Use const reference to ensure we obtain the proper operator[]
134 // on lazy lists (eg, List<bool>, PackedList)
135
136 const ListType& input = inputOutput;
137 const label len = input.size();
138
139 ListType output(len);
140 output.resize(len); // Consistent sizing (eg, DynamicList)
141
142 label maxIdx = -1; // For pruning: The new size = maxIdx+1
143 for (label i=0; i < len; ++i)
144 {
145 const label newIdx = oldToNew[i];
146 if (newIdx >= 0)
147 {
148 // Could enforce (newIdx < len)
149 // ... or just rely on FULLDEBUG from UList
150
151 output[newIdx] = input[i];
152
153 if (maxIdx < newIdx)
154 {
155 maxIdx = newIdx;
156 }
157 }
158 else if (!prune)
159 {
160 output[i] = input[i];
161 }
162 }
163
164 if (prune)
165 {
166 output.resize(maxIdx+1);
167 }
168
169 inputOutput.transfer(output);
170}
171
172
173template<unsigned Width>
175(
176 const labelUList& oldToNew,
177 const PackedList<Width>& input,
178 const bool prune
179)
180{
181 const label len = input.size();
182
183 PackedList<Width> output(len);
184
185 label maxIdx = -1; // For pruning: The new size = maxIdx+1
186 for (label i=0; i < len; ++i)
187 {
188 const auto& val = input.get(i);
189
190 const label newIdx = oldToNew[i];
191
192 if (newIdx >= 0)
193 {
194 // Could enforce (newIdx < len)
195 // ... or just rely on FULLDEBUG from UList
196
197 output.set(newIdx, val);
198
199 if (maxIdx < newIdx)
200 {
201 maxIdx = newIdx;
202 }
203 }
204 else if (!prune)
205 {
206 output.set(i, val);
207 }
208 }
209
210 if (prune)
211 {
212 output.resize(maxIdx+1);
213 }
214
215 // Verify addresses (for movable refs)
216 // Info<< "reordered in " << name(input.cdata()) << nl
217 // << "reordered out " << name(output.cdata()) << nl;
218
219 return output;
220}
221
222
223template<unsigned Width>
225(
226 const labelUList& oldToNew,
227 PackedList<Width>& input,
228 const bool prune
229)
230{
231 input = reorder(oldToNew, input, prune);
232
233 // Verify address (for movable refs)
234 // Info<< "now have " << name(input.cdata()) << nl;
235}
236
237
238template<class Container>
240(
241 const labelUList& oldToNew,
242 Container& input
243)
244{
245 Container output(input.capacity());
246
247 for (auto iter = input.begin(); iter != input.end(); ++iter)
248 {
249 const label oldIdx = iter.key();
250 if (oldIdx >= 0)
251 {
252 // Could enforce (oldIdx < oldToNew.size())
253 // ... or just rely on FULLDEBUG from UList
254
255 output.insert(oldToNew[oldIdx], iter.val());
256 }
257 }
258
259 input.transfer(output);
260}
261
262
263template<class Container>
264Foam::label Foam::inplaceMapValue
265(
266 const labelUList& oldToNew,
267 Container& input
268)
269{
270 label nChanged = 0;
271
272 for (auto iter = input.begin(); iter != input.end(); ++iter)
273 {
274 const label oldIdx = iter.val();
275 if (oldIdx >= 0)
276 {
277 // Could enforce (oldIdx < oldToNew.size())
278 // ... or just rely on FULLDEBUG from UList
279
280 const label newIdx = oldToNew[oldIdx];
281
282 if (oldIdx != newIdx)
283 {
284 iter.val() = newIdx;
285 ++nChanged;
286 }
287 }
288 }
289
290 return nChanged;
291}
292
293
294template<class Container>
295Foam::label Foam::inplaceMapValue
296(
297 const Map<label>& mapper,
298 Container& input
299)
300{
301 if (mapper.empty())
302 {
303 return 0;
304 }
305
306 label nChanged = 0;
307
308 for (auto iter = input.begin(); iter != input.end(); ++iter)
309 {
310 label& value = iter.val();
311
312 auto mapIter = mapper.find(value);
313 if (mapIter.found() && value != *mapIter)
314 {
315 value = *mapIter;
316 ++nChanged;
317 }
318 }
319
320 return nChanged;
321}
322
323
324template<class T>
326(
327 const UList<T>& input
328)
329{
330 labelList order;
331 duplicateOrder(input, order, typename UList<T>::less(input));
332 return order;
333}
334
335
336template<class T>
338(
339 const UList<T>& input,
340 labelList& order
341)
342{
343 duplicateOrder(input, order, typename UList<T>::less(input));
344}
345
346
347template<class T, class ListComparePredicate>
349(
350 const UList<T>& input,
351 labelList& order,
352 const ListComparePredicate& comp
353)
354{
355 if (input.size() < 2)
356 {
357 order.clear();
358 return;
359 }
360
361 Foam::sortedOrder(input, order, comp);
362
363 const label last = (order.size()-1);
364 label count = 0;
365 for (label i = 0; i < last; ++i)
366 {
367 if (input[order[i]] == input[order[i+1]])
368 {
369 order[count] = order[i];
370 ++count;
371 }
372 }
373 order.resize(count);
374}
375
376
377template<class T>
379(
380 const UList<T>& input
381)
382{
383 labelList order;
384 uniqueOrder(input, order, typename UList<T>::less(input));
385 return order;
386}
387
388
389template<class T>
391(
392 const UList<T>& input,
393 labelList& order
394)
395{
396 uniqueOrder(input, order, typename UList<T>::less(input));
397}
398
399
400template<class T, class ListComparePredicate>
402(
403 const UList<T>& input,
404 labelList& order,
405 const ListComparePredicate& comp
406)
407{
408 Foam::sortedOrder(input, order, comp);
409
410 if (order.size() > 1)
411 {
412 const label last = (order.size()-1);
413 label count = 0;
414 for (label i = 0; i < last; ++i)
415 {
416 if (input[order[i]] != input[order[i+1]])
417 {
418 order[count++] = order[i];
419 }
420 }
421 order[count++] = order[last];
422 order.resize(count);
423 }
424}
425
426
427template<class T>
428Foam::List<T> Foam::uniqueSort(const UList<T>& input)
429{
430 List<T> output(input);
431
432 const label len = output.size();
433
434 if (len > 1)
435 {
436 Foam::stableSort(output);
437
438 label count = 0;
439 for (label i = 1; i < len; ++i)
440 {
441 if (output[count] != output[i])
442 {
443 output[++count] = output[i];
444 }
445 }
446
447 output.resize(count+1);
448 }
449
450 return output;
451}
452
453
454template<class ListType>
455void Foam::inplaceUniqueSort(ListType& input)
456{
458 (
459 input,
461 );
462}
463
464
465template<class ListType, class ListComparePredicate>
467(
468 ListType& input,
469 const ListComparePredicate& comp
470)
471{
472 labelList order;
473 uniqueOrder(input, order, comp);
474
475 const label len = order.size();
476
477 ListType output(len);
478 output.resize(len); // Consistent sizing (eg, DynamicList)
479
480 for (label i=0; i < len; ++i)
481 {
482 output[i] = std::move(input[order[i]]);
483 }
484
485 input.transfer(output);
486}
487
488
489template<class BoolListType, class T>
491(
492 const BoolListType& select,
493 const UList<T>& input,
494 const bool invert
495)
496{
497 // Note: select can have a different size (eg, labelHashSet)
498
499 const label len = input.size();
500
501 List<T> output(len);
502
503 label count = 0;
504
505 for (label i=0; i < len; ++i)
506 {
507 if (select[i] ? !invert : invert)
508 {
509 output[count] = input[i];
510 ++count;
511 }
512 }
513
514 output.resize(count);
515
516 return output;
517}
518
519
520template<class T>
522(
523 const bitSet& select,
524 const UList<T>& input,
525 const bool invert
526)
527{
528 const label len = input.size();
529
530 List<T> output;
531
532 label count = 0;
533
534 if (!invert)
535 {
536 output.resize(select.count());
537
538 for (const label i : select)
539 {
540 if (i >= len) break; // Avoid out of bounds (when select is longer)
541
542 output[count] = input[i];
543 ++count;
544 }
545 }
546 else
547 {
548 const label outlen = (select.size() - select.count());
549 output.resize(outlen);
550
551 for (label i=0; i < len; ++i)
552 {
553 if (!select[i])
554 {
555 output[count] = input[i];
556 ++count;
557 if (count >= outlen) break; // terminate early
558 }
559 }
560 }
561
562 output.resize(count);
563
564 return output;
565}
566
567
568template<class BoolListType, class ListType>
570(
571 const BoolListType& select,
572 ListType& input,
573 const bool invert
574)
575{
576 // Note: select can have a different size (eg, labelHashSet)
577
578 const label len = input.size();
579
580 label count = 0;
581
582 for (label i=0; i < len; ++i)
583 {
584 if (select[i] ? !invert : invert)
585 {
586 if (count != i)
587 {
588 input[count] = std::move(input[i]);
589 }
590 ++count;
591 }
592 }
593
594 input.resize(count);
595}
596
597
598template<class ListType>
600(
601 const bitSet& select,
602 ListType& input,
603 const bool invert
604)
605{
606 label count = 0;
607
608 if (!invert)
609 {
610 // Normal selection
611
612 const label len = input.size();
613
614 for (const label i : select)
615 {
616 if (i >= len) break;
617
618 if (count != i)
619 {
620 input[count] = std::move(input[i]);
621 }
622 ++count;
623 }
624 }
625 else
626 {
627 // Inverted selection
628
629 const label outlen = (select.size() - select.count());
630
631 const label len = min(input.size(), select.size());
632
633 for (label i=0; i < len; ++i)
634 {
635 if (!select[i])
636 {
637 if (count != i)
638 {
639 input[count] = std::move(input[i]);
640 }
641 ++count;
642 if (count >= outlen) break; // terminate early
643 }
644 }
645 }
646
647 input.resize(count);
648}
649
650
651template<class T, class UnaryPredicate>
653(
654 const UList<T>& input,
655 const UnaryPredicate& pred,
656 const bool invert
657)
658{
659 const label len = input.size();
660
661 List<T> output(len);
662
663 label count = 0;
664 for (label i=0; i < len; ++i)
665 {
666 if (pred(input[i]) ? !invert : invert)
667 {
668 output[count] = input[i];
669 ++count;
670 }
671 }
672
673 output.resize(count);
674
675 return output;
676}
677
678
679template<class ListType, class UnaryPredicate>
681(
682 ListType& input,
683 const UnaryPredicate& pred,
684 const bool invert
685)
686{
687 const label len = input.size();
688
689 label count = 0;
690 for (label i=0; i < len; ++i)
691 {
692 if (pred(input[i]) ? !invert : invert)
693 {
694 if (count != i)
695 {
696 input[count] = std::move(input[i]);
697 }
698 ++count;
699 }
700 }
701 input.resize(count);
702}
703
704
705template<class InputIntListType, class OutputIntListType>
707(
708 const label len,
709 const UList<InputIntListType>& input,
711)
712{
713 // The output list sizes
714 labelList sizes(len, Zero);
715
716 for (const InputIntListType& sublist : input)
717 {
718 forAll(sublist, idx)
719 {
720 sizes[sublist[idx]]++;
721 }
722 }
723
724 // Size output
725 output.resize(len);
726 forAll(sizes, outi)
727 {
728 output[outi].resize(sizes[outi]);
729 }
730
731 // Fill output
732 sizes = 0;
733 forAll(input, listi)
734 {
735 const InputIntListType& sublist = input[listi];
736
737 forAll(sublist, idx)
738 {
739 const label outi = sublist[idx];
740
741 output[outi][sizes[outi]++] = listi;
742 }
743 }
744}
745
746
747template<class ListType>
749(
750 const ListType& input,
751 typename ListType::const_reference val,
752 label start
753)
754{
755 const label len = input.size();
756
757 // Pass 1: count occurrences
758 label count = 0;
759
760 if (start >= 0)
761 {
762 for (label i = start; i < len; ++i)
763 {
764 if (input[i] == val)
765 {
766 if (!count) start = i; // adjust start for second pass
767 ++count;
768 }
769 }
770 }
771
772 labelList indices(count);
773
774 // Pass 2: fill content
775 if (count)
776 {
777 const label total = count;
778 count = 0;
779 for (label i = start; i < len; ++i)
780 {
781 if (input[i] == val)
782 {
783 indices[count] = i;
784 if (++count == total) // early termination
785 {
786 break;
787 }
788 }
789 }
790 }
791
792 return indices;
793}
794
795
796template<class ListType>
797Foam::label Foam::findMin
798(
799 const ListType& input,
800 label start
801)
802{
803 const label len = input.size();
804
805 if (start < 0 || start >= len)
806 {
807 return -1;
808 }
809
810 for (label i = start+1; i < len; ++i)
811 {
812 if (input[i] < input[start])
813 {
814 start = i;
815 }
816 }
817
818 return start;
819}
820
821
822template<class ListType>
823Foam::label Foam::findMax
824(
825 const ListType& input,
826 label start
827)
828{
829 const label len = input.size();
830
831 if (start < 0 || start >= len)
832 {
833 return -1;
834 }
835
836 for (label i = start+1; i < len; ++i)
837 {
838 if (input[start] < input[i])
839 {
840 start = i;
841 }
842 }
843
844 return start;
845}
846
847
848template<class ListType>
850(
851 const ListType& input,
852 label start
853)
854{
855 const label len = input.size();
856
857 if (start < 0 || start >= len)
858 {
859 return labelPair(-1,-1);
860 }
861
862 label minIdx = start;
863 label maxIdx = start;
864
865 for (label i = start+1; i < len; ++i)
866 {
867 if (input[i] < input[minIdx])
868 {
869 minIdx = i;
870 }
871 if (input[maxIdx] < input[i])
872 {
873 maxIdx = i;
874 }
875 }
876
877 return labelPair(minIdx, maxIdx);
878}
879
880
881template<class ListType>
882Foam::label Foam::findSortedIndex
883(
884 const ListType& input,
885 typename ListType::const_reference val,
886 const label start
887)
888{
889 label low = start;
890 label high = input.size() - 1;
891
892 if (start < 0 || start >= input.size())
893 {
894 return -1;
895 }
896
897 while (low <= high)
898 {
899 const label mid = (low + high)/2;
900
901 if (val < input[mid])
902 {
903 high = mid - 1;
904 }
905 else if (input[mid] < val)
906 {
907 low = mid + 1;
908 }
909 else
910 {
911 return mid;
912 }
913 }
914
915 return -1;
916}
917
918
919template<class ListType, class T, class ComparePredicate>
920Foam::label Foam::findLower
921(
922 const ListType& input,
923 const T& val,
924 const label start,
925 const ComparePredicate& comp
926)
927{
928 label low = start;
929 label high = input.size() - 1;
930
931 if (start < 0 || start >= input.size())
932 {
933 return -1;
934 }
935
936 while ((high - low) > 1)
937 {
938 const label mid = (low + high)/2;
939
940 if (comp(input[mid], val))
941 {
942 low = mid;
943 }
944 else
945 {
946 high = mid;
947 }
948 }
949
950 if (comp(input[high], val))
951 {
952 return high;
953 }
954 else if (comp(input[low], val))
955 {
956 return low;
957 }
958 else
959 {
960 return -1;
961 }
962}
963
964
965template<class ListType, class T>
966Foam::label Foam::findLower
967(
968 const ListType& input,
969 const T& val,
970 const label start
971)
972{
973 return findLower
974 (
975 input,
976 val,
977 start,
978 lessOp<T>()
979 );
980}
981
982
983template<class ListType>
984ListType Foam::reverseList(const ListType& input)
985{
986 const label len = input.size();
987 const label last = (len - 1);
988
989 ListType output(len);
990 output.resize(len); // Consistent sizing (eg, DynamicList)
991
992 for (label i=0; i < len; ++i)
993 {
994 output[i] = input[last - i];
995 }
996
997 return output;
998}
999
1000
1001template<class ListType>
1002void Foam::inplaceReverseList(ListType& input)
1003{
1004 const label len = input.size();
1005 const label last = (len - 1);
1006 const label n2 = len >> 1;
1007
1008 for (label i=0; i<n2; ++i)
1009 {
1010 Foam::Swap(input[i], input[last - i]);
1011 }
1012}
1013
1014
1015template<class ListType>
1016ListType Foam::rotateList(const ListType& input, const label n)
1017{
1018 const label len = input.size();
1019
1020 ListType output(len);
1021 output.resize(len); // Consistent sizing (eg, DynamicList)
1022
1023 for (label i=0; i<len; ++i)
1024 {
1025 label index = (i - n) % len;
1026
1027 if (index < 0)
1028 {
1029 index += len;
1030 }
1031
1032 output[i] = input[index];
1033 }
1034
1035 return output;
1036}
1037
1038
1039template<template<typename> class ListType, class DataType>
1040void Foam::inplaceRotateList(ListType<DataType>& input, label n)
1041{
1042 const label len = input.size();
1043
1044 n = (len - n) % len;
1045
1046 if (n < 0)
1047 {
1048 n += len;
1049 }
1050
1051 SubList<DataType> firstHalf(input, n, 0);
1052 SubList<DataType> secondHalf(input, len - n, n);
1053
1054 inplaceReverseList(firstHalf);
1055 inplaceReverseList(secondHalf);
1056
1057 inplaceReverseList(input);
1058}
1059
1060
1061// * * * * * * * * * * * * * * * * * ListOps * * * * * * * * * * * * * * * * //
1062
1063template<class T>
1065(
1066 List<T>& x,
1067 const List<T>& y
1068) const
1069{
1070 if (y.size())
1071 {
1072 label len = x.size();
1073 if (len)
1074 {
1075 x.resize(len + y.size());
1076 for (const T& val : y)
1077 {
1078 x[len++] = val;
1079 }
1080 }
1081 else
1082 {
1083 x = y;
1084 }
1085 }
1086}
1087
1088
1089template<class T>
1091(
1092 List<T>& x,
1093 const List<T>& y
1094) const
1095{
1096 if (y.size())
1097 {
1098 if (x.size())
1099 {
1100 for (const T& val : y)
1101 {
1102 if (!x.found(val))
1103 {
1104 x.append(val);
1105 }
1106 }
1107 }
1108 else
1109 {
1110 x = y;
1111 }
1112 }
1113}
1114
1115
1116template<class ListType, class UnaryPredicate>
1117Foam::label Foam::ListOps::count_if
1118(
1119 const ListType& input,
1120 const UnaryPredicate& pred,
1121 const label start
1122)
1123{
1124 label num = 0;
1125
1126 const label len = input.size();
1127
1128 if (start >= 0)
1129 {
1130 for (label i = start; i < len; ++i)
1131 {
1132 if (pred(input[i]))
1133 {
1134 ++num;
1135 }
1136 }
1137 }
1138
1139 return num;
1140}
1141
1142
1143template<class ListType, class UnaryPredicate>
1144Foam::label Foam::ListOps::find_if
1145(
1146 const ListType& input,
1147 const UnaryPredicate& pred,
1148 const label start
1149)
1150{
1151 const label len = input.size();
1152
1153 if (start >= 0)
1154 {
1155 for (label i = start; i < len; ++i)
1156 {
1157 if (pred(input[i]))
1158 {
1159 return i;
1160 }
1161 }
1162 }
1163
1164 return -1;
1165}
1166
1167
1168template<class ListType, class UnaryPredicate>
1170(
1171 const ListType& input,
1172 const UnaryPredicate& pred,
1173 const label start
1174)
1175{
1176 return (ListOps::find_if(input, pred, start) >= 0);
1177}
1178
1179
1180template<class ListType, class UnaryPredicate>
1182(
1183 const ListType& input,
1184 const UnaryPredicate& pred,
1185 label start
1186)
1187{
1188 const label len = input.size();
1189
1190 // Pass 1: count occurrences where pred is true. ie, count_if()
1191 label count = 0;
1192
1193 if (start >= 0)
1194 {
1195 for (label i = start; i < len; ++i)
1196 {
1197 if (pred(input[i]))
1198 {
1199 if (!count) start = i; // adjust start for second pass
1200 ++count;
1201 }
1202 }
1203 }
1204
1205 labelList indices(count);
1206
1207 // Pass 2: fill content
1208 if (count)
1209 {
1210 const label total = count;
1211 count = 0;
1212 for (label i = start; i < len; ++i)
1213 {
1214 if (pred(input[i]))
1215 {
1216 indices[count] = i;
1217 if (++count == total) // early termination
1218 {
1219 break;
1220 }
1221 }
1222 }
1223 }
1224
1225 return indices;
1226}
1227
1228
1229template<class T>
1231(
1232 UList<T>& list,
1233 const labelUList& locations,
1234 const T& val
1235)
1236{
1237 const label len = list.size();
1238
1239 for (const label index : locations)
1240 {
1241 // Range-checked
1242 if (index >= 0 && index < len)
1243 {
1244 list[index] = val;
1245 }
1246 }
1247}
1248
1249
1250template<class T>
1252(
1253 UList<T>& list,
1254 const labelHashSet& locations,
1255 const T& val
1256)
1257{
1258 const label len = list.size();
1259
1260 for (const label index : locations)
1261 {
1262 // Range-checked
1263 if (index >= 0 && index < len)
1264 {
1265 list[index] = val;
1266 }
1267 }
1268}
1269
1270
1271template<class T>
1273(
1274 UList<T>& list,
1275 const UList<bool>& locations,
1276 const T& val
1277)
1278{
1279 const label len = list.size();
1280 const label count = locations.size();
1281 const label end = min(count, len);
1282
1283 // The efficiency is modest
1284 for (label index = 0; index < end; ++index)
1285 {
1286 if (locations[index])
1287 {
1288 list[index] = val;
1289 }
1290 }
1291}
1292
1293
1294template<class T>
1296(
1297 UList<T>& list,
1298 const bitSet& locations,
1299 const T& val
1300)
1301{
1302 const label len = list.size();
1303
1304 for
1305 (
1306 label pos = locations.find_first();
1307 pos >= 0 && pos < len;
1308 pos = locations.find_next(pos)
1309 )
1310 {
1311 list[pos] = val;
1312 }
1313}
1314
1315
1316template<class T, class T2, class UnaryOperation>
1318(
1319 const UList<T2>& input,
1320 const UnaryOperation& op
1321)
1322{
1323 const label len = input.size();
1324
1325 List<T> output(len);
1326
1327 if (len)
1328 {
1329 List_ACCESS(T, output, out);
1330 List_CONST_ACCESS(T2, input, in);
1331
1332 for (label i = 0; i < len; ++i)
1333 {
1334 out[i] = op(in[i]);
1335 }
1336 }
1337
1338 return output;
1339}
1340
1341
1342template<class T, class InputIterator, class UnaryOperation>
1344(
1345 InputIterator first,
1346 InputIterator last,
1347 const UnaryOperation& op
1348)
1349{
1350 const label len = std::distance(first, last);
1351
1352 List<T> output(len);
1353
1354 if (len)
1355 {
1356 T* out = output.begin();
1357
1358 while (first != last)
1359 {
1360 *out = op(*first);
1361 ++first;
1362 ++out;
1363 }
1364 }
1365
1366 return output;
1367}
1368
1369
1370template<class T>
1372(
1373 const label len,
1374 const labelUList& locations,
1375 const T& val,
1376 const T& deflt
1377)
1378{
1379 List<T> list(len, deflt);
1380 ListOps::setValue(list, locations, val);
1381
1382 return list;
1383}
1384
1385
1386template<class T>
1388(
1389 const label len,
1390 const labelHashSet& locations,
1391 const T& val,
1392 const T& deflt
1393)
1394{
1395 List<T> list(len, deflt);
1396 ListOps::setValue(list, locations, val);
1397
1398 return list;
1399}
1400
1401
1402template<class T>
1404(
1405 const label len,
1406 const UList<bool>& locations,
1407 const T& val,
1408 const T& deflt
1409)
1410{
1411 List<T> list(len, deflt);
1412 ListOps::setValue(list, locations, val);
1413
1414 return list;
1415}
1416
1417
1418template<class T>
1420(
1421 const label len,
1422 const bitSet& locations,
1423 const T& val,
1424 const T& deflt
1425)
1426{
1427 List<T> list(len, deflt);
1428 ListOps::setValue(list, locations, val);
1429
1430 return list;
1431}
1432
1433
1434template<class T>
1436(
1437 const label len,
1438 const label index,
1439 const T& val,
1440 const T& deflt
1441)
1442{
1443 List<T> list(len, deflt);
1444
1445 // Range-checked
1446 if (index >= 0 && index < len)
1447 {
1448 list[index] = val;
1449 }
1450
1451 return list;
1452}
1453
1454
1455template<class T>
1457(
1458 const label len,
1459 const label index,
1460 T&& val,
1461 const T& deflt
1462)
1463{
1464 List<T> list(len, deflt);
1465
1466 // Range-checked
1467 if (index >= 0 && index < len)
1468 {
1469 list[index] = std::move(val);
1470 }
1471
1472 return list;
1473}
1474
1475
1476// ************************************************************************* //
scalar y
Macros for accessing List elements.
#define List_ACCESS(type, f, fp)
Definition: ListLoopM.H:39
#define List_CONST_ACCESS(type, f, fp)
Definition: ListLoopM.H:43
Various functions to operate on Lists.
label n
static constexpr label size() noexcept
Return the number of elements in the FixedList.
Definition: FixedList.H:416
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
A dynamic list of packed unsigned integers, with the number of bits per item specified by the <Width>...
Definition: PackedList.H:129
A List obtained as a section of another List.
Definition: SubList.H:70
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:66
label find_next(label pos) const
Locate the next bit set, starting one beyond the specified position.
Definition: bitSetI.H:401
label find_first() const
Locate the first bit that is set.
Definition: bitSetI.H:314
friend Ostream & operator(Ostream &, const faMatrix< Type > &)
const volScalarField & T
List< bool > select(const label n, const labelUList &locations)
Definition: BitOps.C:142
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:78
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.
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.
List< T > createWithValue(const label len, const labelUList &locations, const T &val, const T &deflt=T())
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.
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:57
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 (not the indices) of a list.
List< label > labelList
A List of labels.
Definition: List.H:66
label findMin(const ListType &input, label start=0)
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 (not the indices) of 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)
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)
void Swap(DynamicList< T, SizeMinA > &a, DynamicList< T, SizeMinB > &b)
Definition: DynamicList.H:408
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:33
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:36
label findSortedIndex(const ListType &input, typename ListType::const_reference val, const label start=0)
label findMax(const ListType &input, label start=0)
labelList findIndices(const ListType &input, typename ListType::const_reference val, label start=0)
Linear search to find all occurrences of given element.
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:356
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
A list compare binary predicate for normal sort.
Definition: UList.H:188