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