ENH: use std algorithms for copy/move/compare within List containers

ENH: add List resize_fill variant. Fuses resize_nocopy + uniform fill

COMP: avoid cast ambiguity when assigning Foam::zero to UList<char>
This commit is contained in:
Mark Olesen
2023-08-04 16:46:12 +02:00
parent eeb9d144e3
commit 2422e6f061
23 changed files with 397 additions and 466 deletions

View File

@ -79,6 +79,13 @@ int main(int argc, char *argv[])
List<char> alphabet(istr); List<char> alphabet(istr);
Info<< "re-read: " << alphabet << nl; Info<< "re-read: " << alphabet << nl;
// Can assign zero?
//Fails: alphabet = char(Zero);
alphabet = Foam::zero{};
// alphabet = '@';
Info<< "blanked: " << alphabet << nl;
} }
return 0; return 0;

View File

@ -457,10 +457,10 @@ public:
inline reference operator[](const label i); inline reference operator[](const label i);
//- Copy assignment. //- Copy assignment.
inline void operator=(const PackedList<Width>& lst); inline void operator=(const PackedList<Width>& list);
//- Move assignment. //- Move assignment.
inline void operator=(PackedList<Width>&& lst); inline void operator=(PackedList<Width>&& list);
//- Assign all entries to the given value. fill() //- Assign all entries to the given value. fill()
inline void operator=(const unsigned int val); inline void operator=(const unsigned int val);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2022 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,27 +36,28 @@ Foam::label Foam::DynamicList<T, SizeMin>::removeElements
const labelRange& slice const labelRange& slice
) )
{ {
if (!slice.size()) if (!slice.good())
{ {
// No-op // No-op
return 0; return 0;
} }
else if (slice.end_value() >= this->size())
// Note: already checked for valid begin_value before
if (slice.end_value() >= this->size())
{ {
// Remove entire tail // Remove entire tail
this->resize(slice.begin_value()); this->resize(slice.begin_value());
} }
else else
{ {
// Copy (swap) down, from range rbegin() -> rend() // Move all trailing elements down into space previously
// followed by truncation // occupied by the slice. Truncate after
label j = slice.begin_value(); std::move
const label len = this->size(); (
this->begin(slice.end_value()),
for (label i = slice.end_value(); i < len; ++i, ++j) this->end(),
{ this->begin(slice.begin_value())
Foam::Swap(this->operator[](i), this->operator[](j)); );
}
this->resize(this->size() - slice.size()); this->resize(this->size() - slice.size());
} }
@ -73,14 +74,14 @@ Foam::label Foam::DynamicList<T, SizeMin>::subsetElements
{ {
if (slice.begin_value() > 0) if (slice.begin_value() > 0)
{ {
// Copy (swap) down // Move elements down.
label j = slice.begin_value(); // Since begin_value > 0, the initial destination is non-overlapping
const label len = slice.size(); std::move
(
for (label i = 0; i < len; ++i, ++j) this->begin(slice.begin_value()),
{ this->begin(slice.end_value()),
Foam::Swap(this->operator[](i), this->operator[](j)); this->begin()
} );
} }
// Don't need min size, since slice size was already checked before // Don't need min size, since slice size was already checked before

View File

@ -216,9 +216,12 @@ public:
// setting values (as per List usage). // setting values (as per List usage).
inline void resize(const label len); inline void resize(const label len);
//- Alter addressable size and fill new entries with constant value //- Alter addressable size and fill \em new entries with constant value
inline void resize(const label len, const T& val); inline void resize(const label len, const T& val);
//- Alter addressable size and set val for \em all addressed entries
inline void resize_fill(const label len, const T& val);
//- Alter addressable list size, allocating new space if required //- Alter addressable list size, allocating new space if required
//- \em without necessarily recovering old content. //- \em without necessarily recovering old content.
// If no reallocation is required, the contents remain untouched. // If no reallocation is required, the contents remain untouched.
@ -328,7 +331,6 @@ public:
//- Retain a (start,size) subset from the list. //- Retain a (start,size) subset from the list.
// The range is subsetted with the list size itself to ensure // The range is subsetted with the list size itself to ensure
// result always addresses a valid section of the list. // result always addresses a valid section of the list.
// Remaining elements are moved down.
inline label subset(const labelRange& range); inline label subset(const labelRange& range);
//- Retain a (start,size) subset from List. //- Retain a (start,size) subset from List.

View File

@ -363,6 +363,18 @@ inline void Foam::DynamicList<T, SizeMin>::resize
} }
template<class T, int SizeMin>
inline void Foam::DynamicList<T, SizeMin>::resize_fill
(
const label len,
const T& val
)
{
this->doResize(true, len); // nocopy = true
UList<T>::operator=(val);
}
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::DynamicList<T, SizeMin>::resize_nocopy inline void Foam::DynamicList<T, SizeMin>::resize_nocopy
( (
@ -373,18 +385,6 @@ inline void Foam::DynamicList<T, SizeMin>::resize_nocopy
} }
// template<class T, int SizeMin>
// inline void Foam::DynamicList<T, SizeMin>::resize_fill
// (
// const label len,
// const T& val
// )
// {
// this->doResize(true, len); // nocopy = true
// this->fill_uniform(val);
// }
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::DynamicList<T, SizeMin>::resize inline void Foam::DynamicList<T, SizeMin>::resize
( (
@ -392,14 +392,16 @@ inline void Foam::DynamicList<T, SizeMin>::resize
const T& val const T& val
) )
{ {
label idx = List<T>::size(); const label oldLen = List<T>::size();
resize(len); resize(len);
// Fill newly exposed with constant value // Fill newly exposed with constant value
while (idx < len) if (oldLen < List<T>::size())
{ {
this->operator[](idx) = val; std::fill
++idx; (
this->begin(oldLen), this->end(), val
);
} }
} }
@ -527,8 +529,8 @@ inline T& Foam::DynamicList<T, SizeMin>::emplace_back(Args&&... args)
resize(idx + 1); resize(idx + 1);
// move assign element // move assign element
this->operator[](idx) = T(std::forward<Args>(args)...); UList<T>::operator[](idx) = T(std::forward<Args>(args)...);
return this->back(); return UList<T>::operator[](idx);
} }
@ -541,7 +543,7 @@ inline void Foam::DynamicList<T, SizeMin>::push_back
const label idx = List<T>::size(); const label idx = List<T>::size();
resize(idx + 1); resize(idx + 1);
this->operator[](idx) = val; // copy element UList<T>::operator[](idx) = val; // copy element
} }
@ -554,30 +556,27 @@ inline void Foam::DynamicList<T, SizeMin>::push_back
const label idx = List<T>::size(); const label idx = List<T>::size();
resize(idx + 1); resize(idx + 1);
this->operator[](idx) = std::move(val); // move assign element UList<T>::operator[](idx) = std::move(val); // move assign element
} }
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::DynamicList<T, SizeMin>::push_back inline void Foam::DynamicList<T, SizeMin>::push_back
( (
const UList<T>& lst const UList<T>& list
) )
{ {
if (this == &lst) if (this == &list)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempted push_back to self" << "Attempted push_back to self"
<< abort(FatalError); << abort(FatalError);
} }
label idx = List<T>::size(); const label idx = List<T>::size();
resize(idx + lst.size()); resize(idx + list.size());
for (const T& val : lst) std::copy(list.begin(), list.end(), this->begin(idx));
{
this->operator[](idx++) = val; // copy element
}
} }
@ -585,32 +584,26 @@ template<class T, int SizeMin>
template<unsigned N> template<unsigned N>
inline void Foam::DynamicList<T, SizeMin>::push_back inline void Foam::DynamicList<T, SizeMin>::push_back
( (
const FixedList<T, N>& lst const FixedList<T, N>& list
) )
{ {
label idx = List<T>::size(); const label idx = List<T>::size();
resize(idx + lst.size()); resize(idx + list.size());
for (const T& val : lst) std::copy(list.begin(), list.end(), this->begin(idx));
{
this->operator[](idx++) = val; // copy element
}
} }
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::DynamicList<T, SizeMin>::push_back inline void Foam::DynamicList<T, SizeMin>::push_back
( (
std::initializer_list<T> lst std::initializer_list<T> list
) )
{ {
label idx = List<T>::size(); const label idx = List<T>::size();
resize(idx + lst.size()); resize(idx + list.size());
for (const T& val : lst) std::copy(list.begin(), list.end(), this->begin(idx));
{
this->operator[](idx++) = val; // copy element
}
} }
@ -618,17 +611,23 @@ template<class T, int SizeMin>
template<class Addr> template<class Addr>
inline void Foam::DynamicList<T, SizeMin>::push_back inline void Foam::DynamicList<T, SizeMin>::push_back
( (
const IndirectListBase<T, Addr>& lst const IndirectListBase<T, Addr>& list
) )
{ {
label idx = List<T>::size(); // Note: push_back will still work even if the indirect list
const label n = lst.size(); // actually references *this, since its source elements will not
// overlap the new destinations.
resize(idx + n); const label idx = this->size();
const label n = list.size();
for (label i=0; i<n; ++i) resize(list + n);
auto iter = this->begin(idx);
for (label i = 0; i < n; (void)++i, (void)++iter)
{ {
this->operator[](idx++) = lst[i]; // copy element *iter = list[i]; // copy element
} }
} }
@ -646,13 +645,10 @@ inline void Foam::DynamicList<T, SizeMin>::push_back
<< abort(FatalError); << abort(FatalError);
} }
label idx = List<T>::size(); const label idx = List<T>::size();
resize(idx + list.size()); resize(idx + list.size());
for (T& val : list) std::move(list.begin(), list.end(), this->begin(idx));
{
Foam::Swap(this->operator[](idx++), val); // moved content
}
list.clear(); list.clear();
} }
@ -795,7 +791,7 @@ inline T& Foam::DynamicList<T, SizeMin>::operator()
resize(i + 1); resize(i + 1);
} }
return this->operator[](i); return UList<T>::operator[](i);
} }

View File

@ -259,7 +259,7 @@ Foam::Istream& Foam::DynamicList<T, SizeMin>::readList(Istream& is)
); );
// Fill with the value // Fill with the value
this->fill_uniform(elem); UList<T>::operator=(elem);
} }
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,7 +27,6 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "FixedList.H" #include "FixedList.H"
#include "ListLoopM.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
@ -51,11 +50,15 @@ Foam::label Foam::FixedList<T, N>::find(const T& val, label pos) const
{ {
if (pos >= 0) if (pos >= 0)
{ {
List_CONST_ACCESS(T, *this, list); // auto iter = std::find(this->begin(pos), this->end(), val);
// if (iter != this->end())
// {
// return label(iter - this->begin());
// }
while (pos < label(N)) while (pos < label(N))
{ {
if (list[pos] == val) if (this->v_[pos] == val)
{ {
return pos; return pos;
} }
@ -77,11 +80,9 @@ Foam::label Foam::FixedList<T, N>::rfind(const T& val, label pos) const
pos = label(N)-1; pos = label(N)-1;
} }
List_CONST_ACCESS(T, *this, list);
while (pos >= 0) while (pos >= 0)
{ {
if (list[pos] == val) if (this->v_[pos] == val)
{ {
return pos; return pos;
} }
@ -148,44 +149,30 @@ void Foam::FixedList<T, N>::swapLast(const label i)
template<class T, unsigned N> template<class T, unsigned N>
bool Foam::FixedList<T, N>::operator==(const FixedList<T, N>& list) const bool Foam::FixedList<T, N>::operator==(const FixedList<T, N>& list) const
{ {
List_CONST_ACCESS(T, *this, lhs); // Can dispatch with
List_CONST_ACCESS(T, (list), rhs); // - std::execution::parallel_unsequenced_policy
// - std::execution::unsequenced_policy
// List sizes are identical by definition (template parameter) return
for (unsigned i = 0; i < N; ++i) (
{ // List sizes are identical by definition (template parameter)
if (!(lhs[i] == rhs[i])) std::equal(this->cbegin(), this->cend(), list.cbegin())
{ );
return false;
}
}
// Contents appear to be identical.
return true;
} }
template<class T, unsigned N> template<class T, unsigned N>
bool Foam::FixedList<T, N>::operator<(const FixedList<T, N>& list) const bool Foam::FixedList<T, N>::operator<(const FixedList<T, N>& list) const
{ {
List_CONST_ACCESS(T, *this, lhs);
List_CONST_ACCESS(T, (list), rhs);
// List sizes are identical by definition (template parameter) // List sizes are identical by definition (template parameter)
for (unsigned i=0; i<N; ++i)
{
if (lhs[i] < rhs[i])
{
return true;
}
else if (rhs[i] < lhs[i])
{
return false;
}
}
// Contents appear to be identical. // Can dispatch with
return false; // - std::execution::parallel_unsequenced_policy
// - std::execution::unsequenced_policy
return std::lexicographical_compare
(
this->cbegin(), this->cend(),
list.cbegin(), list.cend()
);
} }

View File

@ -239,7 +239,7 @@ public:
//- Return the forward circular index, i.e. next index //- Return the forward circular index, i.e. next index
//- which returns to the first at the end of the list //- which returns to the first at the end of the list
inline label fcIndex(const label i) const; inline label fcIndex(const label i) const noexcept;
//- Return forward circular value (ie, next value in the list) //- Return forward circular value (ie, next value in the list)
inline const T& fcValue(const label i) const; inline const T& fcValue(const label i) const;
@ -249,7 +249,7 @@ public:
//- Return the reverse circular index, i.e. previous index //- Return the reverse circular index, i.e. previous index
//- which returns to the last at the beginning of the list //- which returns to the last at the beginning of the list
inline label rcIndex(const label i) const; inline label rcIndex(const label i) const noexcept;
//- Return reverse circular value (ie, previous value in the list) //- Return reverse circular value (ie, previous value in the list)
inline const T& rcValue(const label i) const; inline const T& rcValue(const label i) const;
@ -297,9 +297,15 @@ public:
// Edit // Edit
//- Dummy function, to make FixedList consistent with List //- Dummy function, to make FixedList consistent with List
//- Any resizing is ignored (Fatal with bad sizing in full debug).
inline void resize(const label n); inline void resize(const label n);
//- Set val for \em all elements.
//- Any resizing is ignored (Fatal with bad sizing in full debug).
inline void resize_fill(const label n, const T& val);
//- Dummy function, to make FixedList consistent with List //- Dummy function, to make FixedList consistent with List
//- Any resizing is ignored (Fatal with bad sizing in full debug).
inline void resize_nocopy(const label n); inline void resize_nocopy(const label n);
//- Dummy function, to make FixedList consistent with List //- Dummy function, to make FixedList consistent with List

View File

@ -56,20 +56,16 @@ inline Foam::FixedList<T, N>::FixedList(const Foam::zero)
template<class T, unsigned N> template<class T, unsigned N>
inline Foam::FixedList<T, N>::FixedList(const FixedList<T, N>& list) inline Foam::FixedList<T, N>::FixedList(const FixedList<T, N>& list)
{ {
for (unsigned i=0; i<N; ++i) // std::execution::unsequenced_policy
{ std::copy(list.begin(), list.end(), v_);
v_[i] = list.v_[i];
}
} }
template<class T, unsigned N> template<class T, unsigned N>
inline Foam::FixedList<T, N>::FixedList(FixedList<T, N>&& list) inline Foam::FixedList<T, N>::FixedList(FixedList<T, N>&& list)
{ {
for (unsigned i=0; i<N; ++i) // std::execution::unsequenced_policy
{ std::move(list.begin(), list.end(), v_);
v_[i] = std::move(list.v_[i]);
}
} }
@ -77,13 +73,7 @@ template<class T, unsigned N>
inline Foam::FixedList<T, N>::FixedList(std::initializer_list<T> list) inline Foam::FixedList<T, N>::FixedList(std::initializer_list<T> list)
{ {
checkSize(list.size()); checkSize(list.size());
std::copy_n(list.begin(), N, v_);
auto iter = list.begin();
for (unsigned i=0; i<N; ++i)
{
v_[i] = *iter;
++iter;
}
} }
@ -91,11 +81,7 @@ template<class T, unsigned N>
inline Foam::FixedList<T, N>::FixedList(const UList<T>& list) inline Foam::FixedList<T, N>::FixedList(const UList<T>& list)
{ {
checkSize(list.size()); checkSize(list.size());
std::copy_n(list.begin(), N, v_);
for (unsigned i=0; i<N; ++i)
{
v_[i] = list[i];
}
} }
@ -107,7 +93,7 @@ inline Foam::FixedList<T, N>::FixedList
const FixedList<label, N>& indices const FixedList<label, N>& indices
) )
{ {
for (unsigned i=0; i<N; ++i) for (unsigned i = 0; i < N; ++i)
{ {
v_[i] = list[indices[i]]; v_[i] = list[indices[i]];
} }
@ -121,7 +107,7 @@ inline Foam::FixedList<T, N>::FixedList
const FixedList<label, N>& indices const FixedList<label, N>& indices
) )
{ {
for (unsigned i=0; i<N; ++i) for (unsigned i = 0; i < N; ++i)
{ {
v_[i] = list[indices[i]]; v_[i] = list[indices[i]];
} }
@ -224,7 +210,7 @@ inline const T& Foam::FixedList<T, N>::back() const noexcept
template<class T, unsigned N> template<class T, unsigned N>
inline Foam::label Foam::FixedList<T, N>::fcIndex(const label i) const inline Foam::label Foam::FixedList<T, N>::fcIndex(const label i) const noexcept
{ {
return (i == N-1 ? 0 : i+1); return (i == N-1 ? 0 : i+1);
} }
@ -245,7 +231,7 @@ inline T& Foam::FixedList<T, N>::fcValue(const label i)
template<class T, unsigned N> template<class T, unsigned N>
inline Foam::label Foam::FixedList<T, N>::rcIndex(const label i) const inline Foam::label Foam::FixedList<T, N>::rcIndex(const label i) const noexcept
{ {
return (i ? i-1 : N-1); return (i ? i-1 : N-1);
} }
@ -307,6 +293,7 @@ inline bool Foam::FixedList<T, N>::uniform() const
{ {
if (empty()) return false; // <- Compile-time disabled anyhow if (empty()) return false; // <- Compile-time disabled anyhow
// std::all_of()
for (unsigned i=1; i<N; ++i) for (unsigned i=1; i<N; ++i)
{ {
if (v_[0] != v_[i]) if (v_[0] != v_[i])
@ -335,6 +322,16 @@ inline void Foam::FixedList<T, N>::resize(const label n)
} }
template<class T, unsigned N>
inline void Foam::FixedList<T, N>::resize_fill(const label n, const T& val)
{
#ifdef FULLDEBUG
checkSize(n);
#endif
this->fill(val);
}
template<class T, unsigned N> template<class T, unsigned N>
inline void Foam::FixedList<T, N>::resize_nocopy(const label n) inline void Foam::FixedList<T, N>::resize_nocopy(const label n)
{ {
@ -348,10 +345,7 @@ template<class T, unsigned N>
inline void Foam::FixedList<T, N>::fill(const T& val) inline void Foam::FixedList<T, N>::fill(const T& val)
{ {
// Usually small enough that parallel execution is pointless... // Usually small enough that parallel execution is pointless...
for (unsigned i=0; i<N; ++i) std::fill_n(v_, N, val);
{
v_[i] = val;
}
} }
@ -359,7 +353,9 @@ template<class T, unsigned N>
inline void Foam::FixedList<T, N>::fill(const Foam::zero) inline void Foam::FixedList<T, N>::fill(const Foam::zero)
{ {
// Usually small enough that parallel execution is pointless... // Usually small enough that parallel execution is pointless...
for (unsigned i=0; i<N; ++i) // Cannot use std::fill (ambiguous conversions for bool, char, etc)
for (unsigned i = 0; i < N; ++i)
{ {
v_[i] = Zero; v_[i] = Zero;
} }
@ -390,10 +386,8 @@ inline void Foam::FixedList<T, N>::transfer(FixedList<T, N>& list)
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
for (unsigned i=0; i<N; ++i) // std::execution::unsequenced_policy
{ std::move(list.begin(), list.end(), v_);
v_[i] = std::move(list[i]);
}
} }
@ -423,11 +417,7 @@ template<class T, unsigned N>
inline void Foam::FixedList<T, N>::operator=(const UList<T>& list) inline void Foam::FixedList<T, N>::operator=(const UList<T>& list)
{ {
checkSize(list.size()); checkSize(list.size());
std::copy_n(list.begin(), N, v_);
for (unsigned i=0; i<N; ++i)
{
v_[i] = list[i];
}
} }
@ -435,15 +425,10 @@ template<class T, unsigned N>
inline void Foam::FixedList<T, N>::operator=(std::initializer_list<T> list) inline void Foam::FixedList<T, N>::operator=(std::initializer_list<T> list)
{ {
checkSize(list.size()); checkSize(list.size());
std::copy_n(list.begin(), N, v_);
auto iter = list.begin();
for (unsigned i=0; i<N; ++i)
{
v_[i] = *iter;
++iter;
}
} }
template<class T, unsigned N> template<class T, unsigned N>
inline void Foam::FixedList<T, N>::operator=(const T& val) inline void Foam::FixedList<T, N>::operator=(const T& val)
{ {
@ -466,12 +451,11 @@ inline void Foam::FixedList<T, N>::operator=(const FixedList<T, N>& list)
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
for (unsigned i=0; i<N; ++i) // std::execution::unsequenced_policy
{ std::copy(list.begin(), list.end(), v_);
v_[i] = list.v_[i];
}
} }
template<class T, unsigned N> template<class T, unsigned N>
inline void Foam::FixedList<T, N>::operator=(FixedList<T, N>&& list) inline void Foam::FixedList<T, N>::operator=(FixedList<T, N>&& list)
{ {
@ -480,10 +464,8 @@ inline void Foam::FixedList<T, N>::operator=(FixedList<T, N>&& list)
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
for (unsigned i=0; i<N; ++i) // std::execution::unsequenced_policy
{ std::move(list.begin(), list.end(), v_);
v_[i] = std::move(list.v_[i]);
}
} }

View File

@ -27,7 +27,6 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "List.H" #include "List.H"
#include "ListLoopM.H"
#include "FixedList.H" #include "FixedList.H"
#include "PtrList.H" #include "PtrList.H"
#include "contiguous.H" #include "contiguous.H"
@ -47,46 +46,26 @@ void Foam::List<T>::doResize(const label len)
// With sign-check to avoid spurious -Walloc-size-larger-than // With sign-check to avoid spurious -Walloc-size-larger-than
const label overlap = min(this->size_, len); const label overlap = min(this->size_, len);
if (!overlap) if (overlap > 0)
{ {
// Can discard old content before allocating new storage. // Recover overlapping content when resizing
// - when used as storage for DynamicList, it is possible to have T* old = this->v_;
// a zero-sized List with a non-null data pointer.
delete[] this->v_;
this->size_ = len; this->size_ = len;
this->v_ = new T[len]; this->v_ = new T[len];
// Can dispatch with
// - std::execution::parallel_unsequenced_policy
// - std::execution::unsequenced_policy
std::move(old, (old + overlap), this->v_);
delete[] old;
} }
else else
{ {
// Recover old (overlapping) content when resizing // No overlapping content
T* nv = new T[len];
// Like std::copy(this->v_, this->v_ + overlap, nv);
// but with move semantics!
#ifdef USEMEMCPY
if (is_contiguous<T>::value)
{
std::memcpy
(
static_cast<void*>(nv), this->v_, overlap*sizeof(T)
);
}
else
#endif
{
List_ACCESS(T, *this, vp);
for (label i = 0; i < overlap; ++i)
{
nv[i] = std::move(vp[i]);
}
}
delete[] this->v_; delete[] this->v_;
this->size_ = len; this->size_ = len;
this->v_ = nv; this->v_ = new T[len];
} }
} }
else else
@ -138,7 +117,7 @@ Foam::List<T>::List(const label len, const T& val)
if (len) if (len)
{ {
doAlloc(); doAlloc();
this->fill_uniform(val); UList<T>::operator=(val);
} }
} }
@ -158,13 +137,7 @@ Foam::List<T>::List(const label len, const Foam::zero)
if (len) if (len)
{ {
doAlloc(); doAlloc();
UList<T>::operator=(Foam::zero{});
// fill_uniform()
List_ACCESS(T, (*this), vp);
for (label i = 0; i < len; ++i)
{
vp[i] = Zero;
}
} }
} }
@ -249,20 +222,8 @@ Foam::List<T>::List(const UList<T>& list, const labelUList& indices)
: :
UList<T>(nullptr, indices.size()) UList<T>(nullptr, indices.size())
{ {
const label len = indices.size(); doAlloc();
copyList(list, indices); // <- deepCopy()
if (len)
{
doAlloc();
// Copy indirect
List_ACCESS(T, (*this), vp);
for (label i=0; i < len; ++i)
{
vp[i] = list[indices[i]];
}
}
} }
@ -274,21 +235,10 @@ Foam::List<T>::List
const FixedList<label,N>& indices const FixedList<label,N>& indices
) )
: :
UList<T>(nullptr, label(N)) UList<T>(nullptr, indices.size())
{ {
const label len = label(N); doAlloc();
copyList(list, indices); // <- deepCopy()
{
doAlloc();
// Copy indirect
List_ACCESS(T, (*this), vp);
for (label i = 0; i < len; ++i)
{
vp[i] = list[indices[i]];
}
}
} }
@ -296,11 +246,8 @@ template<class T>
template<unsigned N> template<unsigned N>
Foam::List<T>::List(const FixedList<T, N>& list) Foam::List<T>::List(const FixedList<T, N>& list)
: :
UList<T>(nullptr, label(N)) List<T>(list.begin(), list.end(), list.size())
{ {}
doAlloc();
copyList(list);
}
template<class T> template<class T>
@ -319,8 +266,11 @@ Foam::List<T>::List(const IndirectListBase<T, Addr>& list)
: :
UList<T>(nullptr, list.size()) UList<T>(nullptr, list.size())
{ {
doAlloc(); if (this->size_ > 0)
copyList(list); {
doAlloc();
UList<T>::deepCopy(list);
}
} }
@ -450,15 +400,9 @@ template<class T>
template<unsigned N> template<unsigned N>
void Foam::List<T>::operator=(const FixedList<T, N>& list) void Foam::List<T>::operator=(const FixedList<T, N>& list)
{ {
reAlloc(static_cast<label>(N)); reAlloc(list.size());
T* iter = this->begin(); std::copy(list.begin(), list.end(), this->v_);
for (const T& val : list)
{
*iter = val;
++iter;
}
} }
@ -466,40 +410,17 @@ template<class T>
template<class Addr> template<class Addr>
void Foam::List<T>::operator=(const IndirectListBase<T, Addr>& list) void Foam::List<T>::operator=(const IndirectListBase<T, Addr>& list)
{ {
const label len = list.size(); reAlloc(list.size());
UList<T>::deepCopy(list);
reAlloc(len);
if (len)
{
// copyList ...
List_ACCESS(T, (*this), vp);
for (label i=0; i < len; ++i)
{
vp[i] = list[i];
}
}
} }
template<class T> template<class T>
void Foam::List<T>::operator=(std::initializer_list<T> list) void Foam::List<T>::operator=(std::initializer_list<T> list)
{ {
const label len = list.size(); reAlloc(list.size());
reAlloc(len); std::copy(list.begin(), list.end(), this->v_);
if (len)
{
T* iter = this->begin();
for (const T& val : list)
{
*iter = val;
++iter;
}
}
} }
@ -571,7 +492,6 @@ void Foam::sortedOrder
} }
// * * * * * * * * * * * * * * * Housekeeping * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Housekeeping * * * * * * * * * * * * * * * //
#include "SLList.H" #include "SLList.H"

View File

@ -86,8 +86,13 @@ class List
inline void reAlloc(const label len); inline void reAlloc(const label len);
//- Copy all list contents. Uses operator[] on the input list //- Copy all list contents. Uses operator[] on the input list
template<class List2> template<class ListType>
inline void copyList(const List2& list); inline void copyList(const ListType& list);
//- Copy list contents via indirect indices.
// Uses operator[] on the values and indices lists
template<class ListType, class ListIndices>
inline void copyList(const ListType& list, const ListIndices& indices);
//- Change allocation size of List, retaining old contents. //- Change allocation size of List, retaining old contents.
// Backend for resize // Backend for resize
@ -98,8 +103,8 @@ class List
template<class InputIterator> template<class InputIterator>
inline List inline List
( (
InputIterator begIter, InputIterator firstIter,
InputIterator endIter, InputIterator lastIter, // (unused)
const label len const label len
); );
@ -213,9 +218,12 @@ public:
// The boolList version fills new memory with false. // The boolList version fills new memory with false.
inline void resize(const label len); inline void resize(const label len);
//- Adjust allocated size of list and set val for new elements //- Adjust allocated size of list and set val for \em new elements
void resize(const label len, const T& val); void resize(const label len, const T& val);
//- Adjust allocated size of list and set val for \em all elements
inline void resize_fill(const label len, const T& val);
//- Adjust allocated size of list \b without necessarily //- Adjust allocated size of list \b without necessarily
// retaining old content. // retaining old content.
// If no reallocation is required, the contents remain untouched. // If no reallocation is required, the contents remain untouched.

View File

@ -52,17 +52,41 @@ inline void Foam::List<T>::reAlloc(const label len)
template<class T> template<class T>
template<class List2> template<class ListType>
inline void Foam::List<T>::copyList(const List2& list) inline void Foam::List<T>::copyList(const ListType& list)
{ {
// NB: operator[] for list read access (eg, an indirect list) // NB: operator[] for list read access (eg, an indirect list)
// cannot necessarily replace with std::copy // cannot necessarily replace with std::copy
const label len = this->size_; const label len = this->size_;
for (label i = 0; i < len; ++i) auto iter = this->v_;
for (label i = 0; i < len; (void)++i, (void)++iter)
{ {
this->v_[i] = list[i]; *iter = list[i];
}
}
template<class T>
template<class ListType, class ListIndices>
inline void Foam::List<T>::copyList
(
const ListType& list,
const ListIndices& indices
)
{
// NB: operator[] for list read access (eg, an indirect list)
// cannot necessarily replace with std::copy
const label len = this->size_;
auto iter = this->v_;
for (label i = 0; i < len; (void)++i, (void)++iter)
{
*iter = list[indices[i]];
} }
} }
@ -71,8 +95,8 @@ template<class T>
template<class InputIterator> template<class InputIterator>
inline Foam::List<T>::List inline Foam::List<T>::List
( (
InputIterator begIter, InputIterator firstIter,
InputIterator endIter, InputIterator lastIter, // (unused)
const label len const label len
) )
: :
@ -85,11 +109,9 @@ inline Foam::List<T>::List
// Like std::copy() or std::copy_n() // Like std::copy() or std::copy_n()
// but without any requirements on the iterator category // but without any requirements on the iterator category
InputIterator iter = begIter; for (label i = 0; i < len; (void)++i, (void)++firstIter)
for (label i = 0; i < len; ++i)
{ {
this->v_[i] = *iter; this->v_[i] = *firstIter;
++iter;
} }
} }
} }
@ -148,6 +170,14 @@ inline void Foam::List<T>::resize(const label len)
} }
template<class T>
inline void Foam::List<T>::resize_fill(const label len, const T& val)
{
this->reAlloc(len);
UList<T>::operator=(val);
}
template<class T> template<class T>
inline void Foam::List<T>::resize_nocopy(const label len) inline void Foam::List<T>::resize_nocopy(const label len)
{ {
@ -155,14 +185,6 @@ inline void Foam::List<T>::resize_nocopy(const label len)
} }
// template<class T>
// inline void Foam::List<T>::resize_fill(const label len, const T& val)
// {
// this->reAlloc(len);
// this->fill_uniform(val);
// }
template<class T> template<class T>
inline T& Foam::List<T>::newElmt(const label i) inline T& Foam::List<T>::newElmt(const label i)
{ {
@ -196,9 +218,8 @@ inline T& Foam::List<T>::emplace_back(Args&&... args)
const label idx = this->size(); const label idx = this->size();
resize(idx + 1); resize(idx + 1);
// move assign element UList<T>::operator[](idx) = T(std::forward<Args>(args)...);
this->operator[](idx) = T(std::forward<Args>(args)...); return UList<T>::operator[](idx);
return this->back();
} }
@ -208,7 +229,7 @@ inline void Foam::List<T>::push_back(const T& val)
const label idx = this->size(); const label idx = this->size();
resize(idx + 1); resize(idx + 1);
this->operator[](idx) = val; // copy element UList<T>::operator[](idx) = val; // copy element
} }
@ -218,7 +239,7 @@ inline void Foam::List<T>::push_back(T&& val)
const label idx = this->size(); const label idx = this->size();
resize(idx + 1); resize(idx + 1);
this->operator[](idx) = std::move(val); // move assign element UList<T>::operator[](idx) = std::move(val); // move assign element
} }
@ -231,15 +252,10 @@ inline void Foam::List<T>::push_back(const UList<T>& list)
<< "Attempted push_back to self" << abort(FatalError); << "Attempted push_back to self" << abort(FatalError);
} }
label idx = this->size(); const label idx = this->size();
const label n = list.size(); resize(idx + list.size());
resize(idx + n); std::copy(list.begin(), list.end(), this->begin(idx));
for (label i=0; i<n; ++i)
{
this->operator[](idx++) = list[i]; // copy element
}
} }
@ -247,14 +263,20 @@ template<class T>
template<class Addr> template<class Addr>
inline void Foam::List<T>::push_back(const IndirectListBase<T, Addr>& list) inline void Foam::List<T>::push_back(const IndirectListBase<T, Addr>& list)
{ {
label idx = this->size(); // Note: push_back will still work even if the indirect list
// actually references *this, since its source elements will not
// overlap the new destinations.
const label idx = this->size();
const label n = list.size(); const label n = list.size();
resize(idx + n); resize(idx + n);
for (label i=0; i<n; ++i) auto iter = this->begin(idx);
for (label i = 0; i < n; (void)++i, (void)++iter)
{ {
this->operator[](idx++) = list[i]; // copy element *iter = list[i]; // copy element
} }
} }

View File

@ -259,7 +259,7 @@ Foam::Istream& Foam::List<T>::readList(Istream& is)
); );
// Fill with the value // Fill with the value
this->fill_uniform(elem); UList<T>::operator=(elem);
} }
} }

View File

@ -27,7 +27,6 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "UList.H" #include "UList.H"
#include "ListLoopM.H"
#include "contiguous.H" #include "contiguous.H"
#include "labelRange.H" #include "labelRange.H"
@ -114,10 +113,9 @@ void Foam::UList<T>::deepCopy(const UList<T>& list)
} }
else if (this->size_ > 0) else if (this->size_ > 0)
{ {
// Can also dispatch with // Can dispatch with
// - std::execution::parallel_unsequenced_policy // - std::execution::parallel_unsequenced_policy
// - std::execution::unsequenced_policy // - std::execution::unsequenced_policy
std::copy(list.cbegin(), list.cend(), this->v_); std::copy(list.cbegin(), list.cend(), this->v_);
} }
} }
@ -136,14 +134,18 @@ void Foam::UList<T>::deepCopy(const IndirectListBase<T, Addr>& list)
} }
else if (this->size_) else if (this->size_)
{ {
// copyList() // Copy the indirect list contents
// NB: operator[] for list read access (eg, an indirect list)
// cannot replace with std::copy
const label len = this->size_; const label len = this->size_;
List_ACCESS(T, (*this), lhs); auto iter = this->v_;
for (label i = 0; i < len; ++i)
for (label i = 0; i < len; (void)++i, (void)++iter)
{ {
lhs[i] = list[i]; *iter = list[i];
} }
} }
} }
@ -151,18 +153,11 @@ void Foam::UList<T>::deepCopy(const IndirectListBase<T, Addr>& list)
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
// This is non-inlined to allow template specializations
template<class T> template<class T>
void Foam::UList<T>::operator=(const Foam::zero) void Foam::UList<T>::operator=(const Foam::zero)
{ {
// fill_uniform() this->fill_uniform(Foam::zero{});
const label len = this->size();
List_ACCESS(T, (*this), vp);
for (label i = 0; i < len; ++i)
{
vp[i] = Zero;
}
} }
@ -186,13 +181,17 @@ Foam::label Foam::UList<T>::find(const T& val, label pos) const
{ {
const label len = this->size(); const label len = this->size();
if (pos >= 0 && len) if (pos >= 0)
{ {
List_CONST_ACCESS(T, (*this), list); // auto iter = std::find(this->begin(pos), this->end(), val);
// if (iter != this->end())
// {
// return label(iter - this->begin());
// }
while (pos < len) while (pos < len)
{ {
if (list[pos] == val) if (this->v_[pos] == val)
{ {
return pos; return pos;
} }
@ -214,11 +213,9 @@ Foam::label Foam::UList<T>::rfind(const T& val, label pos) const
pos = this->size()-1; pos = this->size()-1;
} }
List_CONST_ACCESS(T, (*this), list);
while (pos >= 0) while (pos >= 0)
{ {
if (list[pos] == val) if (this->v_[pos] == val)
{ {
return pos; return pos;
} }
@ -235,28 +232,14 @@ Foam::label Foam::UList<T>::rfind(const T& val, label pos) const
template<class T> template<class T>
bool Foam::UList<T>::operator==(const UList<T>& list) const bool Foam::UList<T>::operator==(const UList<T>& list) const
{ {
/// OR: // Can dispatch with
/// return // - std::execution::parallel_unsequenced_policy
/// ( // - std::execution::unsequenced_policy
/// (this->size_ == list.size_) return
// && std::equal(cbegin(), cend(), list.cbegin()) (
/// ); (this->size_ == list.size_)
&& std::equal(this->cbegin(), this->cend(), list.cbegin())
const label len = this->size_; );
if (len != list.size_)
{
return false;
}
List_CONST_ACCESS(T, (*this), lhs);
List_CONST_ACCESS(T, (list), rhs);
for (label i = 0; i < len; ++i)
{
if (!(lhs[i] == rhs[i])) return false;
}
return true;
} }
@ -270,35 +253,14 @@ bool Foam::UList<T>::operator!=(const UList<T>& list) const
template<class T> template<class T>
bool Foam::UList<T>::operator<(const UList<T>& list) const bool Foam::UList<T>::operator<(const UList<T>& list) const
{ {
/// OR: // Can dispatch with
/// return std::lexicographical_compare // - std::execution::parallel_unsequenced_policy
/// ( // - std::execution::unsequenced_policy
/// cbegin(), cend(), return std::lexicographical_compare
/// list.cbegin(), list.cend()
/// );
const const_iterator last1 = cend();
const const_iterator last2 = list.cend();
for
( (
const_iterator lhs = cbegin(), rhs = list.cbegin(); this->cbegin(), this->cend(),
(lhs != last1) && (rhs != last2); list.cbegin(), list.cend()
++lhs, (void) ++rhs );
)
{
if (*lhs < *rhs)
{
return true;
}
else if (*rhs < *lhs)
{
return false;
}
}
// Contents look to be identical, or lists have different sizes
return (this->size_ < list.size_);
} }
@ -328,6 +290,7 @@ bool Foam::UList<T>::operator>=(const UList<T>& list) const
template<class T> template<class T>
void Foam::sort(UList<T>& list) void Foam::sort(UList<T>& list)
{ {
// With which std::execution:: ?
std::sort(list.begin(), list.end()); std::sort(list.begin(), list.end());
} }
@ -335,6 +298,7 @@ void Foam::sort(UList<T>& list)
template<class T, class Compare> template<class T, class Compare>
void Foam::sort(UList<T>& list, const Compare& comp) void Foam::sort(UList<T>& list, const Compare& comp)
{ {
// With which std::execution:: ?
std::sort(list.begin(), list.end(), comp); std::sort(list.begin(), list.end(), comp);
} }
@ -342,6 +306,7 @@ void Foam::sort(UList<T>& list, const Compare& comp)
template<class T> template<class T>
void Foam::stableSort(UList<T>& list) void Foam::stableSort(UList<T>& list)
{ {
// With which std::execution:: ?
std::stable_sort(list.begin(), list.end()); std::stable_sort(list.begin(), list.end());
} }
@ -349,6 +314,7 @@ void Foam::stableSort(UList<T>& list)
template<class T, class Compare> template<class T, class Compare>
void Foam::stableSort(UList<T>& list, const Compare& comp) void Foam::stableSort(UList<T>& list, const Compare& comp)
{ {
// With which std::execution:: ?
std::stable_sort(list.begin(), list.end(), comp); std::stable_sort(list.begin(), list.end(), comp);
} }

View File

@ -122,6 +122,10 @@ protected:
// Caution: method name subject to change // Caution: method name subject to change
inline void fill_uniform(const T& val); inline void fill_uniform(const T& val);
//- Assign all entries to zero
// Caution: method name subject to change
inline void fill_uniform(const Foam::zero);
//- No copy assignment (default: shallow copy) //- No copy assignment (default: shallow copy)
// //
// Assignment may need to be shallow (copy pointer) // Assignment may need to be shallow (copy pointer)
@ -628,16 +632,18 @@ public:
template<> template<>
Istream& UList<char>::readList(Istream& is); Istream& UList<char>::readList(Istream& is);
//- Specialized writeEntry for character lists which always uses //- Character list writeEntry - always uses binary format.
//- binary format.
template<> template<>
void UList<char>::writeEntry(Ostream& os) const; void UList<char>::writeEntry(Ostream& os) const;
//- Specialized writeList for character lists which always uses //- Character list writeList - always uses binary format.
//- binary format.
template<> template<>
Ostream& UList<char>::writeList(Ostream& os, const label /*unused*/) const; Ostream& UList<char>::writeList(Ostream& os, const label /*unused*/) const;
//- Character list assign zero - avoids Foam::zero casting ambiguities
template<>
void UList<char>::operator=(const Foam::zero);
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //

View File

@ -52,17 +52,42 @@ inline Foam::UList<T>::UList(T* __restrict__ v, const label len) noexcept
template<class T> template<class T>
inline void Foam::UList<T>::fill_uniform(const T& val) inline void Foam::UList<T>::fill_uniform(const T& val)
{ {
// Can also dispatch with // Can dispatch with
// - std::execution::parallel_unsequenced_policy // - std::execution::parallel_unsequenced_policy
// - std::execution::unsequenced_policy // - std::execution::unsequenced_policy
std::fill_n
(
this->v_, this->size_, val
);
}
if (this->size_ > 0)
template<class T>
inline void Foam::UList<T>::fill_uniform(const Foam::zero)
{
// Note: ambiguous conversions for char can still cause compilation
// issues.
// May also have special triggers when assigning non-contiguous from zero...
if (is_contiguous<T>::value)
{ {
// Can dispatch with
// - std::execution::parallel_unsequenced_policy
// - std::execution::unsequenced_policy
std::fill_n std::fill_n
( (
this->v_, this->size_, val this->data_bytes(), this->size_bytes(), char(0)
); );
} }
else
{
const auto last = (this->v_ + this->size_);
for (auto first = this->v_; (first != last); (void)++first)
{
*first = Foam::zero{};
}
}
} }
@ -196,18 +221,16 @@ inline void Foam::UList<T>::checkIndex(const label i) const
template<class T> template<class T>
inline bool Foam::UList<T>::uniform() const inline bool Foam::UList<T>::uniform() const
{ {
const label len = size(); if (!size_)
if (!len)
{ {
return false; return false;
} }
const T& val = (*this)[0]; // first // std::all_of()
for (label i = 1; i < len; ++i) for (label i = 1; i < size_; ++i)
{ {
if (val != (*this)[i]) if (this->v_[0] != this->v_[i])
{ {
return false; return false;
} }
@ -318,7 +341,7 @@ namespace Foam
return Foam::pTraits<bool>::zero; return Foam::pTraits<bool>::zero;
} }
} } // End namespace Foam
template<class T> template<class T>

View File

@ -293,6 +293,9 @@ public:
//- Copy append another list to the end of this list //- Copy append another list to the end of this list
inline void push_back(const UList<T>& list); inline void push_back(const UList<T>& list);
//- Move append another list to the end of this list
inline void push_back(List<T>&& list);
//- Reduce size by 1 or more elements. Can be called on an empty list. //- Reduce size by 1 or more elements. Can be called on an empty list.
inline void pop_back(label n = 1); inline void pop_back(label n = 1);

View File

@ -408,14 +408,16 @@ inline void Foam::DynamicField<T, SizeMin>::resize
const T& val const T& val
) )
{ {
label idx = List<T>::size(); const label oldLen = List<T>::size();
resize(len); resize(len);
// Fill newly exposed with constant value // Fill newly exposed with constant value
while (idx < len) if (oldLen < List<T>::size())
{ {
this->operator[](idx) = val; std::fill
++idx; (
this->begin(oldLen), this->end(), val
);
} }
} }
@ -596,7 +598,7 @@ inline T& Foam::DynamicField<T, SizeMin>::emplace_back(Args&&... args)
// move assign element // move assign element
this->operator[](idx) = T(std::forward<Args>(args)...); this->operator[](idx) = T(std::forward<Args>(args)...);
return this->back(); return this->operator[](idx);
} }
@ -639,13 +641,32 @@ inline void Foam::DynamicField<T, SizeMin>::push_back
<< abort(FatalError); << abort(FatalError);
} }
label idx = List<T>::size(); const label idx = List<T>::size();
resize(idx + list.size()); resize(idx + list.size());
for (const T& val : list) std::copy(list.begin(), list.end(), this->begin(idx));
}
template<class T, int SizeMin>
inline void Foam::DynamicField<T, SizeMin>::push_back
(
List<T>&& list
)
{
if (this == &list)
{ {
this->operator[](idx++) = val; // copy element FatalErrorInFunction
<< "Attempted push_back to self"
<< abort(FatalError);
} }
const label idx = List<T>::size();
resize(idx + list.size());
std::move(list.begin(), list.end(), this->begin(idx));
list.clear();
} }

View File

@ -128,7 +128,7 @@ Foam::Matrix<Form, Type>::Matrix(const label m, const label n, const Foam::zero)
doAlloc(); doAlloc();
std::fill(begin(), end(), Zero); std::fill_n(begin(), size(), Zero);
} }
@ -143,7 +143,7 @@ Foam::Matrix<Form, Type>::Matrix(const label m, const label n, const Type& val)
doAlloc(); doAlloc();
std::fill(begin(), end(), val); std::fill_n(begin(), size(), val);
} }
@ -244,10 +244,7 @@ inline Foam::Matrix<Form, Type>::Matrix
template<class Form, class Type> template<class Form, class Type>
Foam::Matrix<Form, Type>::~Matrix() Foam::Matrix<Form, Type>::~Matrix()
{ {
if (v_) delete[] v_;
{
delete[] v_;
}
} }
@ -594,14 +591,14 @@ void Foam::Matrix<Form, Type>::operator=
template<class Form, class Type> template<class Form, class Type>
void Foam::Matrix<Form, Type>::operator=(const Type& val) void Foam::Matrix<Form, Type>::operator=(const Type& val)
{ {
std::fill(begin(), end(), val); std::fill_n(begin(), size(), val);
} }
template<class Form, class Type> template<class Form, class Type>
void Foam::Matrix<Form, Type>::operator=(const Foam::zero) void Foam::Matrix<Form, Type>::operator=(const Foam::zero)
{ {
std::fill(begin(), end(), Zero); std::fill_n(begin(), size(), Zero);
} }

View File

@ -188,10 +188,22 @@ public:
// Access // Access
//- The number of rows //- The number of rows
inline label m() const noexcept; label mRows() const noexcept { return mRows_; }
//- The number of rows
label nRows() const noexcept { return mRows_; }
//- The number of rows
label m() const noexcept { return mRows_; }
//- The number of columns //- The number of columns
inline label n() const noexcept; label nCols() const noexcept { return nCols_; }
//- The number of columns
label n() const noexcept { return nCols_; }
//- Return true if Matrix is empty (i.e., size() is zero)
inline bool empty() const noexcept;
//- The number of elements in Matrix (m*n) //- The number of elements in Matrix (m*n)
inline label size() const; inline label size() const;
@ -199,9 +211,6 @@ public:
//- Return row/column sizes //- Return row/column sizes
inline labelPair sizes() const; inline labelPair sizes() const;
//- Return true if Matrix is empty (i.e., size() is zero)
inline bool empty() const noexcept;
//- Return const pointer to the first data element, which can also //- Return const pointer to the first data element, which can also
//- be used to address into Matrix contents //- be used to address into Matrix contents
inline const Type* cdata() const noexcept; inline const Type* cdata() const noexcept;
@ -510,25 +519,6 @@ public:
// Housekeeping // Housekeeping
//- The number of rows - same as m()
inline label mRows() const noexcept
{
return mRows_;
}
//- The number of rows - same as m()
inline label nRows() const noexcept
{
return mRows_;
}
//- The number of columns - same as n()
inline label nCols() const noexcept
{
return nCols_;
}
//- Deprecated(2019-04) raw data pointer, const access //- Deprecated(2019-04) raw data pointer, const access
// \deprecated(2019-04) - use cdata() method // \deprecated(2019-04) - use cdata() method
FOAM_DEPRECATED_FOR(2019-04, "cdata() method") FOAM_DEPRECATED_FOR(2019-04, "cdata() method")

View File

@ -92,20 +92,6 @@ inline const Foam::Matrix<Form, Type>& Foam::Matrix<Form, Type>::null()
} }
template<class Form, class Type>
inline Foam::label Foam::Matrix<Form, Type>::m() const noexcept
{
return mRows_;
}
template<class Form, class Type>
inline Foam::label Foam::Matrix<Form, Type>::n() const noexcept
{
return nCols_;
}
template<class Form, class Type> template<class Form, class Type>
inline Foam::label Foam::Matrix<Form, Type>::size() const inline Foam::label Foam::Matrix<Form, Type>::size() const
{ {
@ -181,11 +167,12 @@ inline bool Foam::Matrix<Form, Type>::uniform() const
{ {
const label len = size(); const label len = size();
if (len == 0) if (!len)
{ {
return false; return false;
} }
// std::all_of()
for (label idx = 1; idx < len; ++idx) for (label idx = 1; idx < len; ++idx)
{ {
if (v_[0] != v_[idx]) if (v_[0] != v_[idx])

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2022 OpenCFD Ltd. Copyright (C) 2019-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -118,7 +118,7 @@ bool Foam::Matrix<Form, Type>::readMatrix(Istream& is)
is.fatalCheck("readMatrix : reading the single entry"); is.fatalCheck("readMatrix : reading the single entry");
std::fill(begin(), end(), element); std::fill_n(begin(), size(), element);
} }
} }

View File

@ -188,6 +188,13 @@ Istream& UList<char>::readList(Istream& is)
return is; return is;
} }
template<>
void UList<char>::operator=(const Foam::zero)
{
UList<char>::operator=(char(0));
}
} // End namespace Foam } // End namespace Foam
// ************************************************************************* // // ************************************************************************* //