BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / OpenFOAM / containers / Lists / ListOps / ListOpsTemplates.C
blob41e28c3f64eef5e008f2cb47f4ee0e0dddc4e5e5
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by
13     the Free Software Foundation, either version 3 of the License, or
14     (at your option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "ListOps.H"
28 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
30 template<class ListType>
31 ListType Foam::renumber
33     const labelUList& oldToNew,
34     const ListType& lst
37     // Create copy
38     ListType newLst(lst.size());
40     // ensure consistent addressable size (eg, DynamicList)
41     newLst.setSize(lst.size());
43     forAll(lst, elemI)
44     {
45         if (lst[elemI] >= 0)
46         {
47             newLst[elemI] = oldToNew[lst[elemI]];
48         }
49     }
51     return newLst;
55 template<class ListType>
56 void Foam::inplaceRenumber
58     const labelUList& oldToNew,
59     ListType& lst
62     forAll(lst, elemI)
63     {
64         if (lst[elemI] >= 0)
65         {
66             lst[elemI] = oldToNew[lst[elemI]];
67         }
68     }
72 template<class ListType>
73 ListType Foam::reorder
75     const labelUList& oldToNew,
76     const ListType& lst
79     // Create copy
80     ListType newLst(lst.size());
82     // ensure consistent addressable size (eg, DynamicList)
83     newLst.setSize(lst.size());
85     forAll(lst, elemI)
86     {
87         if (oldToNew[elemI] >= 0)
88         {
89             newLst[oldToNew[elemI]] = lst[elemI];
90         }
91         else
92         {
93             newLst[elemI] = lst[elemI];
94         }
95     }
96     return newLst;
100 template<class ListType>
101 void Foam::inplaceReorder
103     const labelUList& oldToNew,
104     ListType& lst
107     // Create copy
108     ListType newLst(lst.size());
110     // ensure consistent addressable size (eg, DynamicList)
111     newLst.setSize(lst.size());
113     forAll(lst, elemI)
114     {
115         if (oldToNew[elemI] >= 0)
116         {
117             newLst[oldToNew[elemI]] = lst[elemI];
118         }
119         else
120         {
121             newLst[elemI] = lst[elemI];
122         }
123     }
125     lst.transfer(newLst);
129 template<class Container>
130 void Foam::inplaceMapValue
132     const labelUList& oldToNew,
133     Container& lst
136     for
137     (
138         typename Container::iterator iter = lst.begin();
139         iter != lst.end();
140         ++iter
141     )
142     {
143         if (iter() >= 0)
144         {
145             iter() = oldToNew[iter()];
146         }
147     }
151 template<class Container>
152 void Foam::inplaceMapKey
154     const labelUList& oldToNew,
155     Container& lst
158     Container newLst(lst.size());
160     for
161     (
162         typename Container::iterator iter = lst.begin();
163         iter != lst.end();
164         ++iter
165     )
166     {
167         if (iter.key() >= 0)
168         {
169             newLst.insert(oldToNew[iter.key()], iter());
170         }
171     }
173     lst.transfer(newLst);
177 template<class T>
178 void Foam::sortedOrder
180     const UList<T>& lst,
181     labelList& order
184     // list lengths must be identical
185     if (order.size() != lst.size())
186     {
187         // avoid copying any elements, they are overwritten anyhow
188         order.clear();
189         order.setSize(lst.size());
190     }
192     forAll(order, elemI)
193     {
194         order[elemI] = elemI;
195     }
196     Foam::stableSort(order, typename UList<T>::less(lst));
200 template<class T>
201 void Foam::duplicateOrder
203     const UList<T>& lst,
204     labelList& order
207     if (lst.size() < 2)
208     {
209         order.clear();
210         return;
211     }
213     sortedOrder(lst, order);
215     label n = 0;
216     for (label i = 0; i < order.size() - 1; ++i)
217     {
218         if (lst[order[i]] == lst[order[i+1]])
219         {
220             order[n++] = order[i];
221         }
222     }
223     order.setSize(n);
227 template<class T>
228 void Foam::uniqueOrder
230     const UList<T>& lst,
231     labelList& order
234     sortedOrder(lst, order);
236     if (order.size() > 1)
237     {
238         label n = 0;
239         for (label i = 0; i < order.size() - 1; ++i)
240         {
241             if (lst[order[i]] != lst[order[i+1]])
242             {
243                 order[n++] = order[i];
244             }
245         }
246         order[n++] = order[order.size()-1];
247         order.setSize(n);
248     }
252 template<class T, class ListType>
253 ListType Foam::subset
255     const UList<T>& select,
256     const T& value,
257     const ListType& lst
260     // select must at least cover the list range
261     if (select.size() < lst.size())
262     {
263         FatalErrorIn("subset(const UList<T>&, const T&, const ListType&)")
264             << "select is of size " << select.size()
265             << "; but it must index a list of size " << lst.size()
266             << abort(FatalError);
267     }
269     ListType newLst(lst.size());
271     // ensure consistent addressable size (eg, DynamicList)
272     newLst.setSize(lst.size());
274     label nElem = 0;
275     forAll(lst, elemI)
276     {
277         if (select[elemI] == value)
278         {
279             newLst[nElem++] = lst[elemI];
280         }
281     }
282     newLst.setSize(nElem);
284     return newLst;
288 template<class T, class ListType>
289 void Foam::inplaceSubset
291     const UList<T>& select,
292     const T& value,
293     ListType& lst
296     // select must at least cover the list range
297     if (select.size() < lst.size())
298     {
299         FatalErrorIn("inplaceSubset(const UList<T>&, const T&, ListType&)")
300             << "select is of size " << select.size()
301             << "; but it must index a list of size " << lst.size()
302             << abort(FatalError);
303     }
305     label nElem = 0;
306     forAll(lst, elemI)
307     {
308         if (select[elemI] == value)
309         {
310             if (nElem != elemI)
311             {
312                 lst[nElem] = lst[elemI];
313             }
314             ++nElem;
315         }
316     }
318     lst.setSize(nElem);
322 template<class BoolListType, class ListType>
323 ListType Foam::subset
325     const BoolListType& select,
326     const ListType& lst
329     // select can have a different size
330     // eg, when it is a PackedBoolList or a labelHashSet
332     ListType newLst(lst.size());
334     // ensure consistent addressable size (eg, DynamicList)
335     newLst.setSize(lst.size());
337     label nElem = 0;
338     forAll(lst, elemI)
339     {
340         if (select[elemI])
341         {
342             newLst[nElem++] = lst[elemI];
343         }
344     }
345     newLst.setSize(nElem);
347     return newLst;
351 template<class BoolListType, class ListType>
352 void Foam::inplaceSubset
354     const BoolListType& select,
355     ListType& lst
358     // select can have a different size
359     // eg, when it is a PackedBoolList or a labelHashSet
361     label nElem = 0;
362     forAll(lst, elemI)
363     {
364         if (select[elemI])
365         {
366             if (nElem != elemI)
367             {
368                 lst[nElem] = lst[elemI];
369             }
370             ++nElem;
371         }
372     }
374     lst.setSize(nElem);
378 // As clarification:
379 // coded as inversion from pointEdges to edges but completely general.
380 template<class InList, class OutList>
381 void Foam::invertManyToMany
383     const label nEdges,
384     const UList<InList>& pointEdges,
385     List<OutList>& edges
388     // Number of points per edge
389     labelList nPointsPerEdge(nEdges, 0);
391     forAll(pointEdges, pointI)
392     {
393         const InList& pEdges = pointEdges[pointI];
395         forAll(pEdges, j)
396         {
397             nPointsPerEdge[pEdges[j]]++;
398         }
399     }
401     // Size edges
402     edges.setSize(nEdges);
404     forAll(nPointsPerEdge, edgeI)
405     {
406         edges[edgeI].setSize(nPointsPerEdge[edgeI]);
407     }
408     nPointsPerEdge = 0;
410     // Fill edges
411     forAll(pointEdges, pointI)
412     {
413         const InList& pEdges = pointEdges[pointI];
415         forAll(pEdges, j)
416         {
417             label edgeI = pEdges[j];
419             edges[edgeI][nPointsPerEdge[edgeI]++] = pointI;
420         }
421     }
425 template<class ListType>
426 Foam::label Foam::findIndex
428     const ListType& l,
429     typename ListType::const_reference t,
430     const label start
433     label index = -1;
435     for (label i = start; i < l.size(); i++)
436     {
437         if (l[i] == t)
438         {
439             index = i;
440             break;
441         }
442     }
444     return index;
448 template<class ListType>
449 Foam::labelList Foam::findIndices
451     const ListType& l,
452     typename ListType::const_reference t,
453     const label start
456     // Count occurrences
457     label n = 0;
459     for (label i = start; i < l.size(); i++)
460     {
461         if (l[i] == t)
462         {
463             n++;
464         }
465     }
467     // Create and fill
468     labelList indices(n);
469     n = 0;
471     for (label i = start; i < l.size(); i++)
472     {
473         if (l[i] == t)
474         {
475             indices[n++] = i;
476         }
477     }
479     return indices;
483 template<class ListType>
484 void Foam::setValues
486     ListType& l,
487     const labelUList& indices,
488     typename ListType::const_reference t
491     forAll(indices, i)
492     {
493         l[indices[i]] = t;
494     }
498 template<class ListType>
499 ListType Foam::createWithValues
501     const label sz,
502     const typename ListType::const_reference initValue,
503     const labelUList& indices,
504     typename ListType::const_reference setValue
507     ListType l(sz, initValue);
508     setValues(l, indices, setValue);
509     return l;
513 template<class ListType>
514 Foam::label Foam::findMax(const ListType& l, const label start)
516     if (start >= l.size())
517     {
518         return -1;
519     }
521     label index = start;
523     for (label i = start+1; i < l.size(); i++)
524     {
525         if (l[i] > l[index])
526         {
527             index = i;
528         }
529     }
531     return index;
535 template<class ListType>
536 Foam::label Foam::findMin(const ListType& l, const label start)
538     if (start >= l.size())
539     {
540         return -1;
541     }
543     label index = start;
545     for (label i = start+1; i < l.size(); i++)
546     {
547         if (l[i] < l[index])
548         {
549             index = i;
550         }
551     }
553     return index;
557 template<class ListType>
558 Foam::label Foam::findSortedIndex
560     const ListType& l,
561     typename ListType::const_reference t,
562     const label start
565     if (start >= l.size())
566     {
567         return -1;
568     }
570     label low = start;
571     label high = l.size() - 1;
573     while (low <= high)
574     {
575         label mid = (low + high)/2;
577         if (t < l[mid])
578         {
579             high = mid - 1;
580         }
581         else if (t > l[mid])
582         {
583             low = mid + 1;
584         }
585         else
586         {
587             return mid;
588         }
589     }
591     return -1;
595 template<class ListType>
596 Foam::label Foam::findLower
598     const ListType& l,
599     typename ListType::const_reference t,
600     const label start
603     if (start >= l.size())
604     {
605         return -1;
606     }
608     label low = start;
609     label high = l.size() - 1;
611     while ((high - low) > 1)
612     {
613         label mid = (low + high)/2;
615         if (l[mid] < t)
616         {
617             low = mid;
618         }
619         else
620         {
621             high = mid;
622         }
623     }
625     if (l[high] < t)
626     {
627         return high;
628     }
629     else
630     {
631         if (l[low] < t)
632         {
633             return low;
634         }
635         else
636         {
637             return -1;
638         }
639     }
643 template<class Container, class T, int nRows>
644 Foam::List<Container> Foam::initList(const T elems[nRows])
646     List<Container> lst(nRows);
648     forAll(lst, rowI)
649     {
650         lst[rowI] = Container(elems[rowI]);
651     }
652     return lst;
656 template<class Container, class T, int nRows, int nColumns>
657 Foam::List<Container> Foam::initListList(const T elems[nRows][nColumns])
659     List<Container> lst(nRows);
661     Container cols(nColumns);
662     forAll(lst, rowI)
663     {
664         forAll(cols, colI)
665         {
666             cols[colI] = elems[rowI][colI];
667         }
668         lst[rowI] = cols;
669     }
670     return lst;
674 // ************************************************************************* //