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  if (x.size())
1069  {
1070  x.push_back(y);
1071  }
1072  else
1073  {
1074  x = y;
1075  }
1076  }
1077 }
1078 
1079 
1080 template<class T>
1082 (
1083  List<T>& x,
1084  const List<T>& y
1085 ) const
1086 {
1087  if (y.size())
1088  {
1089  if (x.size())
1090  {
1091  for (const T& val : y)
1092  {
1093  x.push_uniq(val);
1094  }
1095  }
1096  else
1097  {
1098  x = y;
1099  }
1100  }
1101 }
1102 
1103 
1104 template<class ListType, class UnaryPredicate>
1105 Foam::label Foam::ListOps::count_if
1106 (
1107  const ListType& input,
1108  const UnaryPredicate& pred,
1109  const label start
1110 )
1111 {
1112  label num = 0;
1113 
1114  const label len = input.size();
1115 
1116  if (start >= 0)
1117  {
1118  for (label i = start; i < len; ++i)
1119  {
1120  if (pred(input[i]))
1121  {
1122  ++num;
1123  }
1124  }
1125  }
1126 
1127  return num;
1128 }
1129 
1130 
1131 template<class ListType, class UnaryPredicate>
1132 Foam::label Foam::ListOps::find_if
1133 (
1134  const ListType& input,
1135  const UnaryPredicate& pred,
1136  const label start
1137 )
1138 {
1139  const label len = input.size();
1140 
1141  if (start >= 0)
1142  {
1143  for (label i = start; i < len; ++i)
1144  {
1145  if (pred(input[i]))
1146  {
1147  return i;
1148  }
1149  }
1150  }
1152  return -1;
1153 }
1154 
1155 
1156 template<class ListType, class UnaryPredicate>
1158 (
1159  const ListType& input,
1160  const UnaryPredicate& pred,
1161  const label start
1162 )
1163 {
1164  return (ListOps::find_if(input, pred, start) >= 0);
1165 }
1166 
1167 
1168 template<class ListType, class UnaryPredicate>
1170 (
1171  const ListType& input,
1172  const UnaryPredicate& pred,
1173  label start
1174 )
1175 {
1176  const label len = input.size();
1177 
1178  // Pass 1: count occurrences where pred is true. ie, count_if()
1179  label count = 0;
1180 
1181  if (start >= 0)
1182  {
1183  for (label i = start; i < len; ++i)
1184  {
1185  if (pred(input[i]))
1186  {
1187  if (!count) start = i; // adjust start for second pass
1188  ++count;
1189  }
1190  }
1191  }
1192 
1193  labelList indices(count);
1194 
1195  // Pass 2: fill content
1196  if (count)
1197  {
1198  const label total = count;
1199  count = 0;
1200  for (label i = start; i < len; ++i)
1201  {
1202  if (pred(input[i]))
1203  {
1204  indices[count] = i;
1205  if (++count == total) // early termination
1206  {
1207  break;
1208  }
1209  }
1210  }
1211  }
1213  return indices;
1214 }
1215 
1216 
1217 template<class T>
1219 (
1220  UList<T>& list,
1221  const labelUList& locations,
1222  const T& val
1223 )
1224 {
1225  const label len = list.size();
1226 
1227  for (const label index : locations)
1228  {
1229  // Range-checked
1230  if (index >= 0 && index < len)
1231  {
1232  list[index] = val;
1233  }
1234  }
1235 }
1236 
1237 
1238 template<class T>
1240 (
1241  UList<T>& list,
1242  const labelHashSet& locations,
1243  const T& val
1244 )
1245 {
1246  const label len = list.size();
1247 
1248  for (const label index : locations)
1249  {
1250  // Range-checked
1251  if (index >= 0 && index < len)
1252  {
1253  list[index] = val;
1254  }
1255  }
1256 }
1257 
1258 
1259 template<class T>
1261 (
1262  UList<T>& list,
1263  const UList<bool>& locations,
1264  const T& val
1265 )
1266 {
1267  const label len = list.size();
1268  const label count = locations.size();
1269  const label end = min(count, len);
1270 
1271  // The efficiency is modest
1272  for (label index = 0; index < end; ++index)
1273  {
1274  if (locations[index])
1275  {
1276  list[index] = val;
1277  }
1278  }
1279 }
1280 
1281 
1282 template<class T>
1284 (
1285  UList<T>& list,
1286  const bitSet& locations,
1287  const T& val
1288 )
1289 {
1290  const label len = list.size();
1291 
1292  for
1293  (
1294  label pos = locations.find_first();
1295  pos >= 0 && pos < len;
1296  pos = locations.find_next(pos)
1297  )
1298  {
1299  list[pos] = val;
1300  }
1301 }
1302 
1303 
1304 template<class T, class T2, class UnaryOperation>
1306 (
1307  const UList<T2>& input,
1308  const UnaryOperation& op
1309 )
1310 {
1311  const label len = input.size();
1312 
1313  List<T> output(len);
1314 
1315  // ie, std::transform(input.begin(), input.end(), output.begin(), op);
1316 
1317  const T2* in = input.begin();
1318  T* out = output.begin();
1319 
1320  for (label i = 0; i < len; ++i)
1321  {
1322  out[i] = op(in[i]);
1323  }
1324 
1325  return output;
1326 }
1327 
1328 
1329 template<class T, class InputIterator, class UnaryOperation>
1331 (
1332  InputIterator first,
1333  InputIterator last,
1334  const UnaryOperation& op
1335 )
1336 {
1337  const label len = std::distance(first, last);
1338 
1339  List<T> output(len);
1340 
1341  // ie, std::transform(first, last, output.begin(), op);
1342 
1343  T* out = output.begin();
1344 
1345  while (first != last)
1346  {
1347  *out = op(*first);
1348  ++first;
1349  ++out;
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 // ************************************************************************* //
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:312
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:421
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:137
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:33
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:201
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)
Exchange contents of lists - see DynamicList::swap().
Definition: DynamicList.H:692
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:44
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:240
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127