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-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 
35 template<class IntListType>
36 IntListType 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 
59 template<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 
78 template<class ListType>
79 ListType Foam::reorder
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 
122 template<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 
173 template<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 
223 template<unsigned Width>
225 (
226  const labelUList& oldToNew,
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 
238 template<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 
263 template<class Container>
264 Foam::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 
294 template<class Container>
295 Foam::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 
324 template<class T>
326 (
327  const UList<T>& input
328 )
329 {
330  labelList order;
331  sortedOrder(input, order, typename UList<T>::less(input));
332  return order;
333 }
334 
335 
336 template<class T>
338 (
339  const UList<T>& input,
340  labelList& order
341 )
342 {
343  sortedOrder(input, order, typename UList<T>::less(input));
344 }
345 
346 
347 template<class T, class ListComparePredicate>
349 (
350  const UList<T>& input,
351  labelList& order,
352  const ListComparePredicate& comp
353 )
354 {
355  // List lengths must be identical. Old content is overwritten
356  order.resize_nocopy(input.size());
357 
358  ListOps::identity(order);
359 
360  Foam::stableSort(order, comp);
361 }
362 
363 
364 template<class T>
366 (
367  const UList<T>& input
368 )
369 {
370  labelList order;
371  duplicateOrder(input, order, typename UList<T>::less(input));
372  return order;
373 }
374 
375 
376 template<class T>
378 (
379  const UList<T>& input,
380  labelList& order
381 )
382 {
383  duplicateOrder(input, order, typename UList<T>::less(input));
384 }
385 
386 
387 template<class T, class ListComparePredicate>
389 (
390  const UList<T>& input,
391  labelList& order,
392  const ListComparePredicate& comp
393 )
394 {
395  if (input.size() < 2)
396  {
397  order.clear();
398  return;
399  }
400 
401  sortedOrder(input, order, comp);
402 
403  const label last = (order.size()-1);
404  label count = 0;
405  for (label i = 0; i < last; ++i)
406  {
407  if (input[order[i]] == input[order[i+1]])
408  {
409  order[count] = order[i];
410  ++count;
411  }
412  }
413  order.resize(count);
414 }
415 
416 
417 template<class T>
419 (
420  const UList<T>& input
421 )
422 {
423  labelList order;
424  uniqueOrder(input, order, typename UList<T>::less(input));
425  return order;
426 }
427 
428 
429 template<class T>
431 (
432  const UList<T>& input,
433  labelList& order
434 )
435 {
436  uniqueOrder(input, order, typename UList<T>::less(input));
437 }
438 
439 
440 template<class T, class ListComparePredicate>
442 (
443  const UList<T>& input,
444  labelList& order,
445  const ListComparePredicate& comp
446 )
447 {
448  sortedOrder(input, order, comp);
449 
450  if (order.size() > 1)
451  {
452  const label last = (order.size()-1);
453  label count = 0;
454  for (label i = 0; i < last; ++i)
455  {
456  if (input[order[i]] != input[order[i+1]])
457  {
458  order[count++] = order[i];
459  }
460  }
461  order[count++] = order[last];
462  order.resize(count);
463  }
464 }
465 
466 
467 template<class ListType>
469 {
471  (
472  input,
474  );
475 }
476 
477 
478 template<class ListType, class ListComparePredicate>
480 (
481  ListType& input,
482  const ListComparePredicate& comp
483 )
484 {
485  labelList order;
486  uniqueOrder(input, order, comp);
487 
488  const label len = order.size();
489 
490  ListType output(len);
491  output.resize(len); // Consistent sizing (eg, DynamicList)
492 
493  for (label i=0; i < len; ++i)
494  {
495  output[i] = std::move(input[order[i]]);
496  }
497 
498  input.transfer(output);
499 }
500 
501 
502 template<class BoolListType, class T>
504 (
505  const BoolListType& select,
506  const UList<T>& input,
507  const bool invert
508 )
509 {
510  // Note: select can have a different size (eg, labelHashSet)
511 
512  const label len = input.size();
513 
514  List<T> output(len);
515 
516  label count = 0;
517 
518  for (label i=0; i < len; ++i)
519  {
520  if (select[i] ? !invert : invert)
521  {
522  output[count] = input[i];
523  ++count;
524  }
525  }
526 
527  output.resize(count);
528 
529  return output;
530 }
531 
532 
533 template<class T>
535 (
536  const bitSet& select,
537  const UList<T>& input,
538  const bool invert
539 )
540 {
541  const label len = input.size();
542 
543  List<T> output;
544 
545  label count = 0;
546 
547  if (!invert)
548  {
549  output.resize(select.count());
550 
551  for (const label i : select)
552  {
553  if (i >= len) break; // Avoid out of bounds (when select is longer)
554 
555  output[count] = input[i];
556  ++count;
557  }
558  }
559  else
560  {
561  const label outlen = (select.size() - select.count());
562  output.resize(outlen);
563 
564  for (label i=0; i < len; ++i)
565  {
566  if (!select[i])
567  {
568  output[count] = input[i];
569  ++count;
570  if (count >= outlen) break; // terminate early
571  }
572  }
573  }
574 
575  output.resize(count);
576 
577  return output;
578 }
579 
580 
581 template<class BoolListType, class ListType>
583 (
584  const BoolListType& select,
585  ListType& input,
586  const bool invert
587 )
588 {
589  // Note: select can have a different size (eg, labelHashSet)
590 
591  const label len = input.size();
592 
593  label count = 0;
594 
595  for (label i=0; i < len; ++i)
596  {
597  if (select[i] ? !invert : invert)
598  {
599  if (count != i)
600  {
601  input[count] = std::move(input[i]);
602  }
603  ++count;
604  }
605  }
606 
607  input.resize(count);
608 }
609 
610 
611 template<class ListType>
613 (
614  const bitSet& select,
615  ListType& input,
616  const bool invert
617 )
618 {
619  label count = 0;
620 
621  if (!invert)
622  {
623  // Normal selection
624 
625  const label len = input.size();
626 
627  for (const label i : select)
628  {
629  if (i >= len) break;
630 
631  if (count != i)
632  {
633  input[count] = std::move(input[i]);
634  }
635  ++count;
636  }
637  }
638  else
639  {
640  // Inverted selection
641 
642  const label outlen = (select.size() - select.count());
643 
644  const label len = min(input.size(), select.size());
645 
646  for (label i=0; i < len; ++i)
647  {
648  if (!select[i])
649  {
650  if (count != i)
651  {
652  input[count] = std::move(input[i]);
653  }
654  ++count;
655  if (count >= outlen) break; // terminate early
656  }
657  }
658  }
659 
660  input.resize(count);
661 }
662 
663 
664 template<class T, class UnaryPredicate>
666 (
667  const UList<T>& input,
668  const UnaryPredicate& pred,
669  const bool invert
670 )
671 {
672  const label len = input.size();
673 
674  List<T> output(len);
675 
676  label count = 0;
677  for (label i=0; i < len; ++i)
678  {
679  if (pred(input[i]) ? !invert : invert)
680  {
681  output[count] = input[i];
682  ++count;
683  }
684  }
685 
686  output.resize(count);
687 
688  return output;
689 }
690 
691 
692 template<class ListType, class UnaryPredicate>
694 (
695  ListType& input,
696  const UnaryPredicate& pred,
697  const bool invert
698 )
699 {
700  const label len = input.size();
701 
702  label count = 0;
703  for (label i=0; i < len; ++i)
704  {
705  if (pred(input[i]) ? !invert : invert)
706  {
707  if (count != i)
708  {
709  input[count] = std::move(input[i]);
710  }
711  ++count;
712  }
713  }
714  input.resize(count);
715 }
716 
717 
718 template<class InputIntListType, class OutputIntListType>
720 (
721  const label len,
724 )
725 {
726  // The output list sizes
727  labelList sizes(len, Zero);
728 
729  for (const InputIntListType& sublist : input)
730  {
731  forAll(sublist, idx)
732  {
733  sizes[sublist[idx]]++;
734  }
735  }
736 
737  // Size output
738  output.resize(len);
739  forAll(sizes, outi)
740  {
741  output[outi].resize(sizes[outi]);
742  }
743 
744  // Fill output
745  sizes = 0;
746  forAll(input, listi)
747  {
748  const InputIntListType& sublist = input[listi];
749 
750  forAll(sublist, idx)
751  {
752  const label outi = sublist[idx];
753 
754  output[outi][sizes[outi]++] = listi;
755  }
756  }
757 }
758 
759 
760 template<class ListType>
762 (
763  const ListType& input,
764  typename ListType::const_reference val,
765  label start
766 )
767 {
768  const label len = input.size();
769 
770  // Pass 1: count occurrences
771  label count = 0;
772 
773  if (start >= 0)
774  {
775  for (label i = start; i < len; ++i)
776  {
777  if (input[i] == val)
778  {
779  if (!count) start = i; // adjust start for second pass
780  ++count;
781  }
782  }
783  }
784 
785  labelList indices(count);
786 
787  // Pass 2: fill content
788  if (count)
789  {
790  const label total = count;
791  count = 0;
792  for (label i = start; i < len; ++i)
793  {
794  if (input[i] == val)
795  {
796  indices[count] = i;
797  if (++count == total) // early termination
798  {
799  break;
800  }
801  }
802  }
803  }
804 
805  return indices;
806 }
807 
808 
809 template<class ListType>
810 Foam::label Foam::findMin
811 (
812  const ListType& input,
813  label start
814 )
815 {
816  const label len = input.size();
817 
818  if (start < 0 || start >= len)
819  {
820  return -1;
821  }
822 
823  for (label i = start+1; i < len; ++i)
824  {
825  if (input[i] < input[start])
826  {
827  start = i;
828  }
829  }
830 
831  return start;
832 }
833 
834 
835 template<class ListType>
836 Foam::label Foam::findMax
837 (
838  const ListType& input,
839  label start
840 )
841 {
842  const label len = input.size();
843 
844  if (start < 0 || start >= len)
845  {
846  return -1;
847  }
848 
849  for (label i = start+1; i < len; ++i)
850  {
851  if (input[start] < input[i])
852  {
853  start = i;
854  }
855  }
856 
857  return start;
858 }
859 
860 
861 template<class ListType>
863 (
864  const ListType& input,
865  label start
866 )
867 {
868  const label len = input.size();
869 
870  if (start < 0 || start >= len)
871  {
872  return labelPair(-1,-1);
873  }
874 
875  label minIdx = start;
876  label maxIdx = start;
877 
878  for (label i = start+1; i < len; ++i)
879  {
880  if (input[i] < input[minIdx])
881  {
882  minIdx = i;
883  }
884  if (input[maxIdx] < input[i])
885  {
886  maxIdx = i;
887  }
888  }
889 
890  return labelPair(minIdx, maxIdx);
891 }
892 
893 
894 template<class ListType>
895 Foam::label Foam::findSortedIndex
896 (
897  const ListType& input,
898  typename ListType::const_reference val,
899  const label start
900 )
901 {
902  label low = start;
903  label high = input.size() - 1;
904 
905  if (start < 0 || start >= input.size())
906  {
907  return -1;
908  }
909 
910  while (low <= high)
911  {
912  const label mid = (low + high)/2;
913 
914  if (val < input[mid])
915  {
916  high = mid - 1;
917  }
918  else if (input[mid] < val)
919  {
920  low = mid + 1;
921  }
922  else
923  {
924  return mid;
925  }
926  }
927 
928  return -1;
929 }
930 
931 
932 template<class ListType, class T, class ComparePredicate>
933 Foam::label Foam::findLower
934 (
935  const ListType& input,
936  const T& val,
937  const label start,
938  const ComparePredicate& comp
939 )
940 {
941  label low = start;
942  label high = input.size() - 1;
943 
944  if (start < 0 || start >= input.size())
945  {
946  return -1;
947  }
948 
949  while ((high - low) > 1)
950  {
951  const label mid = (low + high)/2;
952 
953  if (comp(input[mid], val))
954  {
955  low = mid;
956  }
957  else
958  {
959  high = mid;
960  }
961  }
962 
963  if (comp(input[high], val))
964  {
965  return high;
966  }
967  else if (comp(input[low], val))
968  {
969  return low;
970  }
971  else
972  {
973  return -1;
974  }
975 }
976 
977 
978 template<class ListType, class T>
979 Foam::label Foam::findLower
980 (
981  const ListType& input,
982  const T& val,
983  const label start
984 )
985 {
986  return findLower
987  (
988  input,
989  val,
990  start,
991  lessOp<T>()
992  );
993 }
994 
995 
996 template<class ListType>
997 ListType Foam::reverseList(const ListType& input)
998 {
999  const label len = input.size();
1000  const label last = (len - 1);
1001 
1002  ListType output(len);
1003  output.resize(len); // Consistent sizing (eg, DynamicList)
1004 
1005  for (label i=0; i < len; ++i)
1006  {
1007  output[i] = input[last - i];
1008  }
1009 
1010  return output;
1011 }
1012 
1013 
1014 template<class ListType>
1016 {
1017  const label len = input.size();
1018  const label last = (len - 1);
1019  const label n2 = len >> 1;
1020 
1021  for (label i=0; i<n2; ++i)
1022  {
1023  Foam::Swap(input[i], input[last - i]);
1024  }
1025 }
1026 
1027 
1028 template<class ListType>
1029 ListType Foam::rotateList(const ListType& input, const label n)
1030 {
1031  const label len = input.size();
1032 
1033  ListType output(len);
1034  output.resize(len); // Consistent sizing (eg, DynamicList)
1035 
1036  for (label i=0; i<len; ++i)
1037  {
1038  label index = (i - n) % len;
1039 
1040  if (index < 0)
1041  {
1042  index += len;
1043  }
1044 
1045  output[i] = input[index];
1046  }
1047 
1048  return output;
1049 }
1050 
1051 
1052 template<template<typename> class ListType, class DataType>
1053 void Foam::inplaceRotateList(ListType<DataType>& input, label n)
1054 {
1055  const label len = input.size();
1056 
1057  n = (len - n) % len;
1058 
1059  if (n < 0)
1060  {
1061  n += len;
1062  }
1063 
1064  SubList<DataType> firstHalf(input, n, 0);
1065  SubList<DataType> secondHalf(input, len - n, n);
1066 
1067  inplaceReverseList(firstHalf);
1068  inplaceReverseList(secondHalf);
1069 
1071 }
1072 
1073 
1074 // * * * * * * * * * * * * * * * * * ListOps * * * * * * * * * * * * * * * * //
1075 
1076 template<class T>
1079  List<T>& x,
1080  const List<T>& y
1081 ) const
1082 {
1083  if (y.size())
1084  {
1085  label len = x.size();
1086  if (len)
1087  {
1088  x.resize(len + y.size());
1089  for (const T& val : y)
1090  {
1091  x[len++] = val;
1092  }
1093  }
1094  else
1095  {
1096  x = y;
1097  }
1098  }
1099 }
1100 
1101 
1102 template<class T>
1105  List<T>& x,
1106  const List<T>& y
1107 ) const
1108 {
1109  if (y.size())
1110  {
1111  if (x.size())
1112  {
1113  for (const T& val : y)
1114  {
1115  if (!x.found(val))
1116  {
1117  x.append(val);
1118  }
1119  }
1120  }
1121  else
1122  {
1123  x = y;
1124  }
1125  }
1126 }
1127 
1128 
1129 template<class ListType, class UnaryPredicate>
1130 Foam::label Foam::ListOps::find
1131 (
1132  const ListType& input,
1133  const UnaryPredicate& pred,
1134  const label start
1135 )
1136 {
1137  const label len = input.size();
1138 
1139  if (start >= 0)
1140  {
1141  for (label i = start; i < len; ++i)
1142  {
1143  if (pred(input[i]))
1144  {
1145  return i;
1146  }
1147  }
1148  }
1149 
1150  return -1;
1151 }
1152 
1153 
1154 template<class ListType, class UnaryPredicate>
1157  const ListType& input,
1158  const UnaryPredicate& pred,
1159  const label start
1160 )
1161 {
1162  return (ListOps::find(input, pred, start) >= 0);
1163 }
1164 
1165 
1166 template<class ListType, class UnaryPredicate>
1168 (
1169  const ListType& input,
1170  const UnaryPredicate& pred,
1171  label start
1172 )
1173 {
1174  const label len = input.size();
1175 
1176  // Pass 1: count occurrences
1177  label count = 0;
1178 
1179  if (start >= 0)
1180  {
1181  for (label i = start; i < len; ++i)
1182  {
1183  if (pred(input[i]))
1184  {
1185  if (!count) start = i; // adjust start for second pass
1186  ++count;
1187  }
1188  }
1189  }
1190 
1191  labelList indices(count);
1192 
1193  // Pass 2: fill content
1194  if (count)
1195  {
1196  const label total = count;
1197  count = 0;
1198  for (label i = start; i < len; ++i)
1199  {
1200  if (pred(input[i]))
1201  {
1202  indices[count] = i;
1203  if (++count == total) // early termination
1204  {
1205  break;
1206  }
1207  }
1208  }
1209  }
1210 
1211  return indices;
1212 }
1213 
1214 
1215 template<class T>
1218  UList<T>& list,
1219  const labelUList& locations,
1220  const T& val
1221 )
1222 {
1223  const label len = list.size();
1224 
1225  for (const label index : locations)
1226  {
1227  // Range-checked
1228  if (index >= 0 && index < len)
1229  {
1230  list[index] = val;
1231  }
1232  }
1233 }
1234 
1235 
1236 template<class T>
1239  UList<T>& list,
1240  const labelHashSet& locations,
1241  const T& val
1242 )
1243 {
1244  const label len = list.size();
1245 
1246  for (const label index : locations)
1247  {
1248  // Range-checked
1249  if (index >= 0 && index < len)
1250  {
1251  list[index] = val;
1252  }
1253  }
1254 }
1255 
1256 
1257 template<class T>
1260  UList<T>& list,
1261  const UList<bool>& locations,
1262  const T& val
1263 )
1264 {
1265  const label len = list.size();
1266  const label count = locations.size();
1267  const label end = min(count, len);
1268 
1269  // The efficiency is modest
1270  for (label index = 0; index < end; ++index)
1271  {
1272  if (locations[index])
1273  {
1274  list[index] = val;
1275  }
1276  }
1277 }
1278 
1279 
1280 template<class T>
1283  UList<T>& list,
1284  const bitSet& locations,
1285  const T& val
1286 )
1287 {
1288  const label len = list.size();
1289 
1290  for
1291  (
1292  label pos = locations.find_first();
1293  pos >= 0 && pos < len;
1294  pos = locations.find_next(pos)
1295  )
1296  {
1297  list[pos] = val;
1298  }
1299 }
1300 
1301 
1302 template<class T, class T2, class UnaryOperation>
1304 (
1305  const UList<T2>& input,
1306  const UnaryOperation& op
1307 )
1308 {
1309  const label len = input.size();
1310 
1311  List<T> output(len);
1312 
1313  if (len)
1314  {
1315  List_ACCESS(T, output, out);
1316  List_CONST_ACCESS(T2, input, in);
1317 
1318  for (label i = 0; i < len; ++i)
1319  {
1320  out[i] = op(in[i]);
1321  }
1322  }
1323 
1324  return output;
1325 }
1326 
1327 
1328 template<class T, class InputIterator, class UnaryOperation>
1330 (
1331  InputIterator first,
1332  InputIterator last,
1333  const UnaryOperation& op
1334 )
1335 {
1336  const label len = std::distance(first, last);
1337 
1338  List<T> output(len);
1339 
1340  if (len)
1341  {
1342  T* out = output.begin();
1343 
1344  while (first != last)
1345  {
1346  *out = op(*first);
1347  ++first;
1348  ++out;
1349  }
1350  }
1351 
1352  return output;
1353 }
1354 
1355 
1356 template<class T>
1358 (
1359  const label len,
1360  const labelUList& locations,
1361  const T& val,
1362  const T& deflt
1363 )
1364 {
1365  List<T> list(len, deflt);
1366  ListOps::setValue(list, locations, val);
1367 
1368  return list;
1369 }
1370 
1371 
1372 template<class T>
1374 (
1375  const label len,
1376  const labelHashSet& locations,
1377  const T& val,
1378  const T& deflt
1379 )
1380 {
1381  List<T> list(len, deflt);
1382  ListOps::setValue(list, locations, val);
1383 
1384  return list;
1385 }
1386 
1387 
1388 template<class T>
1390 (
1391  const label len,
1392  const UList<bool>& locations,
1393  const T& val,
1394  const T& deflt
1395 )
1396 {
1397  List<T> list(len, deflt);
1398  ListOps::setValue(list, locations, val);
1399 
1400  return list;
1401 }
1402 
1403 
1404 template<class T>
1406 (
1407  const label len,
1408  const bitSet& locations,
1409  const T& val,
1410  const T& deflt
1411 )
1412 {
1413  List<T> list(len, deflt);
1414  ListOps::setValue(list, locations, val);
1415 
1416  return list;
1417 }
1418 
1419 
1420 template<class T>
1422 (
1423  const label len,
1424  const label index,
1425  const T& val,
1426  const T& deflt
1427 )
1428 {
1429  List<T> list(len, deflt);
1430 
1431  // Range-checked
1432  if (index >= 0 && index < len)
1433  {
1434  list[index] = val;
1435  }
1436 
1437  return list;
1438 }
1439 
1440 
1441 template<class T>
1443 (
1444  const label len,
1445  const label index,
1446  T&& val,
1447  const T& deflt
1448 )
1449 {
1450  List<T> list(len, deflt);
1451 
1452  // Range-checked
1453  if (index >= 0 && index < len)
1454  {
1455  list[index] = std::move(val);
1456  }
1457 
1458  return list;
1459 }
1460 
1461 
1462 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::bitSet::find_first
label find_first() const
Locate the first bit that is set.
Definition: bitSetI.H:314
Foam::Swap
void Swap(DynamicList< T, SizeMinA > &a, DynamicList< T, SizeMinB > &b)
Definition: DynamicList.H:429
Foam::output
static Ostream & output(Ostream &os, const IntRange< T > &range)
Definition: IntRanges.C:66
Foam::inplaceSubsetList
void inplaceSubsetList(ListType &input, const UnaryPredicate &pred, const bool invert=false)
Inplace subset of the list when predicate is true.
Definition: ListOpsTemplates.C:694
Foam::inplaceReverseList
void inplaceReverseList(ListType &input)
Inplace reversal of a list using Swap.
Definition: ListOpsTemplates.C:1015
Foam::uniqueOrder
labelList uniqueOrder(const UList< T > &input)
Return (sorted) indices corresponding to unique list values.
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:63
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::less
static bool less(const vector &x, const vector &y)
To compare normals.
Definition: meshRefinementRefine.C:57
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:54
Foam::ListOps::create
List< T > create(const UList< T2 > &input, const UnaryOperation &op)
Create a List from a List of a dissimilar type, using the entire list.
Foam::subset
List< T > subset(const BoolListType &select, const UList< T > &input, const bool invert=false)
Extract elements of the input list when select is true.
Foam::inplaceRotateList
void inplaceRotateList(ListType< DataType > &list, label n)
Inplace reversal of a list using the Reversal Block Swapping algorithm.
Definition: ListOpsTemplates.C:1053
Foam::inplaceUniqueSort
void inplaceUniqueSort(ListType &input)
Inplace sorting and removal of duplicates.
Definition: ListOpsTemplates.C:468
Foam::ListOps::createWithValue
List< T > createWithValue(const label len, const labelUList &locations, const T &val, const T &deflt=T())
Foam::List::resize_nocopy
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition: ListI.H:146
Foam::HashSet< label, Hash< label > >
Foam::bitSet::count
unsigned int count(const bool on=true) const
Count number of bits set.
Definition: bitSetI.H:499
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Foam::invert
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:36
Foam::inplaceRenumber
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:61
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::stableSort
void stableSort(UList< T > &a)
Definition: UList.C:275
Foam::invertManyToMany
void invertManyToMany(const label len, const UList< InputIntListType > &input, List< OutputIntListType > &output)
Invert many-to-many.
Definition: ListOpsTemplates.C:720
Foam::labelPair
Pair< label > labelPair
A pair of labels.
Definition: Pair.H:54
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::findMinMax
labelPair findMinMax(const ListType &input, label start=0)
Foam::ListOps::findIndices
labelList findIndices(const ListType &input, const UnaryPredicate &pred, label start=0)
Linear search to find all occurences of given element.
Foam::inplaceMapKey
void inplaceMapKey(const labelUList &oldToNew, Container &input)
Rewrite with mapped keys. Ignore elements with negative key.
Definition: ListOpsTemplates.C:240
Foam::findLower
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Foam::reorder
ListType reorder(const labelUList &oldToNew, const ListType &input, const bool prune=false)
Reorder the elements of a list.
Definition: ListOpsTemplates.C:80
Foam::UList::less
A list compare binary predicate for normal sort.
Definition: UList.H:187
Foam::findSortedIndex
label findSortedIndex(const ListType &input, typename ListType::const_reference val, const label start=0)
Foam::inplaceMapValue
label inplaceMapValue(const labelUList &oldToNew, Container &input)
Map values. Ignore negative values.
Foam::duplicateOrder
labelList duplicateOrder(const UList< T > &input)
Return (sorted) indices corresponding to duplicate list values.
Foam::bitSet::find_next
label find_next(label pos) const
Locate the next bit set, starting one beyond the specified position.
Definition: bitSetI.H:400
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam::ListOps::find
label find(const ListType &input, const UnaryPredicate &pred, const label start=0)
Find index of the first occurrence that satisfies the predicate.
Foam::rotateList
ListType rotateList(const ListType &list, const label n)
Rotate a list by n places.
Definition: ListOpsTemplates.C:1029
T
const volScalarField & T
Definition: createFieldRefs.H:2
Foam::ListOps::uniqueEqOp
List helper to append y unique elements onto the end of x.
Definition: ListOps.H:577
Foam::inplaceSubset
void inplaceSubset(const BoolListType &select, ListType &input, const bool invert=false)
Inplace extract elements of the input list when select is true.
Definition: ListOpsTemplates.C:583
Foam::distance
scalar distance(const vector &p1, const vector &p2)
Definition: curveTools.C:12
Foam::ListOps::appendEqOp
List helper to append y elements onto the end of x.
Definition: ListOps.H:570
Foam::reverseList
ListType reverseList(const ListType &input)
Reverse a list. First element becomes last element etc.
Definition: ListOpsTemplates.C:997
Foam::renumber
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:37
List_CONST_ACCESS
#define List_CONST_ACCESS(type, f, fp)
Definition: ListLoopM.H:43
Foam::Pair< label >
Foam::ListOps::setValue
void setValue(UList< T > &list, const labelUList &locations, const T &val)
Set various locations of the list with a specified value.
Definition: ListOpsTemplates.C:1217
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:77
Foam::findMax
label findMax(const ListType &input, label start=0)
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::PackedList
A dynamic list of packed unsigned integers, with the number of bits per item specified by the <Width>...
Definition: PackedList.H:108
Foam::PackedList::size
label size() const noexcept
Number of entries.
Definition: PackedListI.H:377
Foam::UList< label >
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
Foam::input
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:55
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::ListOps::found
bool found(const ListType &input, const UnaryPredicate &pred, const label start=0)
True if there is a value in the list that satisfies the predicate.
Definition: ListOpsTemplates.C:1156
Foam::findIndices
labelList findIndices(const ListType &input, typename ListType::const_reference val, label start=0)
Linear search to find all occurrences of given element.
Foam::inplaceReorder
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
Definition: ListOpsTemplates.C:124
ListOps.H
Various functions to operate on Lists.
Foam::sortedOrder
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
List_ACCESS
#define List_ACCESS(type, f, fp)
Definition: ListLoopM.H:39
Foam::findMin
label findMin(const ListType &input, label start=0)
y
scalar y
Definition: LISASMDCalcMethod1.H:14
ListLoopM.H
Macros for accessing List elements.
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:177
Foam::subsetList
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.