mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improve UPtrList sorting
- adjust nullptr checks to discourage flip-flop when confronted with
multiple null values.
Old: (a && b) ? (*a < *b) : bool(a);
New: (a && b) ? (*a < *b) : !b;
comparing (non-null < null) and (null < non-null) behaves
identically, but comparing (null < null) now tests as true
(ie, already sorted) whereas before it would have been false
(ie, needs a swap)
- add UPtrList trimTrailingNull(), which reduces the effective
(addressable) list size to ignore any trailing null pointers, but
without reallocation. This is particularly useful when creating a
UPtrList list view. For example,
UPtrList<some_iterator> validValues(container.size());
...Loop to add valid entries, by some criteria...
// Shorten list to hide null entries
validValues.trimTrailingNull();
This list view now only needs a single allocation, whereas using
a resize (as was previously necessary) could invoke a second
allocation, as well as recopying.
This commit is contained in:
@ -187,7 +187,7 @@ template<class T, int SizeMin>
|
||||
inline Foam::label Foam::PtrDynList<T, SizeMin>::squeezeNull()
|
||||
{
|
||||
const label newLen = UPtrList<T>::squeezeNull();
|
||||
resize(newLen);
|
||||
PtrList<T>::setAddressableSize(newLen);
|
||||
return newLen;
|
||||
}
|
||||
|
||||
|
||||
@ -65,6 +65,23 @@ Foam::label Foam::UPtrList<T>::squeezeNull()
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Foam::UPtrList<T>::trimTrailingNull()
|
||||
{
|
||||
label newLen = this->size();
|
||||
|
||||
for (label i = newLen-1; i >= 0 && !ptrs_[i]; --i)
|
||||
{
|
||||
--newLen;
|
||||
}
|
||||
|
||||
// Or mutable?
|
||||
// const_cast<Detail::PtrListDetail<T>&>(ptrs_).setAddressableSize(newLen);
|
||||
|
||||
ptrs_.setAddressableSize(newLen);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Foam::UPtrList<T>::reorder(const labelUList& oldToNew, const bool check)
|
||||
{
|
||||
@ -177,6 +194,22 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& list)
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
void Foam::sort(UPtrList<T>& list)
|
||||
{
|
||||
std::stable_sort
|
||||
(
|
||||
list.begin_ptr(),
|
||||
list.end_ptr(),
|
||||
// Compare less, with nullptr protect and sort nullptr to end
|
||||
[](const T* const a, const T* const b) -> bool
|
||||
{
|
||||
return (a && b) ? (*a < *b) : !b;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Compare>
|
||||
void Foam::sort(UPtrList<T>& list, const Compare& comp)
|
||||
{
|
||||
@ -189,12 +222,4 @@ void Foam::sort(UPtrList<T>& list, const Compare& comp)
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Foam::sort(UPtrList<T>& list)
|
||||
{
|
||||
// ie, lessOp<T>() or std::less<T>()
|
||||
Foam::sort(list, [](const T& a, const T& b) { return (a < b); });
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -129,7 +129,7 @@ public:
|
||||
//- Compare dereferenced pointers
|
||||
bool operator()(const T* const a, const T* const b) const
|
||||
{
|
||||
return (a && b) ? comp(*a, *b) : bool(a);
|
||||
return (a && b) ? comp(*a, *b) : !b;
|
||||
}
|
||||
};
|
||||
|
||||
@ -150,7 +150,7 @@ public:
|
||||
const T* const a = values.get(ai);
|
||||
const T* const b = values.get(bi);
|
||||
|
||||
return (a && b) ? (*a < *b) : bool(a);
|
||||
return (a && b) ? (*a < *b) : !b;
|
||||
}
|
||||
};
|
||||
|
||||
@ -171,7 +171,7 @@ public:
|
||||
const T* const a = values.get(ai);
|
||||
const T* const b = values.get(bi);
|
||||
|
||||
return (a && b) ? (*b < *a) : bool(b);
|
||||
return (a && b) ? (*b < *a) : !a;
|
||||
}
|
||||
};
|
||||
|
||||
@ -262,10 +262,15 @@ public:
|
||||
//- Alias for resize()
|
||||
void setSize(const label n) { this->resize(n); }
|
||||
|
||||
//- Squeeze out intermediate nullptr entries in the list of pointers
|
||||
//- Squeeze out nullptr entries in the list of pointers after which
|
||||
//- any null pointers will be at the end of the list
|
||||
// \return the number of non-null entries
|
||||
label squeezeNull();
|
||||
|
||||
//- Reduce addressable list size to ignore any trailing null pointers.
|
||||
// The reduces the effective list length without reallocation
|
||||
void trimTrailingNull();
|
||||
|
||||
//- Append an element to the end of the list
|
||||
inline void push_back(T* ptr);
|
||||
|
||||
@ -343,7 +348,7 @@ public:
|
||||
// Member Functions
|
||||
|
||||
//- Return pointer, can be nullptr.
|
||||
inline pointer get() const;
|
||||
pointer get() const { return *ptr_; }
|
||||
|
||||
// Member Operators
|
||||
|
||||
@ -403,7 +408,7 @@ public:
|
||||
// Member Functions
|
||||
|
||||
//- Return pointer, can be nullptr.
|
||||
inline pointer get() const;
|
||||
pointer get() const { return *ptr_; }
|
||||
|
||||
// Member Operators
|
||||
|
||||
@ -507,6 +512,8 @@ public:
|
||||
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
|
||||
|
||||
//- Inplace (stable) sorting of pointer list.
|
||||
// This sort function includes null pointer guards and will also sort
|
||||
// any null pointers to the end (eg, rubbish that can be truncated)
|
||||
template<class T>
|
||||
void sort(UPtrList<T>& list);
|
||||
|
||||
|
||||
@ -281,13 +281,6 @@ iterator(T** ptr) noexcept
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline T* Foam::UPtrList<T>::iterator::get() const
|
||||
{
|
||||
return *ptr_;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline T* Foam::UPtrList<T>::iterator::operator->() const
|
||||
{
|
||||
@ -455,13 +448,6 @@ const_iterator(const iterator& iter) noexcept
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline const T* Foam::UPtrList<T>::const_iterator::get() const
|
||||
{
|
||||
return *ptr_;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline const T* Foam::UPtrList<T>::const_iterator::operator->() const
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user