Commit 83669e28 authored by Mark Olesen's avatar Mark Olesen
Browse files

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()
      );
parent 0e7b1351
......@@ -42,6 +42,7 @@ See also
#include "vector.H"
#include "labelRange.H"
#include "scalarList.H"
#include "ListOps.H"
#include "SubList.H"
......@@ -144,6 +145,18 @@ int main(int argc, char *argv[])
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<< "normal: " << longLabelList << nl;
......@@ -220,7 +233,32 @@ int main(int argc, char *argv[])
}
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;
......
......@@ -58,7 +58,7 @@ int main(int argc, char *argv[])
Info<<"test sorting" << endl;
DynamicList<labelRange> list1(10);
list1.append(labelRange(25, 8));
list1.append(labelRange(0, 10));
list1.append(labelRange::identity(8));
list1.append(labelRange(15, 5));
list1.append(labelRange(50, -10));
......
......@@ -34,6 +34,8 @@ namespace Foam
int labelRange::debug(debug::debugSwitch("labelRange", 0));
}
const Foam::labelRange Foam::labelRange::null;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
......
......@@ -35,6 +35,7 @@ SourceFiles
#define labelRange_H
#include "label.H"
#include <iterator>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -63,26 +64,32 @@ class labelRange
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
//- Type of values the range contains
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
typedef label size_type;
// Forward declaration
class const_iterator;
// Constructors
//- An empty range with zero for start/size.
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.
inline labelRange
(
......@@ -95,6 +102,12 @@ public:
labelRange(Istream& is);
// Static Member Functions
//- An identity range with range[i] == i.
inline static labelRange identity(const label len);
// Member Functions
//- Adjust start position
......@@ -184,6 +197,9 @@ public:
//- Return element in the range, no bounds checking
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.
inline label operator++();
inline label operator++(int);
......@@ -197,21 +213,30 @@ public:
//- Forward iterator with const access
class const_iterator
:
public std::iterator
<
std::input_iterator_tag,
label,
label,
const label*,
const label&
>
{
//- The current label (not the local index)
label index_;
//- The current (global) value
label value_;
public:
// Constructors
//- Construct from range at given local index.
// A negative index signals the 'end' position
inline const_iterator(const labelRange* range, const label i = 0);
// A negative index is invalid and corresponds to the 'end'
inline const_iterator(const labelRange* range, const label i=0);
// Member operators
//- Return the current label
//- Return the current (global) value
inline label operator*() const;
inline const_iterator& operator++();
......
......@@ -64,7 +64,7 @@ inline Foam::labelRange::const_iterator::const_iterator
const label i
)
:
index_
value_
(
range->start()
+ ((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
{
return index_;
return value_;
}
inline Foam::labelRange::const_iterator&
Foam::labelRange::const_iterator::operator++()
{
++index_;
++value_;
return *this;
}
......@@ -90,7 +90,7 @@ inline Foam::labelRange::const_iterator
Foam::labelRange::const_iterator::operator++(int)
{
const_iterator old = *this;
++index_;
++value_;
return old;
}
......@@ -100,7 +100,7 @@ inline bool Foam::labelRange::const_iterator::operator==
const const_iterator& iter
) 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
{
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 * * * * * * * * * * * * * //
inline Foam::labelRange Foam::labelRange::identity(const label len)
{
return labelRange(0, len);
}
inline void Foam::labelRange::setStart(const label 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++()
{
return ++size_;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment