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()
|
inline Foam::label Foam::PtrDynList<T, SizeMin>::squeezeNull()
|
||||||
{
|
{
|
||||||
const label newLen = UPtrList<T>::squeezeNull();
|
const label newLen = UPtrList<T>::squeezeNull();
|
||||||
resize(newLen);
|
PtrList<T>::setAddressableSize(newLen);
|
||||||
return 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>
|
template<class T>
|
||||||
void Foam::UPtrList<T>::reorder(const labelUList& oldToNew, const bool check)
|
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 * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * 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>
|
template<class T, class Compare>
|
||||||
void Foam::sort(UPtrList<T>& list, const Compare& comp)
|
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
|
//- Compare dereferenced pointers
|
||||||
bool operator()(const T* const a, const T* const b) const
|
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 a = values.get(ai);
|
||||||
const T* const b = values.get(bi);
|
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 a = values.get(ai);
|
||||||
const T* const b = values.get(bi);
|
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()
|
//- Alias for resize()
|
||||||
void setSize(const label n) { this->resize(n); }
|
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
|
// \return the number of non-null entries
|
||||||
label squeezeNull();
|
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
|
//- Append an element to the end of the list
|
||||||
inline void push_back(T* ptr);
|
inline void push_back(T* ptr);
|
||||||
|
|
||||||
@ -343,7 +348,7 @@ public:
|
|||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Return pointer, can be nullptr.
|
//- Return pointer, can be nullptr.
|
||||||
inline pointer get() const;
|
pointer get() const { return *ptr_; }
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
|
|
||||||
@ -403,7 +408,7 @@ public:
|
|||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Return pointer, can be nullptr.
|
//- Return pointer, can be nullptr.
|
||||||
inline pointer get() const;
|
pointer get() const { return *ptr_; }
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
|
|
||||||
@ -507,6 +512,8 @@ public:
|
|||||||
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
//- Inplace (stable) sorting of pointer list.
|
//- 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>
|
template<class T>
|
||||||
void sort(UPtrList<T>& list);
|
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>
|
template<class T>
|
||||||
inline T* Foam::UPtrList<T>::iterator::operator->() const
|
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>
|
template<class T>
|
||||||
inline const T* Foam::UPtrList<T>::const_iterator::operator->() const
|
inline const T* Foam::UPtrList<T>::const_iterator::operator->() const
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user