Commit 75ef6f4e authored by Mark OLESEN's avatar Mark OLESEN
Browse files

ENH: add labelRange comparison operators and subset methods

- improve interface consistency.
parent 7b427c38
......@@ -54,6 +54,34 @@ int main(int argc, char *argv[])
labelRange::debug = 1;
}
{
Info<<"test sorting" << endl;
DynamicList<labelRange> list1(10);
list1.append(labelRange(25, 8));
list1.append(labelRange(0, 10));
list1.append(labelRange(15, 5));
list1.append(labelRange(50, -10));
sort(list1);
Info<<"sorted" << list1 << endl;
}
{
Info<<"test intersections" << endl;
labelRange range1(-15, 25);
labelRange range2(7, 8);
labelRange range3(-20, 8);
labelRange range4(50, 8);
Info<<range1 << " & " << range2
<< " = " << range1.subset(range2) << nl;
Info<< range1 << " & " << range3
<< " = " << range1.subset(range3) << nl;
Info<< range2 << " & " << range4
<< " = " << range2.subset(range4) << nl;
}
labelRange range;
labelRanges ranges;
......
......@@ -29,7 +29,10 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::labelRange::debug(::Foam::debug::debugSwitch("labelRange", 0));
namespace Foam
{
int labelRange::debug(debug::debugSwitch("labelRange", 0));
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
......@@ -66,8 +69,7 @@ bool Foam::labelRange::overlaps(const labelRange& range, bool touches) const
return
(
this->size()
&& range.size()
this->size() && range.size()
&&
(
(
......@@ -91,35 +93,59 @@ Foam::labelRange Foam::labelRange::join(const labelRange& range) const
{
return *this;
}
else if (!range.size_)
else if (!range.size())
{
return range;
}
const label lower = Foam::min(this->first(), range.first());
const label upper = Foam::max(this->last(), range.last());
const label sz = upper - lower + 1;
const label total = upper+1 - lower;
// last = start+size-1
// size = last+1-start
return labelRange(lower, sz);
return labelRange(lower, total);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::labelRange::operator+=(const labelRange& rhs)
Foam::labelRange Foam::labelRange::subset(const labelRange& range) const
{
if (!size_)
const label lower = Foam::max(this->first(), range.first());
const label upper = Foam::min(this->last(), range.last());
const label total = upper+1 - lower;
// last = start+size-1
// size = last+1-start
if (total > 0)
{
// trivial case
operator=(rhs);
return labelRange(lower, total);
}
else if (rhs.size_)
else
{
const label lower = Foam::min(this->first(), rhs.first());
const label upper = Foam::max(this->last(), rhs.last());
return labelRange();
}
}
start_ = lower;
size_ = upper - lower + 1;
Foam::labelRange Foam::labelRange::subset
(
const label start,
const label size
) const
{
const label lower = Foam::max(this->start(), start);
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();
}
}
......@@ -148,7 +174,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const labelRange& range)
{
// Write ASCII only for now
os << token::BEGIN_LIST
<< range.start_ << token::SPACE << range.size_
<< range.start() << token::SPACE << range.size()
<< token::END_LIST;
os.check("operator<<(Ostream&, const labelRange&)");
......
......@@ -25,7 +25,7 @@ Class
Foam::labelRange
Description
A range of labels.
A range of labels defined by a start and a size.
SourceFiles
labelRange.C
......@@ -66,28 +66,13 @@ public:
static int debug;
// Public classes
//- Less function class for sorting labelRange
class less
{
public:
bool operator()(const labelRange& a, const labelRange& b)
{
return a.operator<(b);
}
};
// Constructors
//- Construct an empty range with zero as start and size.
//- An empty range with zero for start/size.
inline labelRange();
//- Construct a range from start and size.
//- Construct a range from start and size, enforcing non-negative size.
// Optionally adjust the start to avoid any negative indices.
// Always reduce a negative size to zero.
inline labelRange
(
const label start,
......@@ -116,21 +101,23 @@ public:
//- Adjust the start to avoid any negative indices
void adjust();
//- Is the range valid (non-empty)?
//- Is the range non-empty?
inline bool valid() const;
//- Return the effective size of the range
//- The (inclusive) lower value of the range
inline label start() const;
//- The effective size of the range
inline label size() const;
//- The (inclusive) lower value of the range
//- The (inclusive) lower value of the range - same as start
inline label first() const;
//- The (inclusive) upper value of the range
inline label last() const;
//- Reset start and size.
//- Reset start and size, enforcing non-negative size.
// Optionally adjust the start to avoid any negative indices.
// Always reduce a negative size to zero.
// Return true if the updated range valid (non-empty).
inline bool reset
(
......@@ -139,8 +126,8 @@ public:
const bool adjustStart = false
);
//- Return true if the value is within the range
inline bool contains(const label value) const;
//- Return true if the value is located the range
inline bool found(const label value) const;
//- Return true if the ranges overlap.
// Optional test for ranges that also just touch each other
......@@ -150,22 +137,21 @@ public:
// A prior overlaps() check can be used to avoid squashing gaps.
labelRange join(const labelRange& range) const;
//- Calculate the intersection of the range with another.
// If there is no intersection, it returns an empty range with zero
// for start/size.
labelRange subset(const labelRange& range) const;
// Member Operators
//- Return element in range, no bounds checking
inline label operator[](const label i) const;
//- Calculate the intersection of the range with another.
// If there is no intersection, it returns an empty range with zero
// for start/size.
labelRange subset(const label start, const label size) const;
//- Comparison function for sorting, compares the start.
// If the start values are equal, also compares the size.
inline bool operator<(const labelRange& rhs) const;
//- Join ranges, squashing any gaps in between
// A prior overlaps() check can be used to avoid squashing gaps.
void operator+=(const labelRange& rhs);
// Member Operators
inline bool operator==(const labelRange& rhs) const;
inline bool operator!=(const labelRange& rhs) const;
//- Return element in the range, no bounds checking
inline label operator[](const label localIndex) const;
// STL iterator
......@@ -175,36 +161,32 @@ public:
{
friend class labelRange;
// Private data
// Private data
//- Reference to the range for which this is an iterator
const labelRange& range_;
//- Reference to the range for which this is an iterator
const labelRange* range_;
//- Current index
label index_;
//- Current index, relative to the start
label index_;
// Constructors
// Constructors
//- Construct from range at 'begin' or 'end' position
inline const_iterator
(
const labelRange& range,
const bool endIter = false
);
//- 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
// Member operators
inline bool operator==(const const_iterator& iter) const;
inline bool operator!=(const const_iterator& iter) const;
inline bool operator==(const const_iterator& iter) const;
inline bool operator!=(const const_iterator& iter) const;
inline label operator*() const;
inline label operator()() const;
//- Return the current label
inline label operator*() const;
inline const_iterator& operator++();
inline const_iterator operator++(int);
inline const_iterator& operator++();
inline const_iterator operator++(int);
};
......@@ -229,6 +211,51 @@ public:
};
// Global Operators
inline bool operator==(const labelRange& a, const labelRange& b)
{
return (a.first() == b.first() && a.size() == b.size());
}
inline bool operator!=(const labelRange& a, const labelRange& b)
{
return !(a == b);
}
//- Comparison function for sorting, compares the start.
// If the start values are equal, also compares the size.
inline bool operator<(const labelRange& a, const labelRange& b)
{
return
(
a.first() < b.first()
||
(
!(b.first() < a.first())
&& a.size() < b.size()
)
);
}
inline bool operator<=(const labelRange& a, const labelRange& b)
{
return !(b < a);
}
inline bool operator>(const labelRange& a, const labelRange& b)
{
return (b < a);
}
inline bool operator>=(const labelRange& a, const labelRange& b)
{
return !(a < b);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
......
......@@ -60,12 +60,12 @@ inline Foam::labelRange::labelRange
inline Foam::labelRange::const_iterator::const_iterator
(
const labelRange& range,
const bool endIter
const labelRange* range,
const label i
)
:
range_(range),
index_(endIter ? range_.size() : 0)
range_(range),
index_(i < 0 ? range->size() : i)
{}
......@@ -89,13 +89,7 @@ inline bool Foam::labelRange::const_iterator::operator!=
inline Foam::label Foam::labelRange::const_iterator::operator*() const
{
return range_[index_];
}
inline Foam::label Foam::labelRange::const_iterator::operator()() const
{
return range_[index_];
return range_->start_ + index_;
}
......@@ -118,25 +112,25 @@ Foam::labelRange::const_iterator::operator++(int)
inline Foam::labelRange::const_iterator Foam::labelRange::cbegin() const
{
return const_iterator(*this);
return const_iterator(this, 0);
}
inline const Foam::labelRange::const_iterator Foam::labelRange::cend() const
{
return const_iterator(*this, true);
return const_iterator(this, -1);
}
inline Foam::labelRange::const_iterator Foam::labelRange::begin() const
{
return const_iterator(*this);
return const_iterator(this, 0);
}
inline const Foam::labelRange::const_iterator Foam::labelRange::end() const
{
return const_iterator(*this, true);
return const_iterator(this, -1);
}
......@@ -183,6 +177,12 @@ inline Foam::label Foam::labelRange::size() const
}
inline Foam::label Foam::labelRange::start() const
{
return start_;
}
inline Foam::label Foam::labelRange::first() const
{
return start_;
......@@ -220,39 +220,17 @@ inline bool Foam::labelRange::reset
}
inline bool Foam::labelRange::contains(const label value) const
inline bool Foam::labelRange::found(const label value) const
{
return value >= this->first() && value <= this->last();
return (value >= this->first() && value <= this->last());
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline Foam::label Foam::labelRange::operator[](const label i) const
{
return start_ + i;
}
inline bool Foam::labelRange::operator<(const labelRange& rhs) const
{
return
(
this->first() < rhs.first()
|| (this->first() == rhs.first() && this->size() < rhs.size())
);
}
inline bool Foam::labelRange::operator==(const labelRange& rhs) const
{
return start_ == rhs.start_ && size_ == rhs.size_;
}
inline bool Foam::labelRange::operator!=(const labelRange& rhs) const
inline Foam::label Foam::labelRange::operator[](const label localIndex) const
{
return !(operator==(rhs));
return start_ + localIndex;
}
......
......@@ -139,7 +139,7 @@ bool Foam::labelRanges::add(const labelRange& range)
if (currRange.overlaps(range, true))
{
// absorb into the existing (adjacent/overlapping) range
currRange += range;
currRange.join(range);
// might connect with the next following range(s)
for (; elemI < this->size()-1; ++elemI)
......@@ -147,7 +147,7 @@ bool Foam::labelRanges::add(const labelRange& range)
labelRange& nextRange = ParentType::operator[](elemI+1);
if (currRange.overlaps(nextRange, true))
{
currRange += nextRange;
currRange.join(nextRange);
nextRange.clear();
}
else
......
......@@ -99,8 +99,8 @@ public:
//- Return true if the list is empty
using DynamicList<labelRange>::empty;
//- Return true if the value is within any of the ranges
inline bool contains(const label value) const;
//- Return true if the value is found any of the sub-ranges
inline bool found(const label value) const;
//- Add the range to the list
bool add(const labelRange& range);
......@@ -116,38 +116,35 @@ public:
{
friend class labelRanges;
// Private data
// Private data
//- Reference to the list for which this is an iterator
const labelRanges& list_;
//- Reference to the list for which this is an iterator
const labelRanges* list_;
//- Current list index
label index_;
//- Current list-index
label index_;
//- Index of current element at listIndex
label subIndex_;
//- Index of current element at list-index
label subIndex_;
// Constructors
// Constructors
//- Construct from ranges at 'begin' or 'end' position
inline const_iterator
(
const labelRanges& lst,
const bool endIter = false
);
//- Construct from ranges at given index.
// A negative index signals the 'end' position
inline const_iterator(const labelRanges* lst, const label i);
public:
// Member operators
// Member operators
inline bool operator==(const const_iterator& iter) const;
inline bool operator!=(const const_iterator& iter) const;
inline bool operator==(const const_iterator& iter) const;
inline bool operator!=(const const_iterator& iter) const;
inline label operator*();
inline label operator()();
//- Return the current label
inline label operator*();
inline const_iterator& operator++();
inline const_iterator operator++(int);
inline const_iterator& operator++();
inline const_iterator operator++(int);
};
......
......@@ -42,12 +42,12 @@ inline Foam::labelRanges::labelRanges(const label nElem)
inline Foam::labelRanges::const_iterator::const_iterator
(
const labelRanges& lst,
const bool endIter
const labelRanges* lst,
const label i
)
:
list_(lst),
index_(endIter ? lst.size() : 0),
index_(i < 0 ? lst->size() : i),
subIndex_(0)
{}
......@@ -76,20 +76,14 @@ inline bool Foam::labelRanges::const_iterator::operator!=
inline Foam::label Foam::labelRanges::const_iterator::operator*()
{
return list_[index_][subIndex_];
}
inline Foam::label Foam::labelRanges::const_iterator::operator()()
{
return list_[index_][subIndex_];
return list_->operator[](index_)[subIndex_];
}
inline Foam::labelRanges::const_iterator&
Foam::labelRanges::const_iterator::operator++()
{
if (++subIndex_ >= list_[index_].size())
if (++subIndex_ >= list_->operator[](index_).size())
{
// Next sub-list
++index_;
......@@ -111,35 +105,35 @@ Foam::labelRanges::const_iterator::operator++(int)
inline Foam::labelRanges::const_iterator Foam::labelRanges::cbegin() const
{