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