mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: replace reverse iterators for UList
- use std::reverse_iterator adaptors, avoid the array-bounds warning - use pointer arithmetic instead of dereferencing the internal array - adjust logic to use 'operator<' instead of 'operator>' in sorting. This creates less work when making other classes sortable.
This commit is contained in:
@ -418,11 +418,7 @@ inline void Foam::DynamicList<T, SizeMin>::swap
|
||||
const label oldSize2 = lst.expandStorage();
|
||||
|
||||
// Swap storage
|
||||
Foam::Swap
|
||||
(
|
||||
static_cast<UList<T>&>(cur),
|
||||
static_cast<UList<T>&>(lst)
|
||||
);
|
||||
UList<T>::swap(lst);
|
||||
|
||||
// Match capacity to the underlying allocated list size
|
||||
cur.setCapacity(cur.size());
|
||||
|
||||
@ -122,31 +122,32 @@ void Foam::UList<T>::swapLast(const label i)
|
||||
|
||||
|
||||
template<class T>
|
||||
void Foam::UList<T>::deepCopy(const UList<T>& a)
|
||||
void Foam::UList<T>::deepCopy(const UList<T>& list)
|
||||
{
|
||||
if (a.size_ != this->size_)
|
||||
const label len = this->size_;
|
||||
|
||||
if (len != list.size_)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "ULists have different sizes: "
|
||||
<< this->size_ << " " << a.size_
|
||||
<< len << " " << list.size_
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (this->size_)
|
||||
else if (len)
|
||||
{
|
||||
#ifdef USEMEMCPY
|
||||
if (contiguous<T>())
|
||||
{
|
||||
memcpy(this->v_, a.v_, this->byteSize());
|
||||
memcpy(this->v_, list.v_, this->byteSize());
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
List_ACCESS(T, (*this), vp);
|
||||
List_CONST_ACCESS(T, a, ap);
|
||||
List_FOR_ALL((*this), i)
|
||||
List_ACCESS(T, (*this), lhs);
|
||||
List_CONST_ACCESS(T, list, rhs);
|
||||
for (label i = 0; i < len; ++i)
|
||||
{
|
||||
vp[i] = ap[i];
|
||||
lhs[i] = rhs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -228,8 +229,7 @@ std::streamsize Foam::UList<T>::byteSize() const
|
||||
if (!contiguous<T>())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Cannot return the binary size of a list of "
|
||||
"non-primitive elements"
|
||||
<< "Cannot return binary size of a list with non-primitive elements"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
@ -317,20 +317,22 @@ void Foam::shuffle(UList<T>& a)
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
bool Foam::UList<T>::operator==(const UList<T>& a) const
|
||||
bool Foam::UList<T>::operator==(const UList<T>& list) const
|
||||
{
|
||||
bool equal = (this->size_ == a.size_);
|
||||
if (!equal)
|
||||
const label len = this->size_;
|
||||
if (len != list.size_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
List_CONST_ACCESS(T, (*this), vp);
|
||||
List_CONST_ACCESS(T, (a), ap);
|
||||
bool equal = false;
|
||||
|
||||
List_FOR_ALL((*this), i)
|
||||
List_CONST_ACCESS(T, (*this), lhs);
|
||||
List_CONST_ACCESS(T, (list), rhs);
|
||||
|
||||
for (label i = 0; i < len; ++i)
|
||||
{
|
||||
equal = (vp[i] == ap[i]);
|
||||
equal = (lhs[i] == rhs[i]);
|
||||
if (!equal) break;
|
||||
}
|
||||
|
||||
@ -339,55 +341,55 @@ bool Foam::UList<T>::operator==(const UList<T>& a) const
|
||||
|
||||
|
||||
template<class T>
|
||||
bool Foam::UList<T>::operator!=(const UList<T>& a) const
|
||||
bool Foam::UList<T>::operator!=(const UList<T>& list) const
|
||||
{
|
||||
return !operator==(a);
|
||||
return !operator==(list);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool Foam::UList<T>::operator<(const UList<T>& a) const
|
||||
bool Foam::UList<T>::operator<(const UList<T>& list) const
|
||||
{
|
||||
for
|
||||
(
|
||||
const_iterator vi = begin(), ai = a.begin();
|
||||
vi < end() && ai < a.end();
|
||||
++vi, ++ai
|
||||
const_iterator lhs = begin(), rhs = list.begin();
|
||||
lhs < end() && rhs < list.end();
|
||||
++lhs, ++rhs
|
||||
)
|
||||
{
|
||||
if (*vi < *ai)
|
||||
if (*lhs < *rhs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (*vi > *ai)
|
||||
else if (*rhs < *lhs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Contents look to be identical, or lists have different sizes
|
||||
return (this->size_ < a.size_);
|
||||
return (this->size_ < list.size_);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool Foam::UList<T>::operator>(const UList<T>& a) const
|
||||
bool Foam::UList<T>::operator>(const UList<T>& list) const
|
||||
{
|
||||
return a.operator<(*this);
|
||||
return list.operator<(*this);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool Foam::UList<T>::operator<=(const UList<T>& a) const
|
||||
bool Foam::UList<T>::operator<=(const UList<T>& list) const
|
||||
{
|
||||
return !operator>(a);
|
||||
return !list.operator<(*this);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool Foam::UList<T>::operator>=(const UList<T>& a) const
|
||||
bool Foam::UList<T>::operator>=(const UList<T>& list) const
|
||||
{
|
||||
return !operator<(a);
|
||||
return !operator<(list);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -51,6 +51,8 @@ SourceFiles
|
||||
#include "Swap.H"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -61,8 +63,6 @@ namespace Foam
|
||||
class labelRange;
|
||||
template<class T> class List;
|
||||
template<class T> class SubList;
|
||||
|
||||
// Forward declaration of friend functions and operators
|
||||
template<class T> class UList;
|
||||
template<class T> Ostream& operator<<(Ostream&, const UList<T>&);
|
||||
template<class T> Istream& operator>>(Istream&, UList<T>&);
|
||||
@ -97,7 +97,7 @@ class UList
|
||||
// for the default assignment to be either. The solution is to
|
||||
// disallow default assignment and provide separate 'shallowCopy' and
|
||||
// 'deepCopy' member functions
|
||||
void operator=(const UList<T>&) = delete;
|
||||
UList<T>& operator=(const UList<T>&) = delete;
|
||||
|
||||
|
||||
protected:
|
||||
@ -124,6 +124,42 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
// STL type definitions
|
||||
|
||||
//- The value type 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;
|
||||
|
||||
//- Random access iterator for traversing a UList
|
||||
typedef T* iterator;
|
||||
|
||||
//- Random access iterator for traversing a UList
|
||||
typedef const T* const_iterator;
|
||||
|
||||
//- The type to represent the size of a UList
|
||||
typedef label size_type;
|
||||
|
||||
//- The difference between iterator objects
|
||||
typedef label difference_type;
|
||||
|
||||
//- Reverse iterator (non-const access)
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
|
||||
//- Reverse iterator (const access)
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
|
||||
// Related types
|
||||
|
||||
//- Declare friendship with the List class
|
||||
@ -135,7 +171,7 @@ public:
|
||||
|
||||
// Static Member Functions
|
||||
|
||||
//- Return a null UList
|
||||
//- Return a UList reference to a nullObject
|
||||
inline static const UList<T>& null();
|
||||
|
||||
|
||||
@ -169,7 +205,7 @@ public:
|
||||
|
||||
bool operator()(const label a, const label b) const
|
||||
{
|
||||
return values[a] > values[b];
|
||||
return values[b] < values[a];
|
||||
}
|
||||
};
|
||||
|
||||
@ -288,10 +324,10 @@ public:
|
||||
// Copy
|
||||
|
||||
//- Copy the pointer held by the given UList
|
||||
inline void shallowCopy(const UList<T>& a);
|
||||
inline void shallowCopy(const UList<T>& list);
|
||||
|
||||
//- Copy elements of the given UList
|
||||
void deepCopy(const UList<T>& a);
|
||||
void deepCopy(const UList<T>& list);
|
||||
|
||||
|
||||
// Member operators
|
||||
@ -337,29 +373,7 @@ public:
|
||||
void operator=(const zero);
|
||||
|
||||
|
||||
// STL type definitions
|
||||
|
||||
//- Type of values the UList contains
|
||||
typedef T value_type;
|
||||
|
||||
//- 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 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;
|
||||
|
||||
|
||||
// STL iterator
|
||||
|
||||
//- Random access iterator for traversing UList
|
||||
typedef T* iterator;
|
||||
// Random access iterator (non-const)
|
||||
|
||||
//- Return an iterator to begin traversing the UList
|
||||
inline iterator begin();
|
||||
@ -368,10 +382,7 @@ public:
|
||||
inline iterator end();
|
||||
|
||||
|
||||
// STL const_iterator
|
||||
|
||||
//- Random access iterator for traversing UList
|
||||
typedef const T* const_iterator;
|
||||
// Random access iterator (const)
|
||||
|
||||
//- Return const_iterator to begin traversing the constant UList
|
||||
inline const_iterator cbegin() const;
|
||||
@ -385,94 +396,8 @@ public:
|
||||
//- Return const_iterator to end traversing the constant UList
|
||||
inline const_iterator end() const;
|
||||
|
||||
// Reverse iterators
|
||||
|
||||
//- Generic const/non-const reverse iterator
|
||||
template<bool Const>
|
||||
class reverse_iterator_base
|
||||
{
|
||||
public:
|
||||
//- The const/non-const type for entries
|
||||
typedef typename std::conditional
|
||||
<Const, const T, T>::type value_type;
|
||||
|
||||
//- A pointer to a const/non-const entry
|
||||
typedef value_type* pointer;
|
||||
|
||||
//- A reference to a const/non-const entry
|
||||
typedef value_type& reference;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
//- The element pointer
|
||||
pointer ptr_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Construct null or from list element pointer
|
||||
inline reverse_iterator_base(pointer ptr = nullptr)
|
||||
:
|
||||
ptr_(ptr)
|
||||
{}
|
||||
|
||||
|
||||
//- Copy construct
|
||||
inline reverse_iterator_base(const reverse_iterator_base& iter)
|
||||
:
|
||||
ptr_(iter.ptr_)
|
||||
{}
|
||||
|
||||
|
||||
//- Reverse increment
|
||||
inline void operator++()
|
||||
{
|
||||
--ptr_;
|
||||
}
|
||||
|
||||
//- Reverse increment
|
||||
inline reverse_iterator_base operator++(int)
|
||||
{
|
||||
reverse_iterator_base old(*this);
|
||||
--ptr_;
|
||||
return old;
|
||||
}
|
||||
|
||||
//- Reverse increase
|
||||
inline void operator+=(int n)
|
||||
{
|
||||
ptr_ -= n;
|
||||
}
|
||||
|
||||
//- Dereference iterator
|
||||
reference operator*() const
|
||||
{
|
||||
return *ptr_;
|
||||
}
|
||||
|
||||
//- Dereference iterator
|
||||
pointer operator->() const
|
||||
{
|
||||
return ptr_;
|
||||
}
|
||||
|
||||
//- Equality
|
||||
bool operator==(const reverse_iterator_base& iter) const
|
||||
{
|
||||
return ptr_ == iter.ptr_;
|
||||
}
|
||||
|
||||
//- inequality
|
||||
bool operator!=(const reverse_iterator_base& iter) const
|
||||
{
|
||||
return ptr_ != iter.ptr_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//- STL reverse_iterator
|
||||
typedef reverse_iterator_base<false> reverse_iterator;
|
||||
// Reverse iterators (non-const)
|
||||
|
||||
//- Return reverse_iterator to begin reverse traversing the UList
|
||||
inline reverse_iterator rbegin();
|
||||
@ -481,8 +406,7 @@ public:
|
||||
inline reverse_iterator rend();
|
||||
|
||||
|
||||
//- STL const reverse iterator
|
||||
typedef reverse_iterator_base<true> const_reverse_iterator;
|
||||
// Reverse iterators (const)
|
||||
|
||||
//- Return const_reverse_iterator to begin reverse traversing the UList
|
||||
inline const_reverse_iterator crbegin() const;
|
||||
@ -523,7 +447,7 @@ public:
|
||||
bool operator!=(const UList<T>& a) const;
|
||||
|
||||
//- Compare two ULists lexicographically. Takes linear time
|
||||
bool operator<(const UList<T>& a) const;
|
||||
bool operator<(const UList<T>& list) const;
|
||||
|
||||
//- Compare two ULists lexicographically. Takes linear time
|
||||
bool operator>(const UList<T>& a) const;
|
||||
|
||||
@ -188,10 +188,10 @@ inline bool Foam::UList<T>::found(const T& val, const label start) const
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::UList<T>::shallowCopy(const UList<T>& a)
|
||||
inline void Foam::UList<T>::shallowCopy(const UList<T>& list)
|
||||
{
|
||||
size_ = a.size_;
|
||||
v_ = a.v_;
|
||||
size_ = list.size_;
|
||||
v_ = list.v_;
|
||||
}
|
||||
|
||||
|
||||
@ -217,10 +217,8 @@ namespace Foam
|
||||
{
|
||||
return v_[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
return Foam::pTraits<bool>::zero;
|
||||
}
|
||||
|
||||
return Foam::pTraits<bool>::zero;
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,63 +266,63 @@ template<class T>
|
||||
inline typename Foam::UList<T>::iterator
|
||||
Foam::UList<T>::end()
|
||||
{
|
||||
return &v_[size_];
|
||||
return (v_ + size_);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename Foam::UList<T>::const_iterator
|
||||
Foam::UList<T>::end() const
|
||||
{
|
||||
return &v_[size_];
|
||||
return (v_ + size_);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename Foam::UList<T>::const_iterator
|
||||
Foam::UList<T>::cend() const
|
||||
{
|
||||
return &v_[size_];
|
||||
return (v_ + size_);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename Foam::UList<T>::reverse_iterator
|
||||
Foam::UList<T>::rbegin()
|
||||
{
|
||||
return reverse_iterator(&v_[size_-1]);
|
||||
return reverse_iterator(end());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename Foam::UList<T>::const_reverse_iterator
|
||||
Foam::UList<T>::rbegin() const
|
||||
{
|
||||
return const_reverse_iterator(&v_[size_-1]);
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename Foam::UList<T>::const_reverse_iterator
|
||||
Foam::UList<T>::crbegin() const
|
||||
{
|
||||
return const_reverse_iterator(&v_[size_-1]);
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename Foam::UList<T>::reverse_iterator
|
||||
Foam::UList<T>::rend()
|
||||
{
|
||||
return reverse_iterator(&v_[-1]);
|
||||
return reverse_iterator(begin());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename Foam::UList<T>::const_reverse_iterator
|
||||
Foam::UList<T>::rend() const
|
||||
{
|
||||
return const_reverse_iterator(&v_[-1]);
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename Foam::UList<T>::const_reverse_iterator
|
||||
Foam::UList<T>::crend() const
|
||||
{
|
||||
return const_reverse_iterator(&v_[-1]);
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -623,17 +623,6 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const dimensioned<Type>& dt)
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
bool Foam::operator>
|
||||
(
|
||||
const dimensioned<Type>& dt1,
|
||||
const dimensioned<Type>& dt2
|
||||
)
|
||||
{
|
||||
return dt1.value() > dt2.value();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool Foam::operator<
|
||||
(
|
||||
@ -645,6 +634,17 @@ bool Foam::operator<
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool Foam::operator>
|
||||
(
|
||||
const dimensioned<Type>& dt1,
|
||||
const dimensioned<Type>& dt2
|
||||
)
|
||||
{
|
||||
return dt2.value() < dt1.value();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::dimensioned<Type> Foam::operator+
|
||||
(
|
||||
|
||||
@ -274,10 +274,10 @@ template<class Type>
|
||||
dimensioned<Type> min(const dimensioned<Type>&, const dimensioned<Type>&);
|
||||
|
||||
template<class Type>
|
||||
bool operator>(const dimensioned<Type>&, const dimensioned<Type>&);
|
||||
bool operator<(const dimensioned<Type>&, const dimensioned<Type>&);
|
||||
|
||||
template<class Type>
|
||||
bool operator<(const dimensioned<Type>&, const dimensioned<Type>&);
|
||||
bool operator>(const dimensioned<Type>&, const dimensioned<Type>&);
|
||||
|
||||
template<class Type>
|
||||
dimensioned<Type> operator+(const dimensioned<Type>&, const dimensioned<Type>&);
|
||||
|
||||
Reference in New Issue
Block a user