mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: simplify and extend labelRange
- add increment/decrement, repositioning. Simplify const_iterator.
- this makes is much easier to use labelRange for constructing ranges of
sub-lists. For symmetry with setSize() it has a setStart() instead of
simply assigning to start() directly. This would also provide the
future possibility to imbue the labelRange with a particular policy
(eg, no negative starts, max size etc) and ensure that they are
enforced.
A simple use case:
// initialize each to zero...
List<labelRange> subListRanges = ...;
// scan and categorize
if (condition)
subListRanges[categoryI]++; // increment size for that category
// finally, set the starting points
start = 0;
for (labelRange& range : subListRanges)
{
range.setStart(start);
start += range.size();
}
This commit is contained in:
@ -35,7 +35,7 @@ License
|
||||
template<class T>
|
||||
Foam::labelRange Foam::UList<T>::validateRange(const labelRange& range) const
|
||||
{
|
||||
const labelRange slice = range.subset(0, this->size());
|
||||
const labelRange slice = range.subset0(this->size());
|
||||
|
||||
#ifdef FULLDEBUG
|
||||
this->checkStart(slice.start());
|
||||
|
||||
@ -289,12 +289,10 @@ public:
|
||||
//- Type of values the UList contains
|
||||
typedef T value_type;
|
||||
|
||||
//- Type that can be used for storing into
|
||||
// UList::value_type objects
|
||||
//- The type used for storing into value_type objects
|
||||
typedef T& reference;
|
||||
|
||||
//- Type that can be used for storing into
|
||||
// constant UList::value_type objects
|
||||
//- The type used for reading from constant value_type objects.
|
||||
typedef const T& const_reference;
|
||||
|
||||
//- The type that can represent the difference between any two
|
||||
|
||||
@ -52,11 +52,17 @@ void Foam::labelRange::adjust()
|
||||
{
|
||||
if (start_ < 0)
|
||||
{
|
||||
size_ += start_;
|
||||
if (size_ <= 0)
|
||||
{
|
||||
size_ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_ += start_;
|
||||
}
|
||||
start_ = 0;
|
||||
}
|
||||
|
||||
if (size_ < 0)
|
||||
else if (size_ < 0)
|
||||
{
|
||||
size_ = 0;
|
||||
}
|
||||
@ -65,7 +71,7 @@ void Foam::labelRange::adjust()
|
||||
|
||||
bool Foam::labelRange::overlaps(const labelRange& range, bool touches) const
|
||||
{
|
||||
const label final = touches ? 1 : 0;
|
||||
const label extra = touches ? 1 : 0;
|
||||
|
||||
return
|
||||
(
|
||||
@ -74,12 +80,12 @@ bool Foam::labelRange::overlaps(const labelRange& range, bool touches) const
|
||||
(
|
||||
(
|
||||
range.first() >= this->first()
|
||||
&& range.first() <= this->last() + final
|
||||
&& range.first() <= this->last() + extra
|
||||
)
|
||||
||
|
||||
(
|
||||
this->first() >= range.first()
|
||||
&& this->first() <= range.last() + final
|
||||
&& this->first() <= range.last() + extra
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -134,7 +140,26 @@ Foam::labelRange Foam::labelRange::subset
|
||||
) const
|
||||
{
|
||||
const label lower = Foam::max(this->start(), start);
|
||||
const label upper = Foam::min(this->last(), start+Foam::max(0,size)-1);
|
||||
const label upper = Foam::min(this->last(), start+Foam::max(0,size-1));
|
||||
const label total = upper+1 - lower;
|
||||
// last = start+size-1
|
||||
// size = last+1-start
|
||||
|
||||
if (total > 0)
|
||||
{
|
||||
return labelRange(lower, total);
|
||||
}
|
||||
else
|
||||
{
|
||||
return labelRange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::labelRange Foam::labelRange::subset0(const label size) const
|
||||
{
|
||||
const label lower = Foam::max(this->start(), 0);
|
||||
const label upper = Foam::min(this->last(), Foam::max(0,size-1));
|
||||
const label total = upper+1 - lower;
|
||||
// last = start+size-1
|
||||
// size = last+1-start
|
||||
|
||||
@ -65,6 +65,17 @@ public:
|
||||
|
||||
static int debug;
|
||||
|
||||
// STL type definitions similar to what UList has
|
||||
|
||||
//- Type of values the range contains
|
||||
typedef label value_type;
|
||||
|
||||
//- The type that can represent the difference between two iterators
|
||||
typedef label difference_type;
|
||||
|
||||
//- The type that can represent the size of the range
|
||||
typedef label size_type;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
@ -86,12 +97,21 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Alias for setSize(const label)
|
||||
inline void resize(const label n);
|
||||
//- Adjust start position
|
||||
inline void setStart(const label i);
|
||||
|
||||
//- Adjust size
|
||||
inline void setSize(const label n);
|
||||
|
||||
//- Alias for setSize()
|
||||
inline void resize(const label n);
|
||||
|
||||
//- Decrease the size by 1, but never below 0.
|
||||
inline void decrement();
|
||||
|
||||
//- Increase the size by 1.
|
||||
inline void increment();
|
||||
|
||||
//- Reset to zero start and zero size
|
||||
inline void clear();
|
||||
|
||||
@ -116,6 +136,12 @@ public:
|
||||
//- The (inclusive) upper value of the range
|
||||
inline label last() const;
|
||||
|
||||
//- The value before the start of the range
|
||||
inline label before() const;
|
||||
|
||||
//- The value after the last element in the range
|
||||
inline label after() const;
|
||||
|
||||
//- Reset start and size, enforcing non-negative size.
|
||||
// Optionally adjust the start to avoid any negative indices.
|
||||
// Return true if the updated range valid (non-empty).
|
||||
@ -142,63 +168,71 @@ public:
|
||||
// for start/size.
|
||||
labelRange subset(const labelRange& range) const;
|
||||
|
||||
//- Calculate the intersection of the range with another.
|
||||
//- Calculate the intersection with the given start/size range.
|
||||
// If there is no intersection, it returns an empty range with zero
|
||||
// for start/size.
|
||||
labelRange subset(const label start, const label size) const;
|
||||
|
||||
//- Calculate the intersection with the given 0/size range.
|
||||
// If there is no intersection, it returns an empty range with zero
|
||||
// for start/size.
|
||||
labelRange subset0(const label size) const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- Return element in the range, no bounds checking
|
||||
inline label operator[](const label localIndex) const;
|
||||
|
||||
//- Increase the size by 1.
|
||||
inline label operator++();
|
||||
inline label operator++(int);
|
||||
|
||||
//- Decrease the size by 1, but never below 0.
|
||||
inline label operator--();
|
||||
inline label operator--(int);
|
||||
|
||||
|
||||
// STL iterator
|
||||
|
||||
//- An STL const_iterator
|
||||
//- Forward iterator with const access
|
||||
class const_iterator
|
||||
{
|
||||
friend class labelRange;
|
||||
|
||||
// Private data
|
||||
|
||||
//- Reference to the range for which this is an iterator
|
||||
const labelRange* range_;
|
||||
|
||||
//- Current index, relative to the start
|
||||
//- The current label (not the local index)
|
||||
label index_;
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from range at given index.
|
||||
// A negative index signals the 'end' position
|
||||
inline const_iterator(const labelRange* range, const label i);
|
||||
|
||||
public:
|
||||
|
||||
// Member operators
|
||||
// Constructors
|
||||
|
||||
inline bool operator==(const const_iterator& iter) const;
|
||||
inline bool operator!=(const const_iterator& iter) const;
|
||||
//- Construct from range at given local index.
|
||||
// A negative index signals the 'end' position
|
||||
inline const_iterator(const labelRange* range, const label i = 0);
|
||||
|
||||
// Member operators
|
||||
|
||||
//- Return the current label
|
||||
inline label operator*() const;
|
||||
|
||||
inline const_iterator& operator++();
|
||||
inline const_iterator operator++(int);
|
||||
|
||||
inline bool operator==(const const_iterator& iter) const;
|
||||
inline bool operator!=(const const_iterator& iter) const;
|
||||
};
|
||||
|
||||
|
||||
//- A const_iterator set to the beginning of the range
|
||||
// The value returned is guaranteed to be the same as start()
|
||||
inline const_iterator begin() const;
|
||||
|
||||
//- A const_iterator set to the beginning of the range
|
||||
// The value returned is guaranteed to be the same as start()
|
||||
inline const_iterator cbegin() const;
|
||||
|
||||
//- A const_iterator set to beyond the end of the range
|
||||
inline const const_iterator cend() const;
|
||||
|
||||
//- A const_iterator set to the beginning of the range
|
||||
inline const_iterator begin() const;
|
||||
|
||||
//- A const_iterator set to beyond the end of the range
|
||||
inline const const_iterator end() const;
|
||||
|
||||
|
||||
@ -64,32 +64,17 @@ inline Foam::labelRange::const_iterator::const_iterator
|
||||
const label i
|
||||
)
|
||||
:
|
||||
range_(range),
|
||||
index_(i < 0 ? range->size() : i)
|
||||
index_
|
||||
(
|
||||
range->start()
|
||||
+ ((i < 0 || i > range->size()) ? range->size() : i)
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
inline bool Foam::labelRange::const_iterator::operator==
|
||||
(
|
||||
const const_iterator& iter
|
||||
) const
|
||||
{
|
||||
return (this->index_ == iter.index_);
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::labelRange::const_iterator::operator!=
|
||||
(
|
||||
const const_iterator& iter
|
||||
) const
|
||||
{
|
||||
return (this->index_ != iter.index_);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::labelRange::const_iterator::operator*() const
|
||||
{
|
||||
return range_->start_ + index_;
|
||||
return index_;
|
||||
}
|
||||
|
||||
|
||||
@ -110,19 +95,31 @@ Foam::labelRange::const_iterator::operator++(int)
|
||||
}
|
||||
|
||||
|
||||
inline Foam::labelRange::const_iterator Foam::labelRange::cbegin() const
|
||||
inline bool Foam::labelRange::const_iterator::operator==
|
||||
(
|
||||
const const_iterator& iter
|
||||
) const
|
||||
{
|
||||
return (this->index_ == iter.index_);
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::labelRange::const_iterator::operator!=
|
||||
(
|
||||
const const_iterator& iter
|
||||
) const
|
||||
{
|
||||
return (this->index_ != iter.index_);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::labelRange::const_iterator Foam::labelRange::begin() const
|
||||
{
|
||||
return const_iterator(this, 0);
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::labelRange::const_iterator Foam::labelRange::cend() const
|
||||
{
|
||||
return const_iterator(this, -1);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::labelRange::const_iterator Foam::labelRange::begin() const
|
||||
inline Foam::labelRange::const_iterator Foam::labelRange::cbegin() const
|
||||
{
|
||||
return const_iterator(this, 0);
|
||||
}
|
||||
@ -134,22 +131,43 @@ inline const Foam::labelRange::const_iterator Foam::labelRange::end() const
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::labelRange::const_iterator Foam::labelRange::cend() const
|
||||
{
|
||||
return const_iterator(this, -1);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline void Foam::labelRange::setStart(const label i)
|
||||
{
|
||||
start_ = i;
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::labelRange::setSize(const label n)
|
||||
{
|
||||
size_ = n;
|
||||
if (size_ < 0) size_ = 0;
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::labelRange::resize(const label n)
|
||||
{
|
||||
setSize(n);
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::labelRange::setSize(const label n)
|
||||
inline void Foam::labelRange::decrement()
|
||||
{
|
||||
size_ = n;
|
||||
--size_;
|
||||
if (size_ < 0) size_ = 0;
|
||||
}
|
||||
|
||||
if (size_ < 0)
|
||||
{
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
inline void Foam::labelRange::increment()
|
||||
{
|
||||
++size_;
|
||||
}
|
||||
|
||||
|
||||
@ -195,6 +213,18 @@ inline Foam::label Foam::labelRange::last() const
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::labelRange::before() const
|
||||
{
|
||||
return start_ - 1;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::labelRange::after() const
|
||||
{
|
||||
return start_ + size_;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::labelRange::reset
|
||||
(
|
||||
const label start,
|
||||
@ -234,4 +264,31 @@ inline Foam::label Foam::labelRange::operator[](const label localIndex) const
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::labelRange::operator++()
|
||||
{
|
||||
return ++size_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::labelRange::operator++(int)
|
||||
{
|
||||
return size_++;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::labelRange::operator--()
|
||||
{
|
||||
decrement();
|
||||
return size_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::labelRange::operator--(int)
|
||||
{
|
||||
const label old = size_;
|
||||
decrement();
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -44,7 +44,7 @@ void Foam::labelRanges::insertBefore
|
||||
<< *this << endl;
|
||||
}
|
||||
|
||||
ParentType::setSize(nElem+1);
|
||||
StorageContainer::setSize(nElem+1);
|
||||
|
||||
if (labelRange::debug)
|
||||
{
|
||||
@ -58,7 +58,7 @@ void Foam::labelRanges::insertBefore
|
||||
Info<<"copy from " << (i) << " to " << (i+1) << nl;
|
||||
}
|
||||
|
||||
ParentType::operator[](i+1) = ParentType::operator[](i);
|
||||
StorageContainer::operator[](i+1) = StorageContainer::operator[](i);
|
||||
}
|
||||
|
||||
// finally insert the range
|
||||
@ -66,7 +66,7 @@ void Foam::labelRanges::insertBefore
|
||||
{
|
||||
Info<< "finally insert the range at " << insert << nl;
|
||||
}
|
||||
ParentType::operator[](insert) = range;
|
||||
StorageContainer::operator[](insert) = range;
|
||||
}
|
||||
|
||||
|
||||
@ -76,18 +76,19 @@ void Foam::labelRanges::purgeEmpty()
|
||||
label nElem = 0;
|
||||
forAll(*this, elemI)
|
||||
{
|
||||
if (!ParentType::operator[](elemI).empty())
|
||||
if (!StorageContainer::operator[](elemI).empty())
|
||||
{
|
||||
if (nElem != elemI)
|
||||
{
|
||||
ParentType::operator[](nElem) = ParentType::operator[](elemI);
|
||||
StorageContainer::operator[](nElem) =
|
||||
StorageContainer::operator[](elemI);
|
||||
}
|
||||
++nElem;
|
||||
}
|
||||
}
|
||||
|
||||
// truncate
|
||||
this->ParentType::setSize(nElem);
|
||||
this->StorageContainer::setSize(nElem);
|
||||
}
|
||||
|
||||
|
||||
@ -134,7 +135,7 @@ bool Foam::labelRanges::add(const labelRange& range)
|
||||
// find the correct place for insertion
|
||||
forAll(*this, elemI)
|
||||
{
|
||||
labelRange& currRange = ParentType::operator[](elemI);
|
||||
labelRange& currRange = StorageContainer::operator[](elemI);
|
||||
|
||||
if (currRange.overlaps(range, true))
|
||||
{
|
||||
@ -144,7 +145,7 @@ bool Foam::labelRanges::add(const labelRange& range)
|
||||
// might connect with the next following range(s)
|
||||
for (; elemI < this->size()-1; ++elemI)
|
||||
{
|
||||
labelRange& nextRange = ParentType::operator[](elemI+1);
|
||||
labelRange& nextRange = StorageContainer::operator[](elemI+1);
|
||||
if (currRange.overlaps(nextRange, true))
|
||||
{
|
||||
currRange.join(nextRange);
|
||||
@ -187,7 +188,7 @@ bool Foam::labelRanges::remove(const labelRange& range)
|
||||
|
||||
forAll(*this, elemI)
|
||||
{
|
||||
labelRange& currRange = ParentType::operator[](elemI);
|
||||
labelRange& currRange = StorageContainer::operator[](elemI);
|
||||
|
||||
if (range.first() > currRange.first())
|
||||
{
|
||||
@ -290,14 +291,14 @@ bool Foam::labelRanges::remove(const labelRange& range)
|
||||
|
||||
Foam::Istream& Foam::operator>>(Istream& is, labelRanges& ranges)
|
||||
{
|
||||
is >> static_cast<labelRanges::ParentType&>(ranges);
|
||||
is >> static_cast<labelRanges::StorageContainer&>(ranges);
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const labelRanges& ranges)
|
||||
{
|
||||
os << static_cast<const labelRanges::ParentType&>(ranges);
|
||||
os << static_cast<const labelRanges::StorageContainer&>(ranges);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
@ -62,7 +62,7 @@ class labelRanges
|
||||
{
|
||||
// Private typedefs for convenience
|
||||
|
||||
typedef DynamicList<labelRange> ParentType;
|
||||
typedef DynamicList<labelRange> StorageContainer;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
@ -28,13 +28,13 @@ License
|
||||
|
||||
inline Foam::labelRanges::labelRanges()
|
||||
:
|
||||
ParentType()
|
||||
StorageContainer()
|
||||
{}
|
||||
|
||||
|
||||
inline Foam::labelRanges::labelRanges(const label nElem)
|
||||
:
|
||||
ParentType(nElem)
|
||||
StorageContainer(nElem)
|
||||
{}
|
||||
|
||||
|
||||
@ -133,7 +133,7 @@ inline bool Foam::labelRanges::found(const label value) const
|
||||
{
|
||||
forAll(*this, i)
|
||||
{
|
||||
if (ParentType::operator[](i).found(value))
|
||||
if (StorageContainer::operator[](i).found(value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user