Commit a0148ac0 authored by Mark Olesen's avatar Mark Olesen
Browse files

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.
parent d029f4c5
......@@ -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());
}
......
......@@ -624,24 +624,24 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const dimensioned<Type>& dt)
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
template<class Type>
bool Foam::operator>
bool Foam::operator<
(
const dimensioned<Type>& dt1,
const dimensioned<Type>& dt2
)
{
return dt1.value() > dt2.value();
return dt1.value() < dt2.value();
}
template<class Type>
bool Foam::operator<
bool Foam::operator>
(
const dimensioned<Type>& dt1,
const dimensioned<Type>& dt2
)
{
return dt1.value() < dt2.value();
return dt2.value() < dt1.value();
}
......
......@@ -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>&);
......
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