Commit 14bac7fa authored by Mark Olesen's avatar Mark Olesen
Browse files

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.
parent 9b8317b7
......@@ -41,6 +41,13 @@ void printInfo(const ListType& lst)
<< "addr: " << flatOutput(lst.addressing()) << nl
<< "list: " << flatOutput(lst) << nl
<< endl;
Info<<"for-range :";
for (const auto& val : lst)
{
Info<< " " << val;
}
Info<< nl;
}
......
......@@ -61,10 +61,10 @@ class IndirectListAddressing
// Private Member Functions
//- Disallow default bitwise copy construct
//- Disallow copy construct
IndirectListAddressing(const IndirectListAddressing&) = delete;
//- Disallow default bitwise assignment
//- Disallow copy assignment
void operator=(const IndirectListAddressing&) = delete;
......@@ -72,10 +72,10 @@ protected:
// Constructors
//- Construct by copying the addressing array
//- Copy construct from addressing array
explicit inline IndirectListAddressing(const labelUList& addr);
//- Construct by transferring addressing array
//- Move construct from addressing array
explicit inline IndirectListAddressing(List<label>&& addr);
......@@ -105,10 +105,10 @@ class IndirectList
{
// Private Member Functions
//- Disallow default assignment operator
//- Disallow copy construct
void operator=(const IndirectList<T>&) = delete;
//- Disallow assignment from UIndirectList
//- Disallow copy assignment
void operator=(const UIndirectList<T>&) = delete;
......@@ -116,25 +116,18 @@ public:
// Constructors
//- Construct given the complete list and the addressing array
inline IndirectList
(
const UList<T>& completeList,
const labelUList& addr
);
//- Copy construct addressing, shallow copy values list reference.
inline IndirectList(const UList<T>& values, const labelUList& addr);
//- Construct given the complete list and by transferring addressing
inline IndirectList
(
const UList<T>& completeList,
List<label>&& addr
);
//- Move construct addressing, shallow copy values list reference.
inline IndirectList(const UList<T>& values, List<label>&& addr);
//- Copy constructor
inline IndirectList(const IndirectList<T>& lst);
//- Copy construct addressing, shallow copy values list reference.
inline IndirectList(const IndirectList<T>& list);
//- Construct from UIndirectList
explicit inline IndirectList(const UIndirectList<T>& lst);
//- Copy construct addressing, shallow copy values list reference
//- from UIndirectList
explicit inline IndirectList(const UIndirectList<T>& list);
// Member Functions
......@@ -142,7 +135,7 @@ public:
//- Return the list addressing
using UIndirectList<T>::addressing;
//- Reset addressing
//- Reset the list addressing
using IndirectListAddressing::resetAddressing;
......
......@@ -46,14 +46,14 @@ inline Foam::IndirectListAddressing::IndirectListAddressing
template<class T>
inline Foam::IndirectList<T>::IndirectList
(
const UList<T>& completeList,
const UList<T>& values,
const labelUList& addr
)
:
IndirectListAddressing(addr),
UIndirectList<T>
(
completeList,
values,
IndirectListAddressing::addressing()
)
{}
......@@ -62,14 +62,14 @@ inline Foam::IndirectList<T>::IndirectList
template<class T>
inline Foam::IndirectList<T>::IndirectList
(
const UList<T>& completeList,
const UList<T>& values,
List<label>&& addr
)
:
IndirectListAddressing(std::move(addr)),
UIndirectList<T>
(
completeList,
values,
IndirectListAddressing::addressing()
)
{}
......@@ -78,13 +78,13 @@ inline Foam::IndirectList<T>::IndirectList
template<class T>
inline Foam::IndirectList<T>::IndirectList
(
const IndirectList<T>& lst
const IndirectList<T>& list
)
:
IndirectListAddressing(lst.addressing()),
IndirectListAddressing(list.addressing()), // Copy addressing
UIndirectList<T>
(
lst.completeList(),
list.completeList(),
IndirectListAddressing::addressing()
)
{}
......@@ -93,13 +93,13 @@ inline Foam::IndirectList<T>::IndirectList
template<class T>
inline Foam::IndirectList<T>::IndirectList
(
const UIndirectList<T>& lst
const UIndirectList<T>& list
)
:
IndirectListAddressing(lst.addressing()),
IndirectListAddressing(list.addressing()), // Copy addressing
UIndirectList<T>
(
lst.completeList(),
list.completeList(),
IndirectListAddressing::addressing()
)
{}
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -34,14 +34,14 @@ inline Foam::label Foam::UIndirectList<T>::find
{
if (start >= 0)
{
List_CONST_ACCESS(T, completeList_, lst);
List_CONST_ACCESS(T, values_, vals);
List_CONST_ACCESS(label, addressing_, addr);
const label len = addressing_.size();
for (label i = start; i < len; ++i)
{
if (lst[addr[i]] == val)
if (vals[addr[i]] == val)
{
return i;
}
......@@ -59,7 +59,7 @@ inline Foam::label Foam::UIndirectList<T>::rfind
const label pos
) const
{
List_CONST_ACCESS(T, completeList_, lst);
List_CONST_ACCESS(T, values_, vals);
List_CONST_ACCESS(label, addressing_, addr);
for
......@@ -74,7 +74,7 @@ inline Foam::label Foam::UIndirectList<T>::rfind
--i
)
{
if (lst[addr[i]] == val)
if (vals[addr[i]] == val)
{
return i;
}
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -29,7 +29,7 @@ Description
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_
variant etc.
......@@ -48,7 +48,7 @@ SourceFiles
namespace Foam
{
// Forward declaration of friend functions and operators
// Forward declarations
template<class T> class UIndirectList;
template<class T> Ostream& operator<<(Ostream&, const UIndirectList<T>&);
......@@ -65,25 +65,50 @@ class UIndirectList
{
// Private data
UList<T>& completeList_;
UList<T>& values_;
const labelUList& addressing_;
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
//- Construct given the complete list and the addressing array
inline UIndirectList
(
const UList<T>& completeList,
const labelUList& addr
);
//- Copy construct from the values list and the addressing array
inline UIndirectList(const UList<T>& values, const labelUList& addr);
// Member Functions
// Access
// Access
//- Return the number of elements in the list
inline label size() const;
......@@ -103,14 +128,14 @@ public:
//- Return the last element of the list.
inline const T& last() const;
//- Return the complete list
//- Return the complete list of values
inline const UList<T>& completeList() const;
//- Return the list addressing
inline const List<label>& addressing() const;
// Search
// Search
//- Find index of the first occurence of the value.
// When start is specified, any occurences before start are ignored.
......@@ -139,38 +164,142 @@ public:
//- Return const access to an element
inline const T& operator[](const label i) const;
//- Assignment to UList of addressed elements
inline void operator=(const UList<T>& ae);
//- Copy assignment from a list of the addressed elements
inline void operator=(const UList<T>& rhs);
//- Assignment to UIndirectList of addressed elements
inline void operator=(const UIndirectList<T>& ae);
//- Copy assignment from a indirect list of the addressed elements
inline void operator=(const UIndirectList<T>& rhs);
//- Assignment of all entries to the given value
inline void operator=(const T& t);
// STL type definitions
//- Type of values the list contains.
typedef T value_type;
//- The type used for storing into UList::value_type objects.
typedef T& reference;
//- The type used for reading from constant UList::value_type objects
typedef const T& const_reference;
//- The type that can represent the difference between any two
//- UList iterator objects.
typedef label difference_type;
//- The type that can represent the size of a UList.
typedef label size_type;
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_);
}
};
//- A const iterator for an indirect list
class const_iterator
{
typename UList<T>::const_pointer data_;
labelUList::const_iterator base_;
public:
const_iterator
(
const UList<T>& list,
labelUList::const_iterator baseIter
)
:
data_(list.begin()),
base_(baseIter)
{}
const_reference operator*() const
{
return data_[*base_];
}
const_iterator& operator++()
{
++base_;
return *this;
}
bool operator==(const_iterator& rhs) const
{
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
//- 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.
// Using '0' suppresses line-breaks entirely.
Ostream& writeList(Ostream& os, const label shortListLen=0) const;
......@@ -178,11 +307,11 @@ public:
// 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>
(
Ostream& os,
const UIndirectList<T>& lst
const UIndirectList<T>& list
);
};
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -28,11 +28,11 @@ License
template<class T>
inline Foam::UIndirectList<T>::UIndirectList
(
const UList<T>& completeList,
const UList<T>& values,
const labelUList& addr
)
:
completeList_(const_cast<UList<T>&>(completeList)),
values_(const_cast<UList<T>&>(values)),
addressing_(addr)
{}
......@@ -56,35 +56,35 @@ inline bool Foam::UIndirectList<T>::empty() const
template<class T>
inline T& Foam::UIndirectList<T>::first()
{
return completeList_[addressing_.first()];
return values_[addressing_.first()];
}
template<class T>
inline const T& Foam::UIndirectList<T>::first() const
{
return completeList_[addressing_.first()];
return values_[addressing_.first()];
}
template<class T>
inline T& Foam::UIndirectList<T>::last()
{
return completeList_[addressing_.last()];
return values_[addressing_.last()];
}
template<class T>
inline const T& Foam::UIndirectList<T>::last() const
{
return completeList_[addressing_.last()];
return values_[addressing_.last()];
}
template<class T>
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>
inline T& Foam::UIndirectList<T>::operator[](const label i)
{
return completeList_[addressing_[i]];
return values_[addressing_[i]];
}
template<class T>
inline const T& Foam::UIndirectList<T>::operator[](const label i) const
{
return completeList_[addressing_[i]];
return values_[addressing_[i]];
}
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
<< "Addressing and list of addressed elements "
"have different sizes: "
<< addressing_.size() << " " << ae.size()
"have different sizes: " << len << " " << rhs.size()
<< 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>
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
<< "Addressing and list of addressed elements "
"have different sizes: "
<< addressing_