diff --git a/applications/test/labelRanges/Make/files b/applications/test/labelRanges/Make/files
new file mode 100644
index 0000000000..df0fcc4843
--- /dev/null
+++ b/applications/test/labelRanges/Make/files
@@ -0,0 +1,3 @@
+Test-labelRanges.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-labelRanges
diff --git a/applications/test/labelRanges/Make/options b/applications/test/labelRanges/Make/options
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/applications/test/labelRanges/Test-labelRanges.C b/applications/test/labelRanges/Test-labelRanges.C
new file mode 100644
index 0000000000..d7ef91301d
--- /dev/null
+++ b/applications/test/labelRanges/Test-labelRanges.C
@@ -0,0 +1,121 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+Application
+
+Description
+ Test label ranges
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "IOobject.H"
+#include "IOstreams.H"
+#include "IFstream.H"
+#include "IStringStream.H"
+#include "labelRanges.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+ argList::noParallel();
+ argList::validArgs.insert("start size .. startN sizeN");
+ argList::addOption("verbose");
+ argList::addNote
+ (
+ "The default is to add ranges, use 'add' and 'del' to toggle\n\n"
+ "Eg, 0 10 30 10 del 20 15"
+ );
+
+ argList args(argc, argv, false, true);
+
+ if (args.optionFound("verbose"))
+ {
+ labelRange::debug = 1;
+ }
+
+
+ labelRanges ranges;
+
+ bool removeMode = false;
+ for (label argI=1; argI < args.size()-1; ++argI)
+ {
+ if (args[argI] == "add")
+ {
+ removeMode = false;
+ continue;
+ }
+ else if (args[argI] == "del")
+ {
+ removeMode = true;
+ continue;
+ }
+
+ label start = 0;
+ label size = 0;
+
+ IStringStream(args[argI])() >> start;
+ ++argI;
+ IStringStream(args[argI])() >> size;
+
+ labelRange range(start, size);
+
+ Info<< "---------------" << nl;
+ if (removeMode)
+ {
+ Info<< "del " << range << " :";
+ forAllConstIter(labelRange, range, iter)
+ {
+ Info<< " " << iter();
+ }
+ Info<< nl;
+
+ ranges.remove(range);
+ }
+ else
+ {
+ Info<< "add " << range << " :";
+ forAllConstIter(labelRange, range, iter)
+ {
+ Info<< " " << iter();
+ }
+ Info<< nl;
+
+ ranges.add(range);
+ }
+
+ Info<< "" << ranges << "
" << nl;
+ forAllConstIter(labelRanges, ranges, iter)
+ {
+ Info<< " " << iter();
+ }
+ Info<< nl;
+ }
+
+ return 0;
+}
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 6f0c12d89a..9cc3dd17b9 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -65,6 +65,8 @@ primitives/random/Random/Random.C
primitives/random/cachedRandom/cachedRandom.H
ranges = primitives/ranges
+$(ranges)/labelRange/labelRange.C
+$(ranges)/labelRange/labelRanges.C
$(ranges)/scalarRange/scalarRange.C
$(ranges)/scalarRange/scalarRanges.C
diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRange.C b/src/OpenFOAM/primitives/ranges/labelRange/labelRange.C
new file mode 100644
index 0000000000..fa4ed366cf
--- /dev/null
+++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRange.C
@@ -0,0 +1,156 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+\*---------------------------------------------------------------------------*/
+
+#include "labelRange.H"
+#include "token.H"
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::labelRange::const_iterator Foam::labelRange::endIter_;
+
+int Foam::labelRange::debug(::Foam::debug::debugSwitch("labelRange", 0));
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::labelRange::labelRange(Istream& is)
+:
+ start_(0),
+ size_(0)
+{
+ is >> *this;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+bool Foam::labelRange::intersects
+(
+ const labelRange& range,
+ const bool touches
+) const
+{
+ label final = touches ? 1 : 0;
+
+ return
+ (
+ this->size()
+ && range.size()
+ &&
+ (
+ (
+ range.first() >= this->first()
+ && range.first() <= this->last() + final
+ )
+ ||
+ (
+ this->first() >= range.first()
+ && this->first() <= range.last() + final
+ )
+ )
+ );
+}
+
+
+Foam::labelRange Foam::labelRange::join(const labelRange& range) const
+{
+ // trivial cases first
+ if (!size_)
+ {
+ return *this;
+ }
+ 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;
+
+ return labelRange(lower, sz);
+}
+
+
+// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
+
+Foam::labelRange& Foam::labelRange::operator+=(const labelRange& rhs)
+{
+ if (!size_)
+ {
+ // trivial case
+ operator=(rhs);
+ }
+ else if (rhs.size_)
+ {
+ const label lower = Foam::min(this->first(), rhs.first());
+ const label upper = Foam::max(this->last(), rhs.last());
+
+ start_ = lower;
+ size_ = upper - lower + 1;
+ }
+
+ return *this;
+}
+
+
+// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
+
+Foam::Istream& Foam::operator>>(Istream& is, labelRange& range)
+{
+ is.readBegin("labelRange");
+ is >> range.start_ >> range.size_;
+ is.readEnd("labelRange");
+
+ is.check("operator>>(Istream&, labelRange&)");
+
+ // disallow invalid sizes
+ if (range.size_ <= 0)
+ {
+ range.clear();
+ }
+
+ return is;
+}
+
+
+Foam::Ostream& Foam::operator<<(Ostream& os, const labelRange& range)
+{
+ // 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
new file mode 100644
index 0000000000..2d4fcc4f84
--- /dev/null
+++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRange.H
@@ -0,0 +1,215 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+Class
+ Foam::labelRange
+
+Description
+ A label range specifier.
+
+SourceFiles
+ labelRange.C
+
+\*---------------------------------------------------------------------------*/
+#ifndef labelRange_H
+#define labelRange_H
+
+#include "label.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class Istream;
+class Ostream;
+
+// Forward declaration of friend functions and operators
+class labelRange;
+Istream& operator>>(Istream&, labelRange&);
+Ostream& operator<<(Ostream&, const labelRange&);
+
+/*---------------------------------------------------------------------------*\
+ Class labelRange Declaration
+\*---------------------------------------------------------------------------*/
+
+class labelRange
+{
+ // Private data
+
+ label start_;
+ label size_;
+
+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.first() < b.first();
+ }
+ };
+
+ // Constructors
+
+ //- Construct an empty range
+ inline labelRange();
+
+ //- Construct a range
+ // A negative size is autmatically changed to zero.
+ inline labelRange(const label start, const label size);
+
+ //- Construct from Istream.
+ labelRange(Istream&);
+
+
+ // Member Functions
+
+ //- Reset to zero size
+ inline void clear();
+
+ //- Is the range empty?
+ inline bool empty() const;
+
+ //- Return the effective size of the range
+ inline label size() const;
+
+ //- The (inclusive) lower value of the range
+ inline label first() const;
+
+ //- 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;
+
+ //- Return true if the ranges intersect
+ // Optional test for ranges that also just touch each other
+ bool intersects(const labelRange&, const 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;
+
+
+ // Member Operators
+
+ //- Return element in range, no bounds checking
+ inline label operator[](const label) const;
+
+ //- Comparison function for sorting, compares the start
+ 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&);
+
+ inline bool operator==(const labelRange&) const;
+ inline bool operator!=(const labelRange&) const;
+
+
+ // STL iterator
+
+ //- An STL const_iterator
+ class const_iterator
+ {
+ // Private data
+
+ //- Reference to the range for which this is an iterator
+ const labelRange& range_;
+
+ //- 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&);
+
+
+ // Member operators
+
+ inline bool operator==(const const_iterator&) const;
+
+ inline bool operator!=(const const_iterator&) const;
+
+ inline label operator*();
+ inline label operator()();
+
+ inline const_iterator& operator++();
+ inline const_iterator operator++(int);
+ };
+
+
+ //- 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;
+
+ //- 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;
+
+
+ // 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_;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "labelRangeI.H"
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRangeI.H b/src/OpenFOAM/primitives/ranges/labelRange/labelRangeI.H
new file mode 100644
index 0000000000..3070657cca
--- /dev/null
+++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRangeI.H
@@ -0,0 +1,205 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+\*---------------------------------------------------------------------------*/
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+inline Foam::labelRange::labelRange()
+:
+ start_(0),
+ size_(0)
+{}
+
+
+inline Foam::labelRange::labelRange(const label start, const label size)
+:
+ start_(start),
+ size_(size)
+{
+ // disallow invalid sizes
+ if (size_ <= 0)
+ {
+ this->clear();
+ }
+}
+
+
+// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
+
+inline Foam::labelRange::const_iterator::const_iterator()
+:
+ range_(*reinterpret_cast< Foam::labelRange* >(0)),
+ index_(-1)
+{}
+
+
+inline Foam::labelRange::const_iterator::const_iterator(const labelRange& range)
+:
+ range_(range),
+ index_(range_.empty() ? -1 : 0)
+{}
+
+
+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->operator==(iter));
+}
+
+
+inline Foam::label Foam::labelRange::const_iterator::operator*()
+{
+ return range_[index_];
+}
+
+
+inline Foam::label Foam::labelRange::const_iterator::operator()()
+{
+ return range_[index_];
+}
+
+
+inline Foam::labelRange::const_iterator&
+Foam::labelRange::const_iterator::operator++()
+{
+ if (++index_ >= range_.size())
+ {
+ // equivalent to end iterator
+ index_ = -1;
+ }
+
+ return *this;
+}
+
+
+inline Foam::labelRange::const_iterator
+Foam::labelRange::const_iterator::operator++(int)
+{
+ const_iterator old = *this;
+ this->operator++();
+ return old;
+}
+
+
+inline Foam::labelRange::const_iterator Foam::labelRange::cbegin() const
+{
+ return const_iterator(*this);
+}
+
+
+inline const Foam::labelRange::const_iterator& Foam::labelRange::cend() const
+{
+ return endIter_;
+}
+
+
+inline Foam::labelRange::const_iterator Foam::labelRange::begin() const
+{
+ return const_iterator(*this);
+}
+
+
+inline const Foam::labelRange::const_iterator& Foam::labelRange::end() const
+{
+ return endIter_;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+inline void Foam::labelRange::clear()
+{
+ start_ = size_ = 0;
+}
+
+
+inline bool Foam::labelRange::empty() const
+{
+ return !size_;
+}
+
+
+inline Foam::label Foam::labelRange::size() const
+{
+ return size_;
+}
+
+
+inline Foam::label Foam::labelRange::first() const
+{
+ return start_;
+}
+
+
+inline Foam::label Foam::labelRange::last() const
+{
+ return start_ + size_ - 1;
+}
+
+
+inline bool Foam::labelRange::contains(const label value) const
+{
+ 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();
+}
+
+
+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
+{
+ return !(operator==(rhs));
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.C b/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.C
new file mode 100644
index 0000000000..188e63e5f0
--- /dev/null
+++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.C
@@ -0,0 +1,310 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+\*---------------------------------------------------------------------------*/
+
+#include "labelRanges.H"
+#include "ListOps.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::labelRanges::const_iterator Foam::labelRanges::endIter_;
+
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+void Foam::labelRanges::insertBefore
+(
+ const label insert,
+ const labelRange& range
+)
+{
+ // insert via copying up
+ label nElem = this->size();
+
+ if (labelRange::debug)
+ {
+ Info<<"before insert "
+ << nElem << " elements, insert at " << insert << nl
+ << *this << endl;
+ }
+
+ ParentType::setSize(nElem+1);
+
+ if (labelRange::debug)
+ {
+ Info<<"copy between " << nElem << " and " << insert << nl;
+ }
+
+ for (label i = nElem-1; i >= insert; --i)
+ {
+ if (labelRange::debug)
+ {
+ Info<<"copy from " << (i) << " to " << (i+1) << nl;
+ }
+
+ ParentType::operator[](i+1) = ParentType::operator[](i);
+ }
+
+ // finally insert the range
+ if (labelRange::debug)
+ {
+ Info<< "finally insert the range at " << insert << nl;
+ }
+ ParentType::operator[](insert) = range;
+}
+
+
+void Foam::labelRanges::purgeEmpty()
+{
+ // purge empty ranges by copying down
+ label nElem = 0;
+ forAll(*this, elemI)
+ {
+ if (!ParentType::operator[](elemI).empty())
+ {
+ if (nElem != elemI)
+ {
+ ParentType::operator[](nElem) = ParentType::operator[](elemI);
+ }
+ ++nElem;
+ }
+ }
+
+ // truncate
+ this->ParentType::setSize(nElem);
+}
+
+
+Foam::Ostream& Foam::labelRanges::printRange
+(
+ Ostream& os,
+ const labelRange& range
+) const
+{
+ if (range.empty())
+ {
+ os << "empty";
+ }
+ else
+ {
+ os << range << " = " << range.first() << ":" << range.last();
+ }
+ return os;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::labelRanges::labelRanges(Istream& is)
+{
+ is >> *this;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+bool Foam::labelRanges::add(const labelRange& range)
+{
+ if (range.empty())
+ {
+ return false;
+ }
+ else if (this->empty())
+ {
+ this->append(range);
+ return true;
+ }
+
+ // find the correct place for insertion
+ forAll(*this, elemI)
+ {
+ labelRange& currRange = ParentType::operator[](elemI);
+
+ if (currRange.intersects(range, true))
+ {
+ // absorb into the existing (adjacent/overlapping) range
+ currRange += range;
+
+ // might connect with the next following range(s)
+ for (; elemI < this->size()-1; ++elemI)
+ {
+ labelRange& nextRange = ParentType::operator[](elemI+1);
+ if (currRange.intersects(nextRange, true))
+ {
+ currRange += nextRange;
+ nextRange.clear();
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ // done - remove any empty ranges that might have been created
+ purgeEmpty();
+ return true;
+ break;
+ }
+ else if (range < currRange)
+ {
+ insertBefore(elemI, range);
+ return true;
+ break;
+ }
+ }
+
+
+ // not found: simply append
+ this->append(range);
+
+ return true;
+}
+
+
+bool Foam::labelRanges::remove(const labelRange& range)
+{
+ bool status = false;
+ if (range.empty() || this->empty())
+ {
+ return status;
+ }
+
+ forAll(*this, elemI)
+ {
+ labelRange& currRange = ParentType::operator[](elemI);
+
+ if (range.first() > currRange.first())
+ {
+ if (range.last() < currRange.last())
+ {
+ // removal of range fragments of currRange
+
+ if (labelRange::debug)
+ {
+ Info<<"Fragment removal ";
+ printRange(Info, range) << " from ";
+ printRange(Info, currRange) << endl;
+ }
+
+ // left-hand-side fragment: insert before current range
+ label lower = currRange.first();
+ label upper = range.first() - 1;
+
+ labelRange fragment(lower, upper - lower + 1);
+
+ // right-hand-side fragment
+ lower = range.last() + 1;
+ upper = currRange.last();
+
+ currRange = labelRange(lower, upper - lower + 1);
+ status = true;
+ insertBefore(elemI, fragment);
+
+ if (labelRange::debug)
+ {
+ Info<<"fragment ";
+ printRange(Info, fragment) << endl;
+ Info<<"yields ";
+ printRange(Info, currRange) << endl;
+ }
+
+ // fragmentation can only affect a single range
+ // thus we are done
+ break;
+ }
+ else if (range.first() <= currRange.last())
+ {
+ // keep left-hand-side, remove right-hand-side
+
+ if (labelRange::debug)
+ {
+ Info<<"RHS removal ";
+ printRange(Info, range) << " from ";
+ printRange(Info, currRange) << endl;
+ }
+
+ const label lower = currRange.first();
+ const label upper = range.first() - 1;
+
+ currRange = labelRange(lower, upper - lower + 1);
+ status = true;
+
+ if (labelRange::debug)
+ {
+ Info<<"yields ";
+ printRange(Info, currRange) << endl;
+ }
+ }
+ }
+ else if (range.first() <= currRange.first())
+ {
+ if (range.last() >= currRange.first())
+ {
+ // remove left-hand-side, keep right-hand-side
+
+ if (labelRange::debug)
+ {
+ Info<<"LHS removal ";
+ printRange(Info, range) << " from ";
+ printRange(Info, currRange) << endl;
+ }
+
+ const label lower = range.last() + 1;
+ const label upper = currRange.last();
+
+ currRange = labelRange(lower, upper - lower + 1);
+ status = true;
+
+ if (labelRange::debug)
+ {
+ Info<<"yields ";
+ printRange(Info, currRange) << endl;
+ }
+ }
+ }
+ }
+
+ purgeEmpty();
+
+ return status;
+}
+
+
+// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
+
+Foam::Istream& Foam::operator>>(Istream& is, labelRanges& ranges)
+{
+ is >> static_cast(ranges);
+ return is;
+}
+
+
+Foam::Ostream& Foam::operator<<(Ostream& os, const labelRanges& ranges)
+{
+ os << static_cast(ranges);
+ return os;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.H b/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.H
new file mode 100644
index 0000000000..d8b00970d0
--- /dev/null
+++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRanges.H
@@ -0,0 +1,191 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+Class
+ Foam::labelRanges
+
+Description
+ A list of labelRange.
+
+SourceFiles
+ labelRanges.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef labelRanges_H
+#define labelRanges_H
+
+#include "labelRange.H"
+#include "DynamicList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class Istream;
+class Ostream;
+
+// Forward declaration of friend functions and operators
+class labelRanges;
+Istream& operator>>(Istream&, labelRanges&);
+Ostream& operator<<(Ostream&, const labelRanges&);
+
+/*---------------------------------------------------------------------------*\
+ Class labelRanges Declaration
+\*---------------------------------------------------------------------------*/
+
+class labelRanges
+:
+ private DynamicList
+{
+ // Private typedefs for convenience
+
+ typedef DynamicList ParentType;
+
+
+ // Private Member Functions
+
+ //- Insert range before specified insertion index, by copying up
+ void insertBefore(const label, const labelRange&);
+
+ //- Purge empty ranges, by copying down
+ void purgeEmpty();
+
+ //- Print the range for debugging purposes
+ Ostream& printRange(Ostream&, const labelRange&) const;
+
+
+public:
+
+ // Constructors
+
+ //- Construct null
+ inline labelRanges();
+
+ //- Construct given size
+ inline explicit labelRanges(const label);
+
+ //- Construct from Istream.
+ labelRanges(Istream&);
+
+
+ // Member Functions
+
+ //- Clear the addressed list
+ using DynamicList::clear;
+
+ //- Return true if the list is empty
+ using DynamicList::empty;
+
+ //- Return true if the value is within any of the ranges
+ inline bool contains(const label) const;
+
+ //- Add the range to the list
+ bool add(const labelRange&);
+
+ //- Remove the range from the list
+ bool remove(const labelRange&);
+
+ // STL iterator
+
+ //- An STL const_iterator
+ class const_iterator
+ {
+ // Private data
+
+ //- Reference to the list for which this is an iterator
+ const labelRanges& list_;
+
+ //- Current list index
+ label index_;
+
+ //- 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&);
+
+
+ // Member operators
+
+ inline bool operator==(const const_iterator&) const;
+
+ inline bool operator!=(const const_iterator&) const;
+
+ inline label operator*();
+ inline label operator()();
+
+ inline const_iterator& operator++();
+ inline const_iterator operator++(int);
+ };
+
+
+ //- 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;
+
+ //- 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;
+
+
+ // 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_;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "labelRangesI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRangesI.H b/src/OpenFOAM/primitives/ranges/labelRange/labelRangesI.H
new file mode 100644
index 0000000000..d4b34ace9f
--- /dev/null
+++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRangesI.H
@@ -0,0 +1,166 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+\*---------------------------------------------------------------------------*/
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+inline Foam::labelRanges::labelRanges()
+:
+ ParentType()
+{}
+
+
+inline Foam::labelRanges::labelRanges(const label nElem)
+:
+ ParentType(nElem)
+{}
+
+
+// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
+
+inline Foam::labelRanges::const_iterator::const_iterator()
+:
+ list_(*reinterpret_cast< Foam::labelRanges* >(0)),
+ index_(-1),
+ subIndex_(-1)
+{}
+
+
+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
+) const
+{
+ return
+ (
+ this->index_ == iter.index_
+ && this->subIndex_ == iter.subIndex_
+ );
+}
+
+
+inline bool Foam::labelRanges::const_iterator::operator!=
+(
+ const const_iterator& iter
+) const
+{
+ return !(this->operator==(iter));
+}
+
+
+inline Foam::label Foam::labelRanges::const_iterator::operator*()
+{
+ return list_[index_][subIndex_];
+}
+
+
+inline Foam::label Foam::labelRanges::const_iterator::operator()()
+{
+ return list_[index_][subIndex_];
+}
+
+
+inline Foam::labelRanges::const_iterator&
+Foam::labelRanges::const_iterator::operator++()
+{
+ if (++subIndex_ >= list_[index_].size())
+ {
+ // go to next list entry
+ subIndex_ = 0;
+ if (++index_ >= list_.size())
+ {
+ // equivalent to end iterator
+ index_ = subIndex_ = -1;
+ }
+ }
+
+ return *this;
+}
+
+
+inline Foam::labelRanges::const_iterator
+Foam::labelRanges::const_iterator::operator++(int)
+{
+ const_iterator old = *this;
+ this->operator++();
+ return old;
+}
+
+
+inline Foam::labelRanges::const_iterator Foam::labelRanges::cbegin() const
+{
+ return const_iterator(*this);
+}
+
+
+inline const Foam::labelRanges::const_iterator& Foam::labelRanges::cend() const
+{
+ return endIter_;
+}
+
+
+inline Foam::labelRanges::const_iterator Foam::labelRanges::begin() const
+{
+ return const_iterator(*this);
+}
+
+
+inline const Foam::labelRanges::const_iterator& Foam::labelRanges::end() const
+{
+ return endIter_;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+inline bool Foam::labelRanges::contains(const label value) const
+{
+ forAll(*this, i)
+ {
+ if (this->ParentType::operator[](i).contains(value))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+// ************************************************************************* //