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-2023 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.good() && value != mapIter.val())
310  {
311  value = mapIter.val();
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  // --> x.push_uniq(val)
1099  if (!x.contains(val))
1100  {
1101  x.push_back(val);
1102  }
1103  }
1104  }
1105  else
1106  {
1107  x = y;
1108  }
1109  }
1110 }
1111 
1112 
1113 template<class ListType, class UnaryPredicate>
1114 Foam::label Foam::ListOps::count_if
1115 (
1116  const ListType& input,
1117  const UnaryPredicate& pred,
1118  const label start
1119 )
1120 {
1121  label num = 0;
1122 
1123  const label len = input.size();
1124 
1125  if (start >= 0)
1126  {
1127  for (label i = start; i < len; ++i)
1128  {
1129  if (pred(input[i]))
1130  {
1131  ++num;
1132  }
1133  }
1134  }
1135 
1136  return num;
1137 }
1138 
1139 
1140 template<class ListType, class UnaryPredicate>
1141 Foam::label Foam::ListOps::find_if
1142 (
1143  const ListType& input,
1144  const UnaryPredicate& pred,
1145  const label start
1146 )
1147 {
1148  const label len = input.size();
1149 
1150  if (start >= 0)
1151  {
1152  for (label i = start; i < len; ++i)
1153  {
1154  if (pred(input[i]))
1155  {
1156  return i;
1157  }
1158  }
1159  }
1161  return -1;
1162 }
1163 
1164 
1165 template<class ListType, class UnaryPredicate>
1167 (
1168  const ListType& input,
1169  const UnaryPredicate& pred,
1170  const label start
1171 )
1172 {
1173  return (ListOps::find_if(input, pred, start) >= 0);
1174 }
1175 
1176 
1177 template<class ListType, class UnaryPredicate>
1179 (
1180  const ListType& input,
1181  const UnaryPredicate& pred,
1182  label start
1183 )
1184 {
1185  const label len = input.size();
1186 
1187  // Pass 1: count occurrences where pred is true. ie, count_if()
1188  label count = 0;
1189 
1190  if (start >= 0)
1191  {
1192  for (label i = start; i < len; ++i)
1193  {
1194  if (pred(input[i]))
1195  {
1196  if (!count) start = i; // adjust start for second pass
1197  ++count;
1198  }
1199  }
1200  }
1201 
1202  labelList indices(count);
1203 
1204  // Pass 2: fill content
1205  if (count)
1206  {
1207  const label total = count;
1208  count = 0;
1209  for (label i = start; i < len; ++i)
1210  {
1211  if (pred(input[i]))
1212  {
1213  indices[count] = i;
1214  if (++count == total) // early termination
1215  {
1216  break;
1217  }
1218  }
1219  }
1220  }
1222  return indices;
1223 }
1224 
1225 
1226 template<class T>
1228 (
1229  UList<T>& list,
1230  const labelUList& locations,
1231  const T& val
1232 )
1233 {
1234  const label len = list.size();
1235 
1236  for (const label index : locations)
1237  {
1238  // Range-checked
1239  if (index >= 0 && index < len)
1240  {
1241  list[index] = val;
1242  }
1243  }
1244 }
1245 
1246 
1247 template<class T>
1249 (
1250  UList<T>& list,
1251  const labelHashSet& locations,
1252  const T& val
1253 )
1254 {
1255  const label len = list.size();
1256 
1257  for (const label index : locations)
1258  {
1259  // Range-checked
1260  if (index >= 0 && index < len)
1261  {
1262  list[index] = val;
1263  }
1264  }
1265 }
1266 
1267 
1268 template<class T>
1270 (
1271  UList<T>& list,
1272  const UList<bool>& locations,
1273  const T& val
1274 )
1275 {
1276  const label len = list.size();
1277  const label count = locations.size();
1278  const label end = min(count, len);
1279 
1280  // The efficiency is modest
1281  for (label index = 0; index < end; ++index)
1282  {
1283  if (locations[index])
1284  {
1285  list[index] = val;
1286  }
1287  }
1288 }
1289 
1290 
1291 template<class T>
1293 (
1294  UList<T>& list,
1295  const bitSet& locations,
1296  const T& val
1297 )
1298 {
1299  const label len = list.size();
1300 
1301  for
1302  (
1303  label pos = locations.find_first();
1304  pos >= 0 && pos < len;
1305  pos = locations.find_next(pos)
1306  )
1307  {
1308  list[pos] = val;
1309  }
1310 }
1311 
1312 
1313 template<class T, class T2, class UnaryOperation>
1315 (
1316  const UList<T2>& input,
1317  const UnaryOperation& op
1318 )
1319 {
1320  const label len = input.size();
1321 
1322  List<T> output(len);
1323 
1324  // ie, std::transform(input.begin(), input.end(), output.begin(), op);
1325 
1326  const T2* in = input.begin();
1327  T* out = output.begin();
1328 
1329  for (label i = 0; i < len; ++i)
1330  {
1331  out[i] = op(in[i]);
1332  }
1333 
1334  return output;
1335 }
1336 
1337 
1338 template<class T, class InputIterator, class UnaryOperation>
1340 (
1341  InputIterator first,
1342  InputIterator last,
1343  const UnaryOperation& op
1344 )
1345 {
1346  const label len = std::distance(first, last);
1347 
1348  List<T> output(len);
1349 
1350  // ie, std::transform(first, last, output.begin(), op);
1351 
1352  T* out = output.begin();
1353 
1354  while (first != last)
1355  {
1356  *out = op(*first);
1357  ++first;
1358  ++out;
1359  }
1360 
1361  return output;
1362 }
1363 
1364 
1365 template<class T>
1367 (
1368  const label len,
1369  const labelUList& locations,
1370  const T& val,
1371  const T& deflt
1372 )
1373 {
1374  List<T> list(len, deflt);
1375  ListOps::setValue(list, locations, val);
1376 
1377  return list;
1378 }
1379 
1380 
1381 template<class T>
1383 (
1384  const label len,
1385  const labelHashSet& locations,
1386  const T& val,
1387  const T& deflt
1388 )
1389 {
1390  List<T> list(len, deflt);
1391  ListOps::setValue(list, locations, val);
1392 
1393  return list;
1394 }
1395 
1396 
1397 template<class T>
1399 (
1400  const label len,
1401  const UList<bool>& locations,
1402  const T& val,
1403  const T& deflt
1404 )
1405 {
1406  List<T> list(len, deflt);
1407  ListOps::setValue(list, locations, val);
1408 
1409  return list;
1410 }
1411 
1412 
1413 template<class T>
1415 (
1416  const label len,
1417  const bitSet& locations,
1418  const T& val,
1419  const T& deflt
1420 )
1421 {
1422  List<T> list(len, deflt);
1423  ListOps::setValue(list, locations, val);
1424 
1425  return list;
1426 }
1427 
1428 
1429 template<class T>
1431 (
1432  const label len,
1433  const label index,
1434  const T& val,
1435  const T& deflt
1436 )
1437 {
1438  List<T> list(len, deflt);
1439 
1440  // Range-checked
1441  if (index >= 0 && index < len)
1442  {
1443  list[index] = val;
1444  }
1445 
1446  return list;
1447 }
1448 
1449 
1450 template<class T>
1452 (
1453  const label len,
1454  const label index,
1455  T&& val,
1456  const T& deflt
1457 )
1458 {
1459  List<T> list(len, deflt);
1460 
1461  // Range-checked
1462  if (index >= 0 && index < len)
1463  {
1464  list[index] = std::move(val);
1465  }
1466 
1467  return list;
1468 }
1469 
1470 
1471 // ************************************************************************* //
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:116
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:362
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:78
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:414
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:47
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:51
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:194
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:659
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:58
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:226
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:133