diff --git a/applications/test/labelRanges/Test-labelRanges.C b/applications/test/labelRanges/Test-labelRanges.C index 9f2be334d1..dec03a06f0 100644 --- a/applications/test/labelRanges/Test-labelRanges.C +++ b/applications/test/labelRanges/Test-labelRanges.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -58,6 +58,7 @@ int main(int argc, char *argv[]) } + labelRange range; labelRanges ranges; bool removeMode = false; @@ -74,14 +75,16 @@ int main(int argc, char *argv[]) continue; } - label start = 0; - label size = 0; + { + label start = 0; + label size = 0; - IStringStream(args[argI])() >> start; - ++argI; - IStringStream(args[argI])() >> size; + IStringStream(args[argI])() >> start; + ++argI; + IStringStream(args[argI])() >> size; - labelRange range(start, size); + range.reset(start, size); + } Info<< "---------------" << nl; if (removeMode) @@ -107,10 +110,11 @@ int main(int argc, char *argv[]) ranges.add(range); } - Info<< "" << ranges << "" << nl; - forAllConstIter(labelRanges, ranges, iter) + Info<< "" << ranges << "" << nl + << "content:"; + for (auto i : ranges) { - Info<< " " << iter(); + Info<< " " << i; } Info<< nl; } diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRange.C b/src/OpenFOAM/primitives/ranges/labelRange/labelRange.C index 11aacf25cb..2bf9810f6c 100644 --- a/src/OpenFOAM/primitives/ranges/labelRange/labelRange.C +++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRange.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,8 +29,6 @@ License // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -const Foam::labelRange::const_iterator Foam::labelRange::endIter_; - int Foam::labelRange::debug(::Foam::debug::debugSwitch("labelRange", 0)); @@ -47,13 +45,24 @@ Foam::labelRange::labelRange(Istream& is) // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -bool Foam::labelRange::intersects -( - const labelRange& range, - const bool touches -) const +void Foam::labelRange::adjust() { - label final = touches ? 1 : 0; + if (start_ < 0) + { + size_ += start_; + start_ = 0; + } + + if (size_ < 0) + { + size_ = 0; + } +} + + +bool Foam::labelRange::overlaps(const labelRange& range, bool touches) const +{ + const label final = touches ? 1 : 0; return ( @@ -97,7 +106,7 @@ Foam::labelRange Foam::labelRange::join(const labelRange& range) const // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // -Foam::labelRange& Foam::labelRange::operator+=(const labelRange& rhs) +void Foam::labelRange::operator+=(const labelRange& rhs) { if (!size_) { @@ -112,8 +121,6 @@ Foam::labelRange& Foam::labelRange::operator+=(const labelRange& rhs) start_ = lower; size_ = upper - lower + 1; } - - return *this; } @@ -127,10 +134,10 @@ Foam::Istream& Foam::operator>>(Istream& is, labelRange& range) is.check("operator>>(Istream&, labelRange&)"); - // disallow invalid sizes - if (range.size_ <= 0) + // Disallow invalid sizes + if (range.size_ < 0) { - range.clear(); + range.size_ = 0; } return is; @@ -139,15 +146,11 @@ Foam::Istream& Foam::operator>>(Istream& is, labelRange& range) Foam::Ostream& Foam::operator<<(Ostream& os, const labelRange& range) { - // write ASCII only for now + // Write ASCII only for now os << token::BEGIN_LIST << range.start_ << token::SPACE << range.size_ << token::END_LIST; -// os << token::BEGIN_BLOCK -// << range.start_ << "-" << range.last() -// << token::END_BLOCK; - os.check("operator<<(Ostream&, const labelRange&)"); return os; } diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRange.H b/src/OpenFOAM/primitives/ranges/labelRange/labelRange.H index 24dd33729c..3fa69c4ff3 100644 --- a/src/OpenFOAM/primitives/ranges/labelRange/labelRange.H +++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRange.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,7 +25,7 @@ Class Foam::labelRange Description - A label range specifier. + A range of labels. SourceFiles labelRange.C @@ -47,8 +47,8 @@ class Ostream; // Forward declaration of friend functions and operators class labelRange; -Istream& operator>>(Istream&, labelRange&); -Ostream& operator<<(Ostream&, const labelRange&); +Istream& operator>>(Istream& is, labelRange& range); +Ostream& operator<<(Ostream& os, const labelRange& range); /*---------------------------------------------------------------------------*\ Class labelRange Declaration @@ -63,7 +63,7 @@ class labelRange public: - static int debug; + static int debug; // Public classes @@ -75,31 +75,50 @@ public: bool operator()(const labelRange& a, const labelRange& b) { - return a.first() < b.first(); + return a.operator<(b); } }; + // Constructors - //- Construct an empty range + //- Construct an empty range with zero as start and size. inline labelRange(); - //- Construct a range - // A negative size is autmatically changed to zero. - inline labelRange(const label start, const label size); + //- Construct a range from start and size. + // Optionally adjust the start to avoid any negative indices. + // Always reduce a negative size to zero. + inline labelRange + ( + const label start, + const label size, + const bool adjustStart = false + ); //- Construct from Istream. - labelRange(Istream&); + labelRange(Istream& is); // Member Functions - //- Reset to zero size + //- Alias for setSize(const label) + inline void resize(const label n); + + //- Adjust size + inline void setSize(const label n); + + //- Reset to zero start and zero size inline void clear(); //- Is the range empty? inline bool empty() const; + //- Adjust the start to avoid any negative indices + void adjust(); + + //- Is the range valid (non-empty)? + inline bool valid() const; + //- Return the effective size of the range inline label size() const; @@ -109,32 +128,44 @@ public: //- The (inclusive) upper value of the range inline label last() const; - //- Return true if the value is within the range - inline bool contains(const label) const; + //- Reset start and 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 + ( + const label start, + const label size, + const bool adjustStart = false + ); - //- Return true if the ranges intersect + //- Return true if the value is within the range + inline bool contains(const label value) const; + + //- Return true if the ranges overlap. // Optional test for ranges that also just touch each other - bool intersects(const labelRange&, const bool touches = false) const; + bool overlaps(const labelRange& range, bool touches=false) const; //- Return a joined range, squashing any gaps in between - // A prior intersects() check can be used to avoid squashing gaps. - labelRange join(const labelRange&) const; + // A prior overlaps() check can be used to avoid squashing gaps. + labelRange join(const labelRange& range) const; // Member Operators //- Return element in range, no bounds checking - inline label operator[](const label) const; + inline label operator[](const label i) const; - //- Comparison function for sorting, compares the start + //- 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 intersects() check can be used to avoid squashing gaps. - labelRange& operator+=(const labelRange&); + // A prior overlaps() check can be used to avoid squashing gaps. + void operator+=(const labelRange& rhs); - inline bool operator==(const labelRange&) const; - inline bool operator!=(const labelRange&) const; + inline bool operator==(const labelRange& rhs) const; + inline bool operator!=(const labelRange& rhs) const; // STL iterator @@ -142,6 +173,8 @@ public: //- An STL const_iterator class const_iterator { + friend class labelRange; + // Private data //- Reference to the range for which this is an iterator @@ -150,54 +183,48 @@ public: //- Current index label index_; - public: // Constructors - //- Construct null - equivalent to an 'end' position - inline const_iterator(); - - //- Construct from range, moving to its 'begin' position - inline explicit const_iterator(const labelRange&); + //- Construct from range at 'begin' or 'end' position + inline const_iterator + ( + const labelRange& range, + const bool endIter = false + ); + public: // Member operators - inline bool operator==(const const_iterator&) const; + inline bool operator==(const const_iterator& iter) const; + inline bool operator!=(const const_iterator& iter) const; - inline bool operator!=(const const_iterator&) const; - - inline label operator*(); - inline label operator()(); + inline label operator*() const; + inline label operator()() const; inline const_iterator& operator++(); inline const_iterator operator++(int); }; - //- const_iterator set to the beginning of the range + //- A const_iterator set to the beginning of the range inline const_iterator cbegin() const; - //- const_iterator set to beyond the end of the range - inline const const_iterator& cend() const; + //- A const_iterator set to beyond the end of the range + inline const const_iterator cend() const; - //- const_iterator set to the beginning of the range + //- A const_iterator set to the beginning of the range inline const_iterator begin() const; - //- const_iterator set to beyond the end of the range - inline const const_iterator& end() const; + //- A const_iterator set to beyond the end of the range + inline const const_iterator end() const; // IOstream Operators - friend Istream& operator>>(Istream&, labelRange&); - friend Ostream& operator<<(Ostream&, const labelRange&); - - -private: - - //- const_iterator returned by end(), cend() - static const const_iterator endIter_; + friend Istream& operator>>(Istream& is, labelRange& range); + friend Ostream& operator<<(Ostream& os, const labelRange& range); }; diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRangeI.H b/src/OpenFOAM/primitives/ranges/labelRange/labelRangeI.H index 21e839cf3c..927a6f57a0 100644 --- a/src/OpenFOAM/primitives/ranges/labelRange/labelRangeI.H +++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRangeI.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -33,32 +33,39 @@ inline Foam::labelRange::labelRange() {} -inline Foam::labelRange::labelRange(const label start, const label size) +inline Foam::labelRange::labelRange +( + const label start, + const label size, + const bool adjustStart +) : start_(start), size_(size) { - // disallow invalid sizes - if (size_ <= 0) + if (adjustStart) { - this->clear(); + // Disallow invalid indices and sizes + adjust(); + } + else if (size_ < 0) + { + // Disallow invalid sizes + size_ = 0; } } // * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * // -inline Foam::labelRange::const_iterator::const_iterator() -: - range_(*reinterpret_cast(0)), - index_(-1) -{} - - -inline Foam::labelRange::const_iterator::const_iterator(const labelRange& range) +inline Foam::labelRange::const_iterator::const_iterator +( + const labelRange& range, + const bool endIter +) : range_(range), - index_(range_.empty() ? -1 : 0) + index_(endIter ? range_.size() : 0) {} @@ -76,17 +83,17 @@ inline bool Foam::labelRange::const_iterator::operator!= const const_iterator& iter ) const { - return !(this->operator==(iter)); + return (this->index_ != iter.index_); } -inline Foam::label 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()() +inline Foam::label Foam::labelRange::const_iterator::operator()() const { return range_[index_]; } @@ -95,12 +102,7 @@ inline Foam::label Foam::labelRange::const_iterator::operator()() inline Foam::labelRange::const_iterator& Foam::labelRange::const_iterator::operator++() { - if (++index_ >= range_.size()) - { - // equivalent to end iterator - index_ = -1; - } - + ++index_; return *this; } @@ -109,7 +111,7 @@ inline Foam::labelRange::const_iterator Foam::labelRange::const_iterator::operator++(int) { const_iterator old = *this; - this->operator++(); + ++index_; return old; } @@ -120,9 +122,9 @@ inline Foam::labelRange::const_iterator Foam::labelRange::cbegin() const } -inline const Foam::labelRange::const_iterator& Foam::labelRange::cend() const +inline const Foam::labelRange::const_iterator Foam::labelRange::cend() const { - return endIter_; + return const_iterator(*this, true); } @@ -132,14 +134,31 @@ inline Foam::labelRange::const_iterator Foam::labelRange::begin() const } -inline const Foam::labelRange::const_iterator& Foam::labelRange::end() const +inline const Foam::labelRange::const_iterator Foam::labelRange::end() const { - return endIter_; + return const_iterator(*this, true); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +inline void Foam::labelRange::resize(const label n) +{ + setSize(n); +} + + +inline void Foam::labelRange::setSize(const label n) +{ + size_ = n; + + if (size_ < 0) + { + size_ = 0; + } +} + + inline void Foam::labelRange::clear() { start_ = size_ = 0; @@ -152,6 +171,12 @@ inline bool Foam::labelRange::empty() const } +inline bool Foam::labelRange::valid() const +{ + return size_; +} + + inline Foam::label Foam::labelRange::size() const { return size_; @@ -170,6 +195,31 @@ inline Foam::label Foam::labelRange::last() const } +inline bool Foam::labelRange::reset +( + const label start, + const label size, + const bool adjustStart +) +{ + start_ = start; + size_ = size; + + if (adjustStart) + { + // Disallow invalid indices and sizes + adjust(); + } + else if (size_ < 0) + { + // Disallow invalid sizes + size_ = 0; + } + + return size_; +} + + inline bool Foam::labelRange::contains(const label value) const { return value >= this->first() && value <= this->last(); @@ -186,7 +236,11 @@ inline Foam::label Foam::labelRange::operator[](const label i) const inline bool Foam::labelRange::operator<(const labelRange& rhs) const { - return this->first() < rhs.first(); + return + ( + this->first() < rhs.first() + || (this->first() == rhs.first() && this->size() < rhs.size()) + ); } diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.C b/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.C index 101c2bce98..d9edff0e47 100644 --- a/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.C +++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,11 +26,6 @@ License #include "labelRanges.H" #include "ListOps.H" -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -const Foam::labelRanges::const_iterator Foam::labelRanges::endIter_; - - // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // void Foam::labelRanges::insertBefore @@ -141,7 +136,7 @@ bool Foam::labelRanges::add(const labelRange& range) { labelRange& currRange = ParentType::operator[](elemI); - if (currRange.intersects(range, true)) + if (currRange.overlaps(range, true)) { // absorb into the existing (adjacent/overlapping) range currRange += range; @@ -150,7 +145,7 @@ bool Foam::labelRanges::add(const labelRange& range) for (; elemI < this->size()-1; ++elemI) { labelRange& nextRange = ParentType::operator[](elemI+1); - if (currRange.intersects(nextRange, true)) + if (currRange.overlaps(nextRange, true)) { currRange += nextRange; nextRange.clear(); diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.H b/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.H index 6fa10b0aac..134acb0482 100644 --- a/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.H +++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -49,8 +49,8 @@ class Ostream; // Forward declaration of friend functions and operators class labelRanges; -Istream& operator>>(Istream&, labelRanges&); -Ostream& operator<<(Ostream&, const labelRanges&); +Istream& operator>>(Istream& is, labelRanges& ranges); +Ostream& operator<<(Ostream& is, const labelRanges& ranges); /*---------------------------------------------------------------------------*\ Class labelRanges Declaration @@ -68,13 +68,13 @@ class labelRanges // Private Member Functions //- Insert range before specified insertion index, by copying up - void insertBefore(const label, const labelRange&); + void insertBefore(const label insert, const labelRange& range); //- Purge empty ranges, by copying down void purgeEmpty(); //- Print the range for debugging purposes - Ostream& printRange(Ostream&, const labelRange&) const; + Ostream& printRange(Ostream& os, const labelRange& range) const; public: @@ -85,10 +85,10 @@ public: inline labelRanges(); //- Construct given size - inline explicit labelRanges(const label); + inline explicit labelRanges(const label nElem); //- Construct from Istream. - labelRanges(Istream&); + labelRanges(Istream& is); // Member Functions @@ -100,19 +100,22 @@ public: using DynamicList::empty; //- Return true if the value is within any of the ranges - inline bool contains(const label) const; + inline bool contains(const label value) const; //- Add the range to the list - bool add(const labelRange&); + bool add(const labelRange& range); //- Remove the range from the list - bool remove(const labelRange&); + bool remove(const labelRange& range); + // STL iterator //- An STL const_iterator class const_iterator { + friend class labelRanges; + // Private data //- Reference to the list for which this is an iterator @@ -124,22 +127,21 @@ public: //- Index of current element at listIndex label subIndex_; - public: - // Constructors - //- Construct null - equivalent to an 'end' position - inline const_iterator(); - - //- Construct from list, moving to its 'begin' position - inline explicit const_iterator(const labelRanges&); + //- Construct from ranges at 'begin' or 'end' position + inline const_iterator + ( + const labelRanges& lst, + const bool endIter = false + ); + public: // Member operators - inline bool operator==(const const_iterator&) const; - - inline bool operator!=(const const_iterator&) const; + inline bool operator==(const const_iterator& iter) const; + inline bool operator!=(const const_iterator& iter) const; inline label operator*(); inline label operator()(); @@ -149,29 +151,23 @@ public: }; - //- const_iterator set to the beginning of the list + //- A const_iterator set to the beginning of the list inline const_iterator cbegin() const; - //- const_iterator set to beyond the end of the list - inline const const_iterator& cend() const; + //- A const_iterator set to beyond the end of the list + inline const const_iterator cend() const; - //- const_iterator set to the beginning of the list + //- A const_iterator set to the beginning of the list inline const_iterator begin() const; - //- const_iterator set to beyond the end of the list - inline const const_iterator& end() const; + //- A const_iterator set to beyond the end of the list + inline const const_iterator end() const; // IOstream Operators - friend Istream& operator>>(Istream&, labelRanges&); - friend Ostream& operator<<(Ostream&, const labelRanges&); - - -private: - - //- const_iterator returned by end(), cend() - static const const_iterator endIter_; + friend Istream& operator>>(Istream& is, labelRanges& ranges); + friend Ostream& operator<<(Ostream& os, const labelRanges& ranges); }; diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRangesI.H b/src/OpenFOAM/primitives/ranges/labelRange/labelRangesI.H index 739d582e9f..9ccad0e300 100644 --- a/src/OpenFOAM/primitives/ranges/labelRange/labelRangesI.H +++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRangesI.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -40,28 +40,18 @@ inline Foam::labelRanges::labelRanges(const label nElem) // * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * // -inline Foam::labelRanges::const_iterator::const_iterator() +inline Foam::labelRanges::const_iterator::const_iterator +( + const labelRanges& lst, + const bool endIter +) : - list_(*reinterpret_cast(0)), - index_(-1), - subIndex_(-1) + list_(lst), + index_(endIter ? lst.size() : 0), + subIndex_(0) {} -inline Foam::labelRanges::const_iterator::const_iterator(const labelRanges& lst) -: - list_(lst), - index_(0), - subIndex_(0) -{ - if (list_.empty()) - { - // equivalent to end iterator - index_ = subIndex_ = -1; - } -} - - inline bool Foam::labelRanges::const_iterator::operator== ( const const_iterator& iter @@ -69,7 +59,7 @@ inline bool Foam::labelRanges::const_iterator::operator== { return ( - this->index_ == iter.index_ + this->index_ == iter.index_ && this->subIndex_ == iter.subIndex_ ); } @@ -101,13 +91,9 @@ Foam::labelRanges::const_iterator::operator++() { if (++subIndex_ >= list_[index_].size()) { - // go to next list entry + // Next sub-list + ++index_; subIndex_ = 0; - if (++index_ >= list_.size()) - { - // equivalent to end iterator - index_ = subIndex_ = -1; - } } return *this; @@ -129,9 +115,9 @@ inline Foam::labelRanges::const_iterator Foam::labelRanges::cbegin() const } -inline const Foam::labelRanges::const_iterator& Foam::labelRanges::cend() const +inline const Foam::labelRanges::const_iterator Foam::labelRanges::cend() const { - return endIter_; + return const_iterator(*this, true); } @@ -141,9 +127,9 @@ inline Foam::labelRanges::const_iterator Foam::labelRanges::begin() const } -inline const Foam::labelRanges::const_iterator& Foam::labelRanges::end() const +inline const Foam::labelRanges::const_iterator Foam::labelRanges::end() const { - return endIter_; + return const_iterator(*this, true); }