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