ENH: improvements for labelRange

- constexpr, noexcept.
  Added an 'at()' method for returning an iterator within the range
  and changed operator()(label) to have behaviour as per found().
  This makes the labelRange usable as a unary predicate.

- added templated conversion class 'toLabelRange'

- add range() method to polyPatch and surfZone classes, and corresponding
  templated conversion functors.
  For example,

      auto patchDims = ListOps::create<labelRange>
      (
          mesh.boundaryMesh(),
          toLabelRange<polyPatch>()
      );

  to create a List<labelRange> representing the patch extents.
This commit is contained in:
Mark Olesen
2018-03-04 20:30:34 +01:00
parent bcabe827f6
commit fc92d30e74
6 changed files with 232 additions and 141 deletions

View File

@ -315,6 +315,12 @@ public:
return start_; return start_;
} }
//- Return start/size range of this patch
labelRange range() const
{
return labelRange(start_, this->size());
}
//- Return boundaryMesh reference //- Return boundaryMesh reference
const polyBoundaryMesh& boundaryMesh() const; const polyBoundaryMesh& boundaryMesh() const;
@ -423,6 +429,19 @@ public:
}; };
// Global Functions
//- Get the labelRange for a polyPatch
template<>
struct toLabelRange<polyPatch>
{
labelRange operator()(const polyPatch& pp) const
{
return pp.range();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam

View File

@ -26,7 +26,6 @@ License
#include "labelRange.H" #include "labelRange.H"
#include "token.H" #include "token.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam namespace Foam
@ -50,23 +49,19 @@ Foam::labelRange::labelRange(Istream& is)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::labelRange::adjust() void Foam::labelRange::adjust() noexcept
{ {
if (start_ < 0) if (start_ < 0)
{ {
if (size_ <= 0) if (size_ > 0) // Second check needed to avoid (negative) overflow
{
size_ = 0;
}
else
{ {
size_ += start_; size_ += start_;
} }
start_ = 0; start_ = 0;
} }
else if (size_ < 0) if (size_ < 0)
{ {
size_ = 0; size_ = 0; // No negative sizes
} }
} }
@ -96,7 +91,7 @@ bool Foam::labelRange::overlaps(const labelRange& range, bool touches) const
Foam::labelRange Foam::labelRange::join(const labelRange& range) const Foam::labelRange Foam::labelRange::join(const labelRange& range) const
{ {
// trivial cases first // Trivial cases first
if (!size_) if (!size_)
{ {
return *this; return *this;
@ -128,10 +123,8 @@ Foam::labelRange Foam::labelRange::subset(const labelRange& range) const
{ {
return labelRange(lower, total); return labelRange(lower, total);
} }
else
{ return labelRange();
return labelRange();
}
} }
@ -151,10 +144,8 @@ Foam::labelRange Foam::labelRange::subset
{ {
return labelRange(lower, total); return labelRange(lower, total);
} }
else
{ return labelRange();
return labelRange();
}
} }
@ -170,10 +161,8 @@ Foam::labelRange Foam::labelRange::subset0(const label size) const
{ {
return labelRange(lower, total); return labelRange(lower, total);
} }
else
{ return labelRange();
return labelRange();
}
} }
@ -185,21 +174,19 @@ Foam::Istream& Foam::operator>>(Istream& is, labelRange& range)
is >> range.start_ >> range.size_; is >> range.start_ >> range.size_;
is.readEnd("labelRange"); is.readEnd("labelRange");
is.check(FUNCTION_NAME);
// Disallow invalid sizes
if (range.size_ < 0) if (range.size_ < 0)
{ {
range.size_ = 0; range.size_ = 0; // No negative sizes
} }
is.check(FUNCTION_NAME);
return is; return is;
} }
Foam::Ostream& Foam::operator<<(Ostream& os, const labelRange& range) Foam::Ostream& Foam::operator<<(Ostream& os, const labelRange& range)
{ {
// Write ASCII only for now // Only write as ASCII for now
os << token::BEGIN_LIST os << token::BEGIN_LIST
<< range.start() << token::SPACE << range.size() << range.start() << token::SPACE << range.size()
<< token::END_LIST; << token::END_LIST;

View File

@ -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 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -42,12 +42,11 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of classes // Forward declarations
class labelRange;
class Istream; class Istream;
class Ostream; class Ostream;
// Forward declaration of friend functions and operators
class labelRange;
Istream& operator>>(Istream& is, labelRange& range); Istream& operator>>(Istream& is, labelRange& range);
Ostream& operator<<(Ostream& os, const labelRange& range); Ostream& operator<<(Ostream& os, const labelRange& range);
@ -57,13 +56,28 @@ Ostream& operator<<(Ostream& os, const labelRange& range);
class labelRange class labelRange
{ {
// Private data // Private Data
//- The start point for the interval
label start_; label start_;
//- The length of the interval
label size_; label size_;
public: public:
// STL type definitions
//- Type of values the range contains
typedef label value_type;
//- The type that can represent the size of the range
typedef label size_type;
//- Forward iterator with const access
class const_iterator;
// Static Data Members // Static Data Members
static int debug; static int debug;
@ -72,22 +86,13 @@ public:
static const labelRange null; static const labelRange null;
// STL type definitions similar to what UList has
//- Type of values the range contains
typedef label value_type;
//- The type that can represent the size of the range
typedef label size_type;
// Forward declaration
class const_iterator;
// Constructors // Constructors
//- An empty range with zero for start/size. //- An empty range with zero for start/size.
inline labelRange(); inline constexpr labelRange() noexcept;
//- Construct a range from start/size, enforcing non-negative size.
inline labelRange(const label start, const label size) noexcept;
//- Construct a range from start/size, enforcing non-negative size. //- Construct a range from start/size, enforcing non-negative size.
// Optionally adjust the start to avoid any negative indices. // Optionally adjust the start to avoid any negative indices.
@ -95,8 +100,8 @@ public:
( (
const label start, const label start,
const label size, const label size,
const bool adjustStart = false const bool adjustStart
); ) noexcept;
//- Construct from Istream. //- Construct from Istream.
labelRange(Istream& is); labelRange(Istream& is);
@ -105,68 +110,75 @@ public:
// Static Member Functions // Static Member Functions
//- An identity range with range[i] == i. //- An identity range with range[i] == i.
inline static labelRange identity(const label len); inline static labelRange identity(const label len) noexcept;
// Member Functions // Member Functions
//- Adjust start position //- Change the start position
inline void setStart(const label i); inline void setStart(const label i) noexcept;
//- Adjust size //- Change the size
inline void setSize(const label n); inline void resize(const label n) noexcept;
//- Alias for setSize() //- Change the size - alias for resize()
inline void resize(const label n); inline void setSize(const label n) noexcept;
//- Decrease the size by 1, but never below 0. //- Decrease the size by 1, but never below 0.
inline void decrement(); inline void decrement() noexcept;
//- Increase the size by 1. //- Increase the size by 1.
inline void increment(); inline void increment() noexcept;
//- Reset to zero start and zero size //- Reset to zero start and zero size
inline void clear(); inline void clear() noexcept;
//- Is the range empty? //- Is the range empty?
inline bool empty() const; inline bool empty() const noexcept;
//- Adjust the start to avoid any negative indices //- Adjust the start to avoid negative indices.
void adjust(); // The size is decreased accordingly, but will never become negative.
// Eg, adjusting (-10, 15) becomes (0,5).
// adjusting (-20, 15) becomes (0,0)
void adjust() noexcept;
//- Is the range non-empty? //- Is the range non-empty?
inline bool valid() const; inline bool valid() const noexcept;
//- The (inclusive) lower value of the range //- The (inclusive) lower value of the range
inline label start() const; inline label start() const noexcept;
//- The effective size of the range //- The effective size of the range
inline label size() const; inline label size() const noexcept;
//- The (inclusive) lower value of the range - same as start //- The (inclusive) lower value of the range - same as start
inline label first() const; inline label first() const noexcept;
//- The (inclusive) upper value of the range //- The (inclusive) upper value of the range
inline label last() const; inline label last() const noexcept;
//- The value before the start of the range //- The value before the start of the range
inline label before() const; inline label before() const noexcept;
//- The value after the last element in the range //- The value after the last element in the range
inline label after() const; inline label after() const noexcept;
//- Reset start and size, enforcing non-negative size.
// \return true if the updated range is valid (non-empty).
inline bool reset(const label start, const label size) noexcept;
//- Reset start and size, enforcing non-negative size. //- Reset start and size, enforcing non-negative size.
// Optionally adjust the start to avoid any negative indices. // Optionally adjust the start to avoid any negative indices.
// Return true if the updated range valid (non-empty). // \return true if the updated range is valid (non-empty).
inline bool reset inline bool reset
( (
const label start, const label start,
const label size, const label size,
const bool adjustStart = false const bool adjustStart
); ) noexcept;
//- Return true if the value is located the range //- Return true if the (global) value is located within the range
inline bool found(const label value) const; inline bool found(const label value) const noexcept;
//- Return true if the ranges overlap. //- Return true if the ranges overlap.
// Optional test for ranges that also just touch each other // Optional test for ranges that also just touch each other
@ -192,21 +204,29 @@ public:
labelRange subset0(const label size) const; labelRange subset0(const label size) const;
//- Return const_iterator to element at in the range, with bounds
//- checking.
// \return iterator at the requested position, or end() if it is
// out of bounds
inline const_iterator at(const label localIndex) const;
// Member Operators // Member Operators
//- Return element in the range, no bounds checking //- Return element in the range, without bounds checking
inline label operator[](const label localIndex) const; inline label operator[](const label localIndex) const noexcept;
//- Return const_iterator to element in the range //- Return true if the (global) value is located within the range.
inline const_iterator operator()(const label localIndex) const; // Behaviour identical to found().
inline bool operator()(const label value) const noexcept;
//- Increase the size by 1. //- Increase the size by 1.
inline label operator++(); inline label operator++() noexcept;
inline label operator++(int); inline label operator++(int) noexcept;
//- Decrease the size by 1, but never below 0. //- Decrease the size by 1, but never below 0.
inline label operator--(); inline label operator--() noexcept;
inline label operator--(int); inline label operator--(int) noexcept;
// STL iterator // STL iterator
@ -223,7 +243,7 @@ public:
const label& const label&
> >
{ {
//- The current (global) value //- The current (global) index value
label value_; label value_;
public: public:
@ -231,7 +251,8 @@ public:
// Constructors // Constructors
//- Construct from range at given local index. //- Construct from range at given local index.
// A negative index is invalid and corresponds to the 'end' // If the local index is out of range (eg, negaative),
// this creates the 'end' iterator
inline const_iterator(const labelRange* range, const label i=0); inline const_iterator(const labelRange* range, const label i=0);
// Member operators // Member operators
@ -270,22 +291,28 @@ public:
}; };
// Global Functions
//- Conversion to labelRange operations
template<class Type> struct toLabelRange {};
// Global Operators // Global Operators
inline bool operator==(const labelRange& a, const labelRange& b) inline bool operator==(const labelRange& a, const labelRange& b) noexcept
{ {
return (a.first() == b.first() && a.size() == b.size()); return (a.first() == b.first() && a.size() == b.size());
} }
inline bool operator!=(const labelRange& a, const labelRange& b) inline bool operator!=(const labelRange& a, const labelRange& b) noexcept
{ {
return !(a == b); return (a.first() != b.first() || a.size() != b.size());
} }
//- Comparison function for sorting, compares the start. //- Comparison function for sorting, compares the start.
// If the start values are equal, also compares the size. // If the start values are equal, also compares the size.
inline bool operator<(const labelRange& a, const labelRange& b) inline bool operator<(const labelRange& a, const labelRange& b) noexcept
{ {
return return
( (
@ -298,18 +325,18 @@ inline bool operator<(const labelRange& a, const labelRange& b)
); );
} }
inline bool operator<=(const labelRange& a, const labelRange& b) inline bool operator<=(const labelRange& a, const labelRange& b) noexcept
{ {
return !(b < a); return !(b < a);
} }
inline bool operator>(const labelRange& a, const labelRange& b) inline bool operator>(const labelRange& a, const labelRange& b) noexcept
{ {
return (b < a); return (b < a);
} }
inline bool operator>=(const labelRange& a, const labelRange& b) inline bool operator>=(const labelRange& a, const labelRange& b) noexcept
{ {
return !(a < b); return !(a < b);
} }

View File

@ -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 | Copyright (C) 2017 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -23,35 +23,47 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::labelRange::labelRange() inline constexpr Foam::labelRange::labelRange() noexcept
: :
start_(0), start_(0),
size_(0) size_(0)
{} {}
inline Foam::labelRange::labelRange
(
const label start,
const label size
) noexcept
:
start_(start),
size_(size)
{
if (size_ < 0)
{
size_ = 0; // No negative sizes
}
}
inline Foam::labelRange::labelRange inline Foam::labelRange::labelRange
( (
const label start, const label start,
const label size, const label size,
const bool adjustStart const bool adjustStart
) ) noexcept
: :
start_(start), start_(start),
size_(size) size_(size)
{ {
if (adjustStart) if (adjustStart)
{ {
// Disallow invalid indices and sizes adjust(); // Eliminate negative start, adjust size accordingly
adjust();
} }
else if (size_ < 0) else if (size_ < 0)
{ {
// Disallow invalid sizes size_ = 0; // No negative sizes
size_ = 0;
} }
} }
@ -89,7 +101,7 @@ Foam::labelRange::const_iterator::operator++()
inline Foam::labelRange::const_iterator inline Foam::labelRange::const_iterator
Foam::labelRange::const_iterator::operator++(int) Foam::labelRange::const_iterator::operator++(int)
{ {
const_iterator old = *this; const_iterator old(*this);
++value_; ++value_;
return old; return old;
} }
@ -125,6 +137,14 @@ inline Foam::labelRange::const_iterator Foam::labelRange::cbegin() const
} }
inline Foam::labelRange::const_iterator
Foam::labelRange::at(const label localIndex) const
{
// The constructor handles out-of-range properly
return const_iterator(this, localIndex);
}
inline const Foam::labelRange::const_iterator Foam::labelRange::end() const inline const Foam::labelRange::const_iterator Foam::labelRange::end() const
{ {
return const_iterator(this, -1); return const_iterator(this, -1);
@ -139,93 +159,94 @@ inline const Foam::labelRange::const_iterator Foam::labelRange::cend() const
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::labelRange Foam::labelRange::identity(const label len) inline Foam::labelRange Foam::labelRange::identity(const label len) noexcept
{ {
return labelRange(0, len); return labelRange(0, len);
} }
inline void Foam::labelRange::setStart(const label i) inline void Foam::labelRange::setStart(const label i) noexcept
{ {
start_ = i; start_ = i;
} }
inline void Foam::labelRange::setSize(const label n) inline void Foam::labelRange::resize(const label n) noexcept
{ {
size_ = n; size_ = n;
if (size_ < 0) size_ = 0; if (size_ < 0) size_ = 0; // No negative sizes
} }
inline void Foam::labelRange::resize(const label n) inline void Foam::labelRange::setSize(const label n) noexcept
{ {
setSize(n); size_ = n;
if (size_ < 0) size_ = 0; // No negative sizes
} }
inline void Foam::labelRange::decrement() inline void Foam::labelRange::decrement() noexcept
{ {
--size_; --size_;
if (size_ < 0) size_ = 0; if (size_ < 0) size_ = 0; // No negative sizes
} }
inline void Foam::labelRange::increment() inline void Foam::labelRange::increment() noexcept
{ {
++size_; ++size_;
} }
inline void Foam::labelRange::clear() inline void Foam::labelRange::clear() noexcept
{ {
start_ = size_ = 0; start_ = size_ = 0;
} }
inline bool Foam::labelRange::empty() const inline bool Foam::labelRange::empty() const noexcept
{ {
return !size_; return !size_;
} }
inline bool Foam::labelRange::valid() const inline bool Foam::labelRange::valid() const noexcept
{ {
return size_; return size_;
} }
inline Foam::label Foam::labelRange::size() const inline Foam::label Foam::labelRange::size() const noexcept
{ {
return size_; return size_;
} }
inline Foam::label Foam::labelRange::start() const inline Foam::label Foam::labelRange::start() const noexcept
{ {
return start_; return start_;
} }
inline Foam::label Foam::labelRange::first() const inline Foam::label Foam::labelRange::first() const noexcept
{ {
return start_; return start_;
} }
inline Foam::label Foam::labelRange::last() const inline Foam::label Foam::labelRange::last() const noexcept
{ {
return start_ + size_ - 1; return start_ + size_ - 1;
} }
inline Foam::label Foam::labelRange::before() const inline Foam::label Foam::labelRange::before() const noexcept
{ {
return start_ - 1; return start_ - 1;
} }
inline Foam::label Foam::labelRange::after() const inline Foam::label Foam::labelRange::after() const noexcept
{ {
return start_ + size_; return start_ + size_;
} }
@ -234,29 +255,45 @@ inline Foam::label Foam::labelRange::after() const
inline bool Foam::labelRange::reset inline bool Foam::labelRange::reset
( (
const label start, const label start,
const label size, const label size
const bool adjustStart ) noexcept
)
{ {
start_ = start; start_ = start;
size_ = size; size_ = size;
if (adjustStart) if (size_ < 0)
{ {
// Disallow invalid indices and sizes size_ = 0; // No negative sizes
adjust();
}
else if (size_ < 0)
{
// Disallow invalid sizes
size_ = 0;
} }
return size_; return size_;
} }
inline bool Foam::labelRange::found(const label value) const inline bool Foam::labelRange::reset
(
const label start,
const label size,
const bool adjustStart
) noexcept
{
start_ = start;
size_ = size;
if (adjustStart)
{
adjust(); // Eliminate negative start, adjust size accordingly
}
else if (size_ < 0)
{
size_ = 0; // No negative sizes
}
return size_;
}
inline bool Foam::labelRange::found(const label value) const noexcept
{ {
return (value >= this->first() && value <= this->last()); return (value >= this->first() && value <= this->last());
} }
@ -264,41 +301,43 @@ inline bool Foam::labelRange::found(const label value) const
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline Foam::label Foam::labelRange::operator[](const label localIndex) const inline Foam::label Foam::labelRange::operator[]
(
const label localIndex
) const noexcept
{ {
return start_ + localIndex; return start_ + localIndex;
} }
inline Foam::labelRange::const_iterator inline bool Foam::labelRange::operator()(const label value) const noexcept
Foam::labelRange::operator()(const label localIndex) const
{ {
return const_iterator(this, localIndex); return found(value);
} }
inline Foam::label Foam::labelRange::operator++() inline Foam::label Foam::labelRange::operator++() noexcept
{ {
return ++size_; return ++size_;
} }
inline Foam::label Foam::labelRange::operator++(int) inline Foam::label Foam::labelRange::operator++(int) noexcept
{ {
return size_++; return size_++;
} }
inline Foam::label Foam::labelRange::operator--() inline Foam::label Foam::labelRange::operator--() noexcept
{ {
decrement(); decrement();
return size_; return size_;
} }
inline Foam::label Foam::labelRange::operator--(int) inline Foam::label Foam::labelRange::operator--(int) noexcept
{ {
const label old = size_; const label old(size_);
decrement(); decrement();
return old; return old;
} }

View File

@ -31,7 +31,7 @@ License
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(surfZone, 0); defineTypeNameAndDebug(surfZone, 0);
} }

View File

@ -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) 2018 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -41,6 +41,7 @@ SourceFiles
#include "label.H" #include "label.H"
#include "className.H" #include "className.H"
#include "surfZoneIdentifier.H" #include "surfZoneIdentifier.H"
#include "labelRange.H"
#include "autoPtr.H" #include "autoPtr.H"
#include "dictionary.H" #include "dictionary.H"
@ -49,8 +50,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of friend functions and operators // Forward declarations
class surfZone; class surfZone;
Istream& operator>>(Istream&, surfZone&); Istream& operator>>(Istream&, surfZone&);
@ -153,6 +153,12 @@ public:
return size_; return size_;
} }
//- Return start/size range of this zone
labelRange range() const
{
return labelRange(start_, size_);
}
//- Write //- Write
void write(Ostream&) const; void write(Ostream&) const;
@ -175,6 +181,19 @@ public:
}; };
// Global Functions
//- Get the labelRange for a surfZone
template<>
struct toLabelRange<surfZone>
{
labelRange operator()(const surfZone& zone) const
{
return zone.range();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam