initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / containers / Lists / ListOps / ListOpsTemplates.C
blobdd8536eec9b9f1466c518e2069c4a96b489cdc80
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     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, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "ListOps.H"
29 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
31 template<class ListType>
32 ListType Foam::renumber
34     const UList<label>& oldToNew,
35     const ListType& lst
38     // Create copy
39     ListType newLst(lst.size());
41     forAll(lst, elemI)
42     {
43         if (lst[elemI] >= 0)
44         {
45             newLst[elemI] = oldToNew[lst[elemI]];
46         }
47     }
49     return newLst;
53 template<class ListType>
54 void Foam::inplaceRenumber
56     const UList<label>& oldToNew,
57     ListType& lst
60     forAll(lst, elemI)
61     {
62         if (lst[elemI] >= 0)
63         {
64             lst[elemI] = oldToNew[lst[elemI]];
65         }
66     }
70 template<class ListType>
71 ListType Foam::reorder
73     const UList<label>& oldToNew,
74     const ListType& lst
77     // Create copy
78     ListType newLst(lst.size());
80     forAll(lst, elemI)
81     {
82         if (oldToNew[elemI] >= 0)
83         {
84             newLst[oldToNew[elemI]] = lst[elemI];
85         }
86         else
87         {
88             newLst[elemI] = lst[elemI];
89         }
90     }
91     return newLst;
95 template<class ListType>
96 void Foam::inplaceReorder
98     const UList<label>& oldToNew,
99     ListType& lst
102     // Create copy
103     ListType newLst(lst.size());
105     forAll(lst, elemI)
106     {
107         if (oldToNew[elemI] >= 0)
108         {
109             newLst[oldToNew[elemI]] = lst[elemI];
110         }
111         else
112         {
113             newLst[elemI] = lst[elemI];
114         }
115     }
117     lst.transfer(newLst);
121 template<class Container>
122 void Foam::inplaceMapValue
124     const UList<label>& oldToNew,
125     Container& lst
128     for
129     (
130         typename Container::iterator iter = lst.begin();
131         iter != lst.end();
132         ++iter
133     )
134     {
135         if (iter() >= 0)
136         {
137             iter() = oldToNew[iter()];
138         }
139     }
143 template<class Container>
144 void Foam::inplaceMapKey
146     const UList<label>& oldToNew,
147     Container& lst
150     Container newLst(lst.size());
152     for
153     (
154         typename Container::iterator iter = lst.begin();
155         iter != lst.end();
156         ++iter
157     )
158     {
159         if (iter.key() >= 0)
160         {
161             newLst.insert(oldToNew[iter.key()], iter());
162         }
163     }
165     lst.transfer(newLst);
169 template<class T>
170 void Foam::sortedOrder
172     const UList<T>& lst,
173     labelList& order
176     // list lengths must be identical
177     if (order.size() != lst.size())
178     {
179         // avoid copying any elements, they are overwritten anyhow
180         order.clear();
181         order.setSize(lst.size());
182     }
184     forAll(order, elemI)
185     {
186         order[elemI] = elemI;
187     }
188     Foam::stableSort(order, typename UList<T>::less(lst));
192 template<class T>
193 void Foam::duplicateOrder
195     const UList<T>& lst,
196     labelList& order
199     if (lst.size() < 2)
200     {
201         order.clear();
202         return;
203     }
205     sortedOrder(lst, order);
207     label n = 0;
208     for (label i = 0; i < order.size() - 1; ++i)
209     {
210         if (lst[order[i]] == lst[order[i+1]])
211         {
212             order[n++] = order[i];
213         }
214     }
215     order.setSize(n);
219 template<class T>
220 void Foam::uniqueOrder
222     const UList<T>& lst,
223     labelList& order
226     sortedOrder(lst, order);
228     if (order.size() > 1)
229     {
230         label n = 0;
231         for (label i = 0; i < order.size() - 1; ++i)
232         {
233             if (lst[order[i]] != lst[order[i+1]])
234             {
235                 order[n++] = order[i];
236             }
237         }
238         order.setSize(n);
239     }
243 template<class T, class ListType>
244 ListType Foam::subset
246     const UList<T>& select,
247     const T& value,
248     const ListType& lst
251     // select must at least cover the list range
252     if (select.size() < lst.size())
253     {
254         FatalErrorIn("subset(const UList<T>&, const T&, const ListType&)")
255             << "select is of size " << select.size()
256             << "; but it must index a list of size " << lst.size()
257             << abort(FatalError);
258     }
260     ListType newLst(lst.size());
262     label nElem = 0;
263     forAll(lst, elemI)
264     {
265         if (select[elemI] == value)
266         {
267             newLst[nElem++] = lst[elemI];
268         }
269     }
270     newLst.setSize(nElem);
272     return newLst;
276 template<class T, class ListType>
277 void Foam::inplaceSubset
279     const UList<T>& select,
280     const T& value,
281     ListType& lst
284     // select must at least cover the list range
285     if (select.size() < lst.size())
286     {
287         FatalErrorIn("inplaceSubset(const UList<T>&, const T&, ListType&)")
288             << "select is of size " << select.size()
289             << "; but it must index a list of size " << lst.size()
290             << abort(FatalError);
291     }
293     label nElem = 0;
294     forAll(lst, elemI)
295     {
296         if (select[elemI] == value)
297         {
298             if (nElem != elemI)
299             {
300                 lst[nElem] = lst[elemI];
301             }
302             ++nElem;
303         }
304     }
306     lst.setSize(nElem);
310 template<class BoolListType, class ListType>
311 ListType Foam::subset
313     const BoolListType& select,
314     const ListType& lst
317     // select can have a different size
318     // eg, when it is a PackedBoolList or a labelHashSet
320     ListType newLst(lst.size());
322     label nElem = 0;
323     forAll(lst, elemI)
324     {
325         if (select[elemI])
326         {
327             newLst[nElem++] = lst[elemI];
328         }
329     }
330     newLst.setSize(nElem);
332     return newLst;
336 template<class BoolListType, class ListType>
337 void Foam::inplaceSubset
339     const BoolListType& select,
340     ListType& lst
343     // select can have a different size
344     // eg, when it is a PackedBoolList or a labelHashSet
346     label nElem = 0;
347     forAll(lst, elemI)
348     {
349         if (select[elemI])
350         {
351             if (nElem != elemI)
352             {
353                 lst[nElem] = lst[elemI];
354             }
355             ++nElem;
356         }
357     }
359     lst.setSize(nElem);
363 // As clarification:
364 // coded as inversion from pointEdges to edges but completely general.
365 template<class InList, class OutList>
366 void Foam::invertManyToMany
368     const label nEdges,
369     const UList<InList>& pointEdges,
370     List<OutList>& edges
373     // Number of points per edge
374     labelList nPointsPerEdge(nEdges, 0);
376     forAll(pointEdges, pointI)
377     {
378         const InList& pEdges = pointEdges[pointI];
380         forAll(pEdges, j)
381         {
382             nPointsPerEdge[pEdges[j]]++;
383         }
384     }
386     // Size edges
387     edges.setSize(nEdges);
389     forAll(nPointsPerEdge, edgeI)
390     {
391         edges[edgeI].setSize(nPointsPerEdge[edgeI]);
392     }
393     nPointsPerEdge = 0;
395     // Fill edges
396     forAll(pointEdges, pointI)
397     {
398         const InList& pEdges = pointEdges[pointI];
400         forAll(pEdges, j)
401         {
402             label edgeI = pEdges[j];
404             edges[edgeI][nPointsPerEdge[edgeI]++] = pointI;
405         }
406     }
410 template<class ListType>
411 Foam::label Foam::findIndex
413     const ListType& l,
414     typename ListType::const_reference t,
415     const label start
418     label index = -1;
420     for (label i = start; i < l.size(); i++)
421     {
422         if (l[i] == t)
423         {
424             index = i;
425             break;
426         }
427     }
429     return index;
433 template<class ListType>
434 Foam::labelList Foam::findIndices
436     const ListType& l,
437     typename ListType::const_reference t,
438     const label start
441     // Count occurrences
442     label n = 0;
444     for (label i = start; i < l.size(); i++)
445     {
446         if (l[i] == t)
447         {
448             n++;
449         }
450     }
452     // Create and fill
453     labelList indices(n);
454     n = 0;
456     for (label i = start; i < l.size(); i++)
457     {
458         if (l[i] == t)
459         {
460             indices[n++] = i;
461         }
462     }
464     return indices;
468 template<class ListType>
469 void Foam::setValues
471     ListType& l,
472     const UList<label>& indices,
473     typename ListType::const_reference t
476     forAll(indices, i)
477     {
478         l[indices[i]] = t;
479     }
483 template<class ListType>
484 ListType Foam::createWithValues
486     const label sz,
487     const typename ListType::const_reference initValue,
488     const UList<label>& indices,
489     typename ListType::const_reference setValue
492     ListType l(sz, initValue);
493     setValues(l, indices, setValue);
494     return l;
498 template<class ListType>
499 Foam::label Foam::findMax(const ListType& l, const label start)
501     if (start >= l.size())
502     {
503         return -1;
504     }
506     label index = start;
508     for (label i = start+1; i < l.size(); i++)
509     {
510         if (l[i] > l[index])
511         {
512             index = i;
513         }
514     }
516     return index;
520 template<class ListType>
521 Foam::label Foam::findMin(const ListType& l, const label start)
523     if (start >= l.size())
524     {
525         return -1;
526     }
528     label index = start;
530     for (label i = start+1; i < l.size(); i++)
531     {
532         if (l[i] < l[index])
533         {
534             index = i;
535         }
536     }
538     return index;
542 template<class ListType>
543 Foam::label Foam::findSortedIndex
545     const ListType& l,
546     typename ListType::const_reference t,
547     const label start
550     if (start >= l.size())
551     {
552         return -1;
553     }
555     label low = start;
556     label high = l.size() - 1;
558     while (low <= high)
559     {
560         label mid = (low + high)/2;
562         if (t < l[mid])
563         {
564             high = mid - 1;
565         }
566         else if (t > l[mid])
567         {
568             low = mid + 1;
569         }
570         else
571         {
572             return mid;
573         }
574     }
576     return -1;
580 template<class ListType>
581 Foam::label Foam::findLower
583     const ListType& l,
584     typename ListType::const_reference t,
585     const label start
588     if (start >= l.size())
589     {
590         return -1;
591     }
593     label low = start;
594     label high = l.size() - 1;
596     while ((high - low) > 1)
597     {
598         label mid = (low + high)/2;
600         if (l[mid] < t)
601         {
602             low = mid;
603         }
604         else
605         {
606             high = mid;
607         }
608     }
610     if (l[high] < t)
611     {
612         return high;
613     }
614     else
615     {
616         if (l[low] < t)
617         {
618             return low;
619         }
620         else
621         {
622             return -1;
623         }
624     }
628 template<class Container, class T, int nRows>
629 Foam::List<Container> Foam::initList(const T elems[nRows])
631     List<Container> lst(nRows);
633     forAll(lst, rowI)
634     {
635         lst[rowI] = Container(elems[rowI]);
636     }
637     return lst;
641 template<class Container, class T, int nRows, int nColumns>
642 Foam::List<Container> Foam::initListList(const T elems[nRows][nColumns])
644     List<Container> lst(nRows);
646     Container cols(nColumns);
647     forAll(lst, rowI)
648     {
649         forAll(cols, colI)
650         {
651             cols[colI] = elems[rowI][colI];
652         }
653         lst[rowI] = cols;
654     }
655     return lst;
659 // ************************************************************************* //