mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: support UList[labelRange] and SubList construction with labelRange
This uses a concept similar to what std::valarray and std::slice do.
A labelRange provides a convenient container for holding start/size
and lends itself to addressing 'sliced' views of lists.
For safety, the operations and constructors restricts the given input range
to a valid addressible region of the underlying list, while the labelRange
itself precludes negative sizes.
The SubList version is useful for patches or other things that have a
SubList as its parameter. Otherwise the UList [] operator will be the
more natural solution. The slices can be done with a labelRange, or
a {start,size} pair.
Examples,
labelList list1 = identity(20);
list1[labelRange(18,10)] = -1;
list1[{-20,25}] = -2;
list1[{1000,5}] = -3;
const labelList list2 = identity(20);
list2[{5,10}] = -3; // ERROR: cannot assign to const!
This commit is contained in:
@ -76,7 +76,6 @@ int main(int argc, char *argv[])
|
|||||||
Info<<"is >>: " << intlist << endl;
|
Info<<"is >>: " << intlist << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List<vector> list1(IStringStream("1 ((0 1 2))")());
|
List<vector> list1(IStringStream("1 ((0 1 2))")());
|
||||||
Info<< "list1: " << list1 << endl;
|
Info<< "list1: " << list1 << endl;
|
||||||
|
|
||||||
@ -150,7 +149,6 @@ int main(int argc, char *argv[])
|
|||||||
Info<< "normal: " << longLabelList << nl;
|
Info<< "normal: " << longLabelList << nl;
|
||||||
Info<< "flatOutput: " << flatOutput(longLabelList) << nl;
|
Info<< "flatOutput: " << flatOutput(longLabelList) << nl;
|
||||||
// Info<< "flatOutput(14): " << flatOutput(longLabelList, 14) << nl;
|
// Info<< "flatOutput(14): " << flatOutput(longLabelList, 14) << nl;
|
||||||
// Info<< "flatOutput(15): " << flatOutput(longLabelList, 15) << nl;
|
|
||||||
|
|
||||||
stringList longStringList(12);
|
stringList longStringList(12);
|
||||||
forAll(longStringList, i)
|
forAll(longStringList, i)
|
||||||
@ -165,6 +163,66 @@ int main(int argc, char *argv[])
|
|||||||
// contiguous longStringList[i].resize(3, 'a' + i);
|
// contiguous longStringList[i].resize(3, 'a' + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test SubList and labelRange
|
||||||
|
{
|
||||||
|
Info<< nl;
|
||||||
|
labelList longLabelList = identity(25);
|
||||||
|
reverse(longLabelList);
|
||||||
|
|
||||||
|
FixedList<label, 6> fixedLabelList{0,1,2,3,4,5};
|
||||||
|
const labelList constLabelList = identity(25);
|
||||||
|
|
||||||
|
Info<< "full-list: " << flatOutput(longLabelList) << nl;
|
||||||
|
|
||||||
|
labelRange range1(-15, 25);
|
||||||
|
Info<<"sub range:" << range1 << "=";
|
||||||
|
Info<< SubList<label>(longLabelList, range1) << nl;
|
||||||
|
|
||||||
|
labelRange range2(7, 8);
|
||||||
|
Info<<"sub range:" << range2 << "=";
|
||||||
|
Info<< SubList<label>(longLabelList, range2) << nl;
|
||||||
|
|
||||||
|
// labelRange range2(7, 8);
|
||||||
|
Info<<"use range " << range2 << " to set value";
|
||||||
|
SubList<label>(longLabelList, range2) = -15;
|
||||||
|
Info<< "=> " << flatOutput(longLabelList) << nl;
|
||||||
|
|
||||||
|
// This syntax looks even nicer:
|
||||||
|
|
||||||
|
// GOOD: does not compile
|
||||||
|
// > constLabelList[labelRange(23,5)] = 5;
|
||||||
|
|
||||||
|
// Check correct overlaps
|
||||||
|
longLabelList[labelRange(-10, 12)] = 200;
|
||||||
|
longLabelList[{18,3}] = 100;
|
||||||
|
longLabelList[{23,3}] = 400;
|
||||||
|
// and complete misses
|
||||||
|
longLabelList[{500,50}] = 100;
|
||||||
|
|
||||||
|
// labelRange automatically suppresses -ve size -> nop
|
||||||
|
longLabelList[{5,-5}] = 42;
|
||||||
|
longLabelList[{21,100}] = 42;
|
||||||
|
|
||||||
|
//Good: does not compile
|
||||||
|
//> longLabelList[labelRange(20,50)] = constLabelList;
|
||||||
|
|
||||||
|
//Good: does not compile
|
||||||
|
// longLabelList[labelRange(20,50)] = fixedLabelList;
|
||||||
|
|
||||||
|
Info<< "updated: " << constLabelList[labelRange(23,5)] << nl;
|
||||||
|
Info<< "updated: " << flatOutput(longLabelList) << nl;
|
||||||
|
|
||||||
|
//Nope: sort(longLabelList[labelRange(18,5)]);
|
||||||
|
{
|
||||||
|
// Instead
|
||||||
|
UList<label> sub = longLabelList[labelRange(0, 8)];
|
||||||
|
sort(sub);
|
||||||
|
}
|
||||||
|
Info<< "sub-sorted: " << flatOutput(longLabelList) << nl;
|
||||||
|
|
||||||
|
// Info<<"Slice=" << longLabelList[labelRange(23,5)] << nl;
|
||||||
|
}
|
||||||
|
|
||||||
wordReList reLst;
|
wordReList reLst;
|
||||||
wordList wLst;
|
wordList wLst;
|
||||||
stringList sLst;
|
stringList sLst;
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -40,6 +40,7 @@ SourceFiles
|
|||||||
#define SubList_H
|
#define SubList_H
|
||||||
|
|
||||||
#include "List.H"
|
#include "List.H"
|
||||||
|
#include "labelRange.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -55,7 +56,6 @@ class SubList
|
|||||||
:
|
:
|
||||||
public UList<T>
|
public UList<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Static Member Functions
|
// Static Member Functions
|
||||||
@ -81,6 +81,23 @@ public:
|
|||||||
const label startIndex
|
const label startIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Construct from UList and a (start,size) range.
|
||||||
|
// The range is subsetted with the list size itself to ensure that the
|
||||||
|
// result always addresses a valid section of the list.
|
||||||
|
inline SubList
|
||||||
|
(
|
||||||
|
const UList<T>& list,
|
||||||
|
const labelRange& range
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from UList and a (start,size) range, but bypassing
|
||||||
|
// run-time range checking.
|
||||||
|
inline SubList
|
||||||
|
(
|
||||||
|
const labelRange& range,
|
||||||
|
const UList<T>& list
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Member operators
|
// Member operators
|
||||||
|
|
||||||
@ -88,13 +105,13 @@ public:
|
|||||||
inline operator const Foam::List<T>&() const;
|
inline operator const Foam::List<T>&() const;
|
||||||
|
|
||||||
//- Assignment of all entries to the given sub-list
|
//- Assignment of all entries to the given sub-list
|
||||||
inline void operator=(const SubList<T>&);
|
inline void operator=(const SubList<T>& list);
|
||||||
|
|
||||||
//- Assignment of all entries to the given list
|
//- Assignment of all entries to the given list
|
||||||
inline void operator=(const UList<T>&);
|
inline void operator=(const UList<T>& list);
|
||||||
|
|
||||||
//- Assignment of all entries to the given value
|
//- Assignment of all entries to the given value
|
||||||
inline void operator=(const T&);
|
inline void operator=(const T& t);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -51,7 +51,6 @@ inline Foam::SubList<T>::SubList
|
|||||||
UList<T>(&(list.v_[startIndex]), subSize)
|
UList<T>(&(list.v_[startIndex]), subSize)
|
||||||
{
|
{
|
||||||
#ifdef FULLDEBUG
|
#ifdef FULLDEBUG
|
||||||
|
|
||||||
// Artificially allow the start of a zero-sized subList to be
|
// Artificially allow the start of a zero-sized subList to be
|
||||||
// one past the end of the original list.
|
// one past the end of the original list.
|
||||||
if (subSize)
|
if (subSize)
|
||||||
@ -69,6 +68,28 @@ inline Foam::SubList<T>::SubList
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline Foam::SubList<T>::SubList
|
||||||
|
(
|
||||||
|
const UList<T>& list,
|
||||||
|
const labelRange& range
|
||||||
|
)
|
||||||
|
:
|
||||||
|
SubList<T>(list.validateRange(range), list)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline Foam::SubList<T>::SubList
|
||||||
|
(
|
||||||
|
const labelRange& range,
|
||||||
|
const UList<T>& list
|
||||||
|
)
|
||||||
|
:
|
||||||
|
SubList<T>(list, range.size(), range.start())
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@ -88,16 +109,16 @@ inline Foam::SubList<T>::operator const Foam::List<T>&() const
|
|||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void Foam::SubList<T>::operator=(const SubList<T>& sl)
|
inline void Foam::SubList<T>::operator=(const SubList<T>& list)
|
||||||
{
|
{
|
||||||
UList<T>::deepCopy(sl);
|
UList<T>::deepCopy(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void Foam::SubList<T>::operator=(const UList<T>& l)
|
inline void Foam::SubList<T>::operator=(const UList<T>& list)
|
||||||
{
|
{
|
||||||
UList<T>::deepCopy(l);
|
UList<T>::deepCopy(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,9 +26,49 @@ License
|
|||||||
#include "UList.H"
|
#include "UList.H"
|
||||||
#include "ListLoopM.H"
|
#include "ListLoopM.H"
|
||||||
#include "contiguous.H"
|
#include "contiguous.H"
|
||||||
|
#include "labelRange.H"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Foam::labelRange Foam::UList<T>::validateRange(const labelRange& range) const
|
||||||
|
{
|
||||||
|
const labelRange slice = range.subset(0, this->size());
|
||||||
|
|
||||||
|
#ifdef FULLDEBUG
|
||||||
|
this->checkStart(slice.start());
|
||||||
|
this->checkSize(slice.start() + slice.size());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return slice;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Foam::labelRange Foam::UList<T>::validateRange
|
||||||
|
(
|
||||||
|
std::initializer_list<label> start_size_pair
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (start_size_pair.size() != 2)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "range specified with " << start_size_pair.size()
|
||||||
|
<< " elements instead of 2"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto iter = start_size_pair.begin();
|
||||||
|
|
||||||
|
const label beg = *(iter++);
|
||||||
|
const label sz = *iter;
|
||||||
|
|
||||||
|
return this->validateRange(labelRange(beg, sz));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@ -64,6 +104,47 @@ void Foam::UList<T>::deepCopy(const UList<T>& a)
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Foam::UList<T> Foam::UList<T>::operator[](const labelRange& range)
|
||||||
|
{
|
||||||
|
const labelRange slice = validateRange(range);
|
||||||
|
|
||||||
|
return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
const Foam::UList<T> Foam::UList<T>::operator[](const labelRange& range) const
|
||||||
|
{
|
||||||
|
const labelRange slice = validateRange(range);
|
||||||
|
|
||||||
|
return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Foam::UList<T> Foam::UList<T>::operator[]
|
||||||
|
(
|
||||||
|
std::initializer_list<label> start_size_pair
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const labelRange slice = validateRange(start_size_pair);
|
||||||
|
|
||||||
|
return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
const Foam::UList<T> Foam::UList<T>::operator[]
|
||||||
|
(
|
||||||
|
std::initializer_list<label> start_size_range
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Restricted range
|
||||||
|
const labelRange slice = validateRange(start_size_range);
|
||||||
|
|
||||||
|
return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Foam::UList<T>::operator=(const T& t)
|
void Foam::UList<T>::operator=(const T& t)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -48,13 +48,15 @@ SourceFiles
|
|||||||
#include "nullObject.H"
|
#include "nullObject.H"
|
||||||
#include "zero.H"
|
#include "zero.H"
|
||||||
#include "stdFoam.H"
|
#include "stdFoam.H"
|
||||||
|
#include <initializer_list>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// Forward declaration of friend classes
|
// Forward declarations
|
||||||
|
class labelRange;
|
||||||
template<class T> class List;
|
template<class T> class List;
|
||||||
template<class T> class SubList;
|
template<class T> class SubList;
|
||||||
|
|
||||||
@ -101,6 +103,16 @@ protected:
|
|||||||
//- Write the UList with its compound type
|
//- Write the UList with its compound type
|
||||||
void writeEntry(Ostream& os) const;
|
void writeEntry(Ostream& os) const;
|
||||||
|
|
||||||
|
//- Return a validated (start,size) subset range, which means that it
|
||||||
|
// always addresses a valid section of the list.
|
||||||
|
labelRange validateRange(const labelRange& range) const;
|
||||||
|
|
||||||
|
//- Return a validated (start,size) subset range, which means that it
|
||||||
|
// always addresses a valid section of the list.
|
||||||
|
labelRange validateRange
|
||||||
|
(
|
||||||
|
std::initializer_list<label> start_size_pair
|
||||||
|
) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -239,6 +251,29 @@ public:
|
|||||||
// an out-of-range element returns false without any ill-effects
|
// an out-of-range element returns false without any ill-effects
|
||||||
inline const T& operator[](const label i) const;
|
inline const T& operator[](const label i) const;
|
||||||
|
|
||||||
|
//- Return (start,size) subset from UList with non-const access.
|
||||||
|
// The range is subsetted with the list size itself to ensure that the
|
||||||
|
// result always addresses a valid section of the list.
|
||||||
|
UList<T> operator[](const labelRange& range);
|
||||||
|
|
||||||
|
//- Return (start,size) subset from UList with const access.
|
||||||
|
// The range is subsetted with the list size itself to ensure that the
|
||||||
|
// result always addresses a valid section of the list.
|
||||||
|
const UList<T> operator[](const labelRange& range) const;
|
||||||
|
|
||||||
|
//- Return (start,size) subset from UList with non-const access.
|
||||||
|
// The range is subsetted with the list size itself to ensure that the
|
||||||
|
// result always addresses a valid section of the list.
|
||||||
|
UList<T> operator[](std::initializer_list<label> start_size_range);
|
||||||
|
|
||||||
|
//- Return (start,size) subset from UList with const access.
|
||||||
|
// The range is subsetted with the list size itself to ensure that the
|
||||||
|
// result always addresses a valid section of the list.
|
||||||
|
const UList<T> operator[]
|
||||||
|
(
|
||||||
|
std::initializer_list<label> start_size_range
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Allow cast to a const List<T>&
|
//- Allow cast to a const List<T>&
|
||||||
inline operator const Foam::List<T>&() const;
|
inline operator const Foam::List<T>&() const;
|
||||||
|
|
||||||
|
|||||||
@ -162,7 +162,6 @@ inline void Foam::UList<T>::shallowCopy(const UList<T>& a)
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline T& Foam::UList<T>::operator[](const label i)
|
inline T& Foam::UList<T>::operator[](const label i)
|
||||||
{
|
{
|
||||||
@ -172,7 +171,6 @@ inline T& Foam::UList<T>::operator[](const label i)
|
|||||||
return v_[i];
|
return v_[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
// Template specialization for bool
|
// Template specialization for bool
|
||||||
@ -191,7 +189,6 @@ namespace Foam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline const T& Foam::UList<T>::operator[](const label i) const
|
inline const T& Foam::UList<T>::operator[](const label i) const
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user