ENH: improvements to labelRange const_iterator

- inherit from std::iterator to obtain the full STL typedefs, meaning
  that std::distance works and the following is now possible:

      labelRange range(100, 1500);
      scalarList list(range.begin(), range.end());

  --
  Note that this does not work (mismatched data-types):

      scalarList list = identity(12345);

  But this does, since the *iter promotes label to scalar:

      labelList ident = identity(12345);
      scalarList list(ident.begin(), ident.end());

  It is however more than slightly wasteful to create a labelList
  just for initializing a scalarList. An alternative could be a
  a labelRange for the same purpose.

      labelRange ident = labelRange::identity(12345);
      scalarList list(ident.begin(), ident.end());

  Or this
      scalarList list
      (
          labelRange::null.begin(),
          labelRange::identity(12345).end()
      );
This commit is contained in:
Mark Olesen
2017-05-14 14:39:17 +02:00
parent 0e7b135181
commit 83669e284f
5 changed files with 96 additions and 18 deletions

View File

@ -42,6 +42,7 @@ See also
#include "vector.H" #include "vector.H"
#include "labelRange.H" #include "labelRange.H"
#include "scalarList.H"
#include "ListOps.H" #include "ListOps.H"
#include "SubList.H" #include "SubList.H"
@ -144,6 +145,18 @@ int main(int argc, char *argv[])
labelList longLabelList = identity(15); labelList longLabelList = identity(15);
// This does not work:
// scalarList slist = identity(15);
//
// More writing, but does work:
scalarList slist
(
labelRange::null.begin(),
labelRange::identity(15).end()
);
Info<<"scalar identity:" << flatOutput(slist) << endl;
Info<< "labels (contiguous=" << contiguous<label>() << ")" << nl; Info<< "labels (contiguous=" << contiguous<label>() << ")" << nl;
Info<< "normal: " << longLabelList << nl; Info<< "normal: " << longLabelList << nl;
@ -220,7 +233,32 @@ int main(int argc, char *argv[])
} }
Info<< "sub-sorted: " << flatOutput(longLabelList) << nl; Info<< "sub-sorted: " << flatOutput(longLabelList) << nl;
// Info<<"Slice=" << longLabelList[labelRange(23,5)] << nl; // construct from a label-range
labelRange range(25,15);
labelList ident(range.begin(), range.end());
Info<<"range-list (label)=" << ident << nl;
List<scalar> sident(range.begin(), range.end());
Info<<"range-list (scalar)=" << sident << nl;
// Sub-ranges also work
List<scalar> sident2(range(3), range(10));
Info<<"range-list (scalar)=" << sident2 << nl;
// VERY BAD IDEA: List<scalar> sident3(range(10), range(3));
// This doesn't work, and don't know what it should do anyhow
// List<vector> vident(range.begin(), range.end());
// Info<<"range-list (vector)=" << vident << nl;
// Even weird things like this
List<scalar> sident4
(
labelRange().begin(),
labelRange::identity(8).end()
);
Info<<"range-list (scalar)=" << sident4 << nl;
} }
wordReList reLst; wordReList reLst;

View File

@ -58,7 +58,7 @@ int main(int argc, char *argv[])
Info<<"test sorting" << endl; Info<<"test sorting" << endl;
DynamicList<labelRange> list1(10); DynamicList<labelRange> list1(10);
list1.append(labelRange(25, 8)); list1.append(labelRange(25, 8));
list1.append(labelRange(0, 10)); list1.append(labelRange::identity(8));
list1.append(labelRange(15, 5)); list1.append(labelRange(15, 5));
list1.append(labelRange(50, -10)); list1.append(labelRange(50, -10));

View File

@ -34,6 +34,8 @@ namespace Foam
int labelRange::debug(debug::debugSwitch("labelRange", 0)); int labelRange::debug(debug::debugSwitch("labelRange", 0));
} }
const Foam::labelRange Foam::labelRange::null;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //

View File

@ -35,6 +35,7 @@ SourceFiles
#define labelRange_H #define labelRange_H
#include "label.H" #include "label.H"
#include <iterator>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -63,26 +64,32 @@ class labelRange
public: public:
static int debug; // Static Data Members
static int debug;
//- An empty range with start=0, size=0.
static const labelRange null;
// STL type definitions similar to what UList has // STL type definitions similar to what UList has
//- Type of values the range contains //- Type of values the range contains
typedef label value_type; typedef label value_type;
//- The type that can represent the difference between two iterators
typedef label difference_type;
//- The type that can represent the size of the range //- The type that can represent the size of the range
typedef label size_type; 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 labelRange();
//- Construct a range from start and 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.
inline labelRange inline labelRange
( (
@ -95,6 +102,12 @@ public:
labelRange(Istream& is); labelRange(Istream& is);
// Static Member Functions
//- An identity range with range[i] == i.
inline static labelRange identity(const label len);
// Member Functions // Member Functions
//- Adjust start position //- Adjust start position
@ -184,6 +197,9 @@ public:
//- Return element in the range, no bounds checking //- Return element in the range, no bounds checking
inline label operator[](const label localIndex) const; inline label operator[](const label localIndex) const;
//- Return const_iterator to element in the range
inline const_iterator operator()(const label localIndex) const;
//- Increase the size by 1. //- Increase the size by 1.
inline label operator++(); inline label operator++();
inline label operator++(int); inline label operator++(int);
@ -197,21 +213,30 @@ public:
//- Forward iterator with const access //- Forward iterator with const access
class const_iterator class const_iterator
:
public std::iterator
<
std::input_iterator_tag,
label,
label,
const label*,
const label&
>
{ {
//- The current label (not the local index) //- The current (global) value
label index_; label value_;
public: public:
// Constructors // Constructors
//- Construct from range at given local index. //- Construct from range at given local index.
// A negative index signals the 'end' position // A negative index is invalid and corresponds to the 'end'
inline const_iterator(const labelRange* range, const label i = 0); inline const_iterator(const labelRange* range, const label i=0);
// Member operators // Member operators
//- Return the current label //- Return the current (global) value
inline label operator*() const; inline label operator*() const;
inline const_iterator& operator++(); inline const_iterator& operator++();

View File

@ -64,7 +64,7 @@ inline Foam::labelRange::const_iterator::const_iterator
const label i const label i
) )
: :
index_ value_
( (
range->start() range->start()
+ ((i < 0 || i > range->size()) ? range->size() : i) + ((i < 0 || i > range->size()) ? range->size() : i)
@ -74,14 +74,14 @@ inline Foam::labelRange::const_iterator::const_iterator
inline Foam::label Foam::labelRange::const_iterator::operator*() const inline Foam::label Foam::labelRange::const_iterator::operator*() const
{ {
return index_; return value_;
} }
inline Foam::labelRange::const_iterator& inline Foam::labelRange::const_iterator&
Foam::labelRange::const_iterator::operator++() Foam::labelRange::const_iterator::operator++()
{ {
++index_; ++value_;
return *this; return *this;
} }
@ -90,7 +90,7 @@ 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;
++index_; ++value_;
return old; return old;
} }
@ -100,7 +100,7 @@ inline bool Foam::labelRange::const_iterator::operator==
const const_iterator& iter const const_iterator& iter
) const ) const
{ {
return (this->index_ == iter.index_); return (this->value_ == iter.value_);
} }
@ -109,7 +109,7 @@ inline bool Foam::labelRange::const_iterator::operator!=
const const_iterator& iter const const_iterator& iter
) const ) const
{ {
return (this->index_ != iter.index_); return (this->value_ != iter.value_);
} }
@ -139,6 +139,12 @@ inline const Foam::labelRange::const_iterator Foam::labelRange::cend() const
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::labelRange Foam::labelRange::identity(const label len)
{
return labelRange(0, len);
}
inline void Foam::labelRange::setStart(const label i) inline void Foam::labelRange::setStart(const label i)
{ {
start_ = i; start_ = i;
@ -264,6 +270,13 @@ inline Foam::label Foam::labelRange::operator[](const label localIndex) const
} }
inline Foam::labelRange::const_iterator
Foam::labelRange::operator()(const label localIndex) const
{
return const_iterator(this, localIndex);
}
inline Foam::label Foam::labelRange::operator++() inline Foam::label Foam::labelRange::operator++()
{ {
return ++size_; return ++size_;