ENH: provide iterators for IndirectList, UIndirectList

- consistency with other containers.
  Allows range-for, enables various std algorithms, and can be used
  with ListOp::create() with an iterator range.
This commit is contained in:
Mark Olesen
2018-03-07 17:50:34 +01:00
parent 77338c8bd0
commit 23b6ea4b85
7 changed files with 230 additions and 99 deletions

View File

@ -41,6 +41,13 @@ void printInfo(const ListType& lst)
<< "addr: " << flatOutput(lst.addressing()) << nl << "addr: " << flatOutput(lst.addressing()) << nl
<< "list: " << flatOutput(lst) << nl << "list: " << flatOutput(lst) << nl
<< endl; << endl;
Info<<"for-range :";
for (const auto& val : lst)
{
Info<< " " << val;
}
Info<< nl;
} }

View File

@ -61,10 +61,10 @@ class IndirectListAddressing
// Private Member Functions // Private Member Functions
//- Disallow default bitwise copy construct //- Disallow copy construct
IndirectListAddressing(const IndirectListAddressing&) = delete; IndirectListAddressing(const IndirectListAddressing&) = delete;
//- Disallow default bitwise assignment //- Disallow copy assignment
void operator=(const IndirectListAddressing&) = delete; void operator=(const IndirectListAddressing&) = delete;
@ -72,10 +72,10 @@ protected:
// Constructors // Constructors
//- Construct by copying the addressing array //- Copy construct from addressing array
explicit inline IndirectListAddressing(const labelUList& addr); explicit inline IndirectListAddressing(const labelUList& addr);
//- Construct by transferring addressing array //- Move construct from addressing array
explicit inline IndirectListAddressing(List<label>&& addr); explicit inline IndirectListAddressing(List<label>&& addr);
@ -105,10 +105,10 @@ class IndirectList
{ {
// Private Member Functions // Private Member Functions
//- Disallow default assignment operator //- Disallow copy construct
void operator=(const IndirectList<T>&) = delete; void operator=(const IndirectList<T>&) = delete;
//- Disallow assignment from UIndirectList //- Disallow copy assignment
void operator=(const UIndirectList<T>&) = delete; void operator=(const UIndirectList<T>&) = delete;
@ -116,25 +116,18 @@ public:
// Constructors // Constructors
//- Construct given the complete list and the addressing array //- Copy construct addressing, shallow copy values list reference.
inline IndirectList inline IndirectList(const UList<T>& values, const labelUList& addr);
(
const UList<T>& completeList,
const labelUList& addr
);
//- Construct given the complete list and by transferring addressing //- Move construct addressing, shallow copy values list reference.
inline IndirectList inline IndirectList(const UList<T>& values, List<label>&& addr);
(
const UList<T>& completeList,
List<label>&& addr
);
//- Copy constructor //- Copy construct addressing, shallow copy values list reference.
inline IndirectList(const IndirectList<T>& lst); inline IndirectList(const IndirectList<T>& list);
//- Construct from UIndirectList //- Copy construct addressing, shallow copy values list reference
explicit inline IndirectList(const UIndirectList<T>& lst); //- from UIndirectList
explicit inline IndirectList(const UIndirectList<T>& list);
// Member Functions // Member Functions
@ -142,7 +135,7 @@ public:
//- Return the list addressing //- Return the list addressing
using UIndirectList<T>::addressing; using UIndirectList<T>::addressing;
//- Reset addressing //- Reset the list addressing
using IndirectListAddressing::resetAddressing; using IndirectListAddressing::resetAddressing;

View File

@ -46,14 +46,14 @@ inline Foam::IndirectListAddressing::IndirectListAddressing
template<class T> template<class T>
inline Foam::IndirectList<T>::IndirectList inline Foam::IndirectList<T>::IndirectList
( (
const UList<T>& completeList, const UList<T>& values,
const labelUList& addr const labelUList& addr
) )
: :
IndirectListAddressing(addr), IndirectListAddressing(addr),
UIndirectList<T> UIndirectList<T>
( (
completeList, values,
IndirectListAddressing::addressing() IndirectListAddressing::addressing()
) )
{} {}
@ -62,14 +62,14 @@ inline Foam::IndirectList<T>::IndirectList
template<class T> template<class T>
inline Foam::IndirectList<T>::IndirectList inline Foam::IndirectList<T>::IndirectList
( (
const UList<T>& completeList, const UList<T>& values,
List<label>&& addr List<label>&& addr
) )
: :
IndirectListAddressing(std::move(addr)), IndirectListAddressing(std::move(addr)),
UIndirectList<T> UIndirectList<T>
( (
completeList, values,
IndirectListAddressing::addressing() IndirectListAddressing::addressing()
) )
{} {}
@ -78,13 +78,13 @@ inline Foam::IndirectList<T>::IndirectList
template<class T> template<class T>
inline Foam::IndirectList<T>::IndirectList inline Foam::IndirectList<T>::IndirectList
( (
const IndirectList<T>& lst const IndirectList<T>& list
) )
: :
IndirectListAddressing(lst.addressing()), IndirectListAddressing(list.addressing()), // Copy addressing
UIndirectList<T> UIndirectList<T>
( (
lst.completeList(), list.completeList(),
IndirectListAddressing::addressing() IndirectListAddressing::addressing()
) )
{} {}
@ -93,13 +93,13 @@ inline Foam::IndirectList<T>::IndirectList
template<class T> template<class T>
inline Foam::IndirectList<T>::IndirectList inline Foam::IndirectList<T>::IndirectList
( (
const UIndirectList<T>& lst const UIndirectList<T>& list
) )
: :
IndirectListAddressing(lst.addressing()), IndirectListAddressing(list.addressing()), // Copy addressing
UIndirectList<T> UIndirectList<T>
( (
lst.completeList(), list.completeList(),
IndirectListAddressing::addressing() IndirectListAddressing::addressing()
) )
{} {}

View File

@ -2,7 +2,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) 2017 OpenCFD Ltd. \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -34,14 +34,14 @@ inline Foam::label Foam::UIndirectList<T>::find
{ {
if (start >= 0) if (start >= 0)
{ {
List_CONST_ACCESS(T, completeList_, lst); List_CONST_ACCESS(T, values_, vals);
List_CONST_ACCESS(label, addressing_, addr); List_CONST_ACCESS(label, addressing_, addr);
const label len = addressing_.size(); const label len = addressing_.size();
for (label i = start; i < len; ++i) for (label i = start; i < len; ++i)
{ {
if (lst[addr[i]] == val) if (vals[addr[i]] == val)
{ {
return i; return i;
} }
@ -59,7 +59,7 @@ inline Foam::label Foam::UIndirectList<T>::rfind
const label pos const label pos
) const ) const
{ {
List_CONST_ACCESS(T, completeList_, lst); List_CONST_ACCESS(T, values_, vals);
List_CONST_ACCESS(label, addressing_, addr); List_CONST_ACCESS(label, addressing_, addr);
for for
@ -74,7 +74,7 @@ inline Foam::label Foam::UIndirectList<T>::rfind
--i --i
) )
{ {
if (lst[addr[i]] == val) if (vals[addr[i]] == val)
{ {
return i; return i;
} }

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.
@ -29,7 +29,7 @@ Description
Like IndirectList but does not store addressing. Like IndirectList but does not store addressing.
Note the const_cast of the completeList. This is so we can use it both Note the const_cast of the list values. This is so we can use it both
on const and non-const lists. Alternative would be to have a const_ on const and non-const lists. Alternative would be to have a const_
variant etc. variant etc.
@ -48,7 +48,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of friend functions and operators // Forward declarations
template<class T> class UIndirectList; template<class T> class UIndirectList;
template<class T> Ostream& operator<<(Ostream&, const UIndirectList<T>&); template<class T> Ostream& operator<<(Ostream&, const UIndirectList<T>&);
@ -65,25 +65,50 @@ class UIndirectList
{ {
// Private data // Private data
UList<T>& completeList_; UList<T>& values_;
const labelUList& addressing_; const labelUList& addressing_;
public: public:
// STL type definitions
//- Type of values the list contains.
typedef T value_type;
//- The pointer type for non-const access to value_type items
typedef T* pointer;
//- The pointer type for const access to value_type items
typedef const T* const_pointer;
//- The type used for storing into value_type objects
typedef T& reference;
//- The type used for reading from constant value_type objects.
typedef const T& const_reference;
//- The type to represent the size of a UList
typedef label size_type;
//- The difference between iterator objects
typedef label difference_type;
//- Forward iterator with non-const access
class iterator;
//- Forward iterator with const access
class const_iterator;
// Constructors // Constructors
//- Construct given the complete list and the addressing array //- Copy construct from the values list and the addressing array
inline UIndirectList inline UIndirectList(const UList<T>& values, const labelUList& addr);
(
const UList<T>& completeList,
const labelUList& addr
);
// Member Functions // Member Functions
// Access // Access
//- Return the number of elements in the list //- Return the number of elements in the list
inline label size() const; inline label size() const;
@ -103,14 +128,14 @@ public:
//- Return the last element of the list. //- Return the last element of the list.
inline const T& last() const; inline const T& last() const;
//- Return the complete list //- Return the complete list of values
inline const UList<T>& completeList() const; inline const UList<T>& completeList() const;
//- Return the list addressing //- Return the list addressing
inline const List<label>& addressing() const; inline const List<label>& addressing() const;
// Search // Search
//- Find index of the first occurence of the value. //- Find index of the first occurence of the value.
// When start is specified, any occurences before start are ignored. // When start is specified, any occurences before start are ignored.
@ -139,38 +164,142 @@ public:
//- Return const access to an element //- Return const access to an element
inline const T& operator[](const label i) const; inline const T& operator[](const label i) const;
//- Assignment to UList of addressed elements //- Copy assignment from a list of the addressed elements
inline void operator=(const UList<T>& ae); inline void operator=(const UList<T>& rhs);
//- Assignment to UIndirectList of addressed elements //- Copy assignment from a indirect list of the addressed elements
inline void operator=(const UIndirectList<T>& ae); inline void operator=(const UIndirectList<T>& rhs);
//- Assignment of all entries to the given value //- Assignment of all entries to the given value
inline void operator=(const T& t); inline void operator=(const T& val);
//- An iterator for an indirect list
class iterator
{
typename UList<T>::pointer data_;
labelUList::const_iterator base_;
public:
iterator
(
UList<T>& list,
labelUList::const_iterator baseIter
)
:
data_(list.begin()),
base_(baseIter)
{}
reference operator*() const
{
return data_[*base_];
}
iterator& operator++()
{
++base_;
return *this;
}
bool operator==(iterator& rhs) const
{
return base_ == rhs.base_;
}
bool operator!=(iterator& rhs) const
{
return (base_ != rhs.base_);
}
};
// STL type definitions //- A const iterator for an indirect list
class const_iterator
{
typename UList<T>::const_pointer data_;
labelUList::const_iterator base_;
//- Type of values the list contains. public:
typedef T value_type;
//- The type used for storing into UList::value_type objects. const_iterator
typedef T& reference; (
const UList<T>& list,
labelUList::const_iterator baseIter
)
:
data_(list.begin()),
base_(baseIter)
{}
//- The type used for reading from constant UList::value_type objects const_reference operator*() const
typedef const T& const_reference; {
return data_[*base_];
}
//- The type that can represent the difference between any two const_iterator& operator++()
//- UList iterator objects. {
typedef label difference_type; ++base_;
return *this;
}
//- The type that can represent the size of a UList. bool operator==(const_iterator& rhs) const
typedef label size_type; {
return base_ == rhs.base_;
}
bool operator!=(const_iterator& rhs) const
{
return base_ != rhs.base_;
}
};
// iterator (non-const)
//- Return an iterator at begin of list
inline iterator begin()
{
return iterator(values_, addressing_.cbegin());
}
//- Return an iterator at end of list
inline iterator end()
{
return iterator(values_, addressing_.cend());
}
// iterator (const)
//- Return a const_iterator at begin of list
inline const_iterator cbegin() const
{
return const_iterator(values_, addressing_.cbegin());
}
//- Return a const_iterator at end of list
inline const_iterator cend() const
{
return const_iterator(values_, addressing_.cend());
}
//- Return a const_iterator at end of list
inline const_iterator begin() const
{
return cbegin();
}
//- Return a const_iterator at end of list
inline const_iterator end() const
{
return cend();
}
// Writing // Writing
//- Write the List, with line-breaks in ASCII if the list length //- Write the list, with line-breaks in ASCII if its length
//- exceeds shortListLen. //- exceeds shortListLen.
// Using '0' suppresses line-breaks entirely. // Using '0' suppresses line-breaks entirely.
Ostream& writeList(Ostream& os, const label shortListLen=0) const; Ostream& writeList(Ostream& os, const label shortListLen=0) const;
@ -178,11 +307,11 @@ public:
// Ostream operator // Ostream operator
//- Write List to Ostream, as per writeList() with shortListLen=10 //- Write list to Ostream, as per writeList() with shortListLen=10
friend Ostream& operator<< <T> friend Ostream& operator<< <T>
( (
Ostream& os, Ostream& os,
const UIndirectList<T>& lst const UIndirectList<T>& 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-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 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.
@ -28,11 +28,11 @@ License
template<class T> template<class T>
inline Foam::UIndirectList<T>::UIndirectList inline Foam::UIndirectList<T>::UIndirectList
( (
const UList<T>& completeList, const UList<T>& values,
const labelUList& addr const labelUList& addr
) )
: :
completeList_(const_cast<UList<T>&>(completeList)), values_(const_cast<UList<T>&>(values)),
addressing_(addr) addressing_(addr)
{} {}
@ -56,35 +56,35 @@ inline bool Foam::UIndirectList<T>::empty() const
template<class T> template<class T>
inline T& Foam::UIndirectList<T>::first() inline T& Foam::UIndirectList<T>::first()
{ {
return completeList_[addressing_.first()]; return values_[addressing_.first()];
} }
template<class T> template<class T>
inline const T& Foam::UIndirectList<T>::first() const inline const T& Foam::UIndirectList<T>::first() const
{ {
return completeList_[addressing_.first()]; return values_[addressing_.first()];
} }
template<class T> template<class T>
inline T& Foam::UIndirectList<T>::last() inline T& Foam::UIndirectList<T>::last()
{ {
return completeList_[addressing_.last()]; return values_[addressing_.last()];
} }
template<class T> template<class T>
inline const T& Foam::UIndirectList<T>::last() const inline const T& Foam::UIndirectList<T>::last() const
{ {
return completeList_[addressing_.last()]; return values_[addressing_.last()];
} }
template<class T> template<class T>
inline const Foam::UList<T>& Foam::UIndirectList<T>::completeList() const inline const Foam::UList<T>& Foam::UIndirectList<T>::completeList() const
{ {
return completeList_; return values_;
} }
@ -125,61 +125,63 @@ inline Foam::List<T> Foam::UIndirectList<T>::operator()() const
template<class T> template<class T>
inline T& Foam::UIndirectList<T>::operator[](const label i) inline T& Foam::UIndirectList<T>::operator[](const label i)
{ {
return completeList_[addressing_[i]]; return values_[addressing_[i]];
} }
template<class T> template<class T>
inline const T& Foam::UIndirectList<T>::operator[](const label i) const inline const T& Foam::UIndirectList<T>::operator[](const label i) const
{ {
return completeList_[addressing_[i]]; return values_[addressing_[i]];
} }
template<class T> template<class T>
inline void Foam::UIndirectList<T>::operator=(const UList<T>& ae) inline void Foam::UIndirectList<T>::operator=(const UList<T>& rhs)
{ {
if (addressing_.size() != ae.size()) const label len = addressing_.size();
if (len != rhs.size())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Addressing and list of addressed elements " << "Addressing and list of addressed elements "
"have different sizes: " "have different sizes: " << len << " " << rhs.size()
<< addressing_.size() << " " << ae.size()
<< abort(FatalError); << abort(FatalError);
} }
forAll(addressing_, i) for (label i = 0; i < len; ++i)
{ {
completeList_[addressing_[i]] = ae[i]; values_[addressing_[i]] = rhs[i];
} }
} }
template<class T> template<class T>
inline void Foam::UIndirectList<T>::operator=(const UIndirectList<T>& ae) inline void Foam::UIndirectList<T>::operator=(const UIndirectList<T>& rhs)
{ {
if (addressing_.size() != ae.size()) const label len = addressing_.size();
if (len != rhs.size())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Addressing and list of addressed elements " << "Addressing and list of addressed elements "
"have different sizes: " "have different sizes: " << len << " " << rhs.size()
<< addressing_.size() << " " << ae.size()
<< abort(FatalError); << abort(FatalError);
} }
forAll(addressing_, i) for (label i = 0; i < len; ++i)
{ {
completeList_[addressing_[i]] = ae[i]; values_[addressing_[i]] = rhs[i];
} }
} }
template<class T> template<class T>
inline void Foam::UIndirectList<T>::operator=(const T& t) inline void Foam::UIndirectList<T>::operator=(const T& val)
{ {
forAll(addressing_, i) for (const label idx : addressing_)
{ {
completeList_[addressing_[i]] = t; values_[idx] = val;
} }
} }

View File

@ -140,10 +140,10 @@ template<class T>
Foam::Ostream& Foam::operator<< Foam::Ostream& Foam::operator<<
( (
Foam::Ostream& os, Foam::Ostream& os,
const Foam::UIndirectList<T>& lst const Foam::UIndirectList<T>& list
) )
{ {
return lst.writeList(os, 10); return list.writeList(os, 10);
} }