diff --git a/applications/test/charList/Test-charList.C b/applications/test/charList/Test-charList.C index 3288c3b7f0..270e255ae8 100644 --- a/applications/test/charList/Test-charList.C +++ b/applications/test/charList/Test-charList.C @@ -79,6 +79,13 @@ int main(int argc, char *argv[]) List alphabet(istr); Info<< "re-read: " << alphabet << nl; + + // Can assign zero? +//Fails: alphabet = char(Zero); + alphabet = Foam::zero{}; + + // alphabet = '@'; + Info<< "blanked: " << alphabet << nl; } return 0; diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedList.H b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H index 39d679c024..eb512faab1 100644 --- a/src/OpenFOAM/containers/Bits/PackedList/PackedList.H +++ b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H @@ -457,10 +457,10 @@ public: inline reference operator[](const label i); //- Copy assignment. - inline void operator=(const PackedList& lst); + inline void operator=(const PackedList& list); //- Move assignment. - inline void operator=(PackedList&& lst); + inline void operator=(PackedList&& list); //- Assign all entries to the given value. fill() inline void operator=(const unsigned int val); diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C index df8407a0b9..2da74d37bb 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2022 OpenCFD Ltd. + Copyright (C) 2017-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -36,27 +36,28 @@ Foam::label Foam::DynamicList::removeElements const labelRange& slice ) { - if (!slice.size()) + if (!slice.good()) { // No-op 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 this->resize(slice.begin_value()); } else { - // Copy (swap) down, from range rbegin() -> rend() - // followed by truncation - label j = slice.begin_value(); - const label len = this->size(); - - for (label i = slice.end_value(); i < len; ++i, ++j) - { - Foam::Swap(this->operator[](i), this->operator[](j)); - } + // Move all trailing elements down into space previously + // occupied by the slice. Truncate after + std::move + ( + this->begin(slice.end_value()), + this->end(), + this->begin(slice.begin_value()) + ); this->resize(this->size() - slice.size()); } @@ -73,14 +74,14 @@ Foam::label Foam::DynamicList::subsetElements { if (slice.begin_value() > 0) { - // Copy (swap) down - label j = slice.begin_value(); - const label len = slice.size(); - - for (label i = 0; i < len; ++i, ++j) - { - Foam::Swap(this->operator[](i), this->operator[](j)); - } + // Move elements down. + // Since begin_value > 0, the initial destination is non-overlapping + std::move + ( + this->begin(slice.begin_value()), + this->begin(slice.end_value()), + this->begin() + ); } // Don't need min size, since slice size was already checked before diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H index 77abd3d1b5..2850fb073a 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H @@ -216,9 +216,12 @@ public: // setting values (as per List usage). 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); + //- 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 //- \em without necessarily recovering old content. // If no reallocation is required, the contents remain untouched. @@ -328,7 +331,6 @@ public: //- Retain a (start,size) subset from the list. // The range is subsetted with the list size itself to ensure // result always addresses a valid section of the list. - // Remaining elements are moved down. inline label subset(const labelRange& range); //- Retain a (start,size) subset from List. diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H index c44f9f8697..432adc9dff 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H @@ -363,6 +363,18 @@ inline void Foam::DynamicList::resize } +template +inline void Foam::DynamicList::resize_fill +( + const label len, + const T& val +) +{ + this->doResize(true, len); // nocopy = true + UList::operator=(val); +} + + template inline void Foam::DynamicList::resize_nocopy ( @@ -373,18 +385,6 @@ inline void Foam::DynamicList::resize_nocopy } -// template -// inline void Foam::DynamicList::resize_fill -// ( -// const label len, -// const T& val -// ) -// { -// this->doResize(true, len); // nocopy = true -// this->fill_uniform(val); -// } - - template inline void Foam::DynamicList::resize ( @@ -392,14 +392,16 @@ inline void Foam::DynamicList::resize const T& val ) { - label idx = List::size(); + const label oldLen = List::size(); resize(len); // Fill newly exposed with constant value - while (idx < len) + if (oldLen < List::size()) { - this->operator[](idx) = val; - ++idx; + std::fill + ( + this->begin(oldLen), this->end(), val + ); } } @@ -527,8 +529,8 @@ inline T& Foam::DynamicList::emplace_back(Args&&... args) resize(idx + 1); // move assign element - this->operator[](idx) = T(std::forward(args)...); - return this->back(); + UList::operator[](idx) = T(std::forward(args)...); + return UList::operator[](idx); } @@ -541,7 +543,7 @@ inline void Foam::DynamicList::push_back const label idx = List::size(); resize(idx + 1); - this->operator[](idx) = val; // copy element + UList::operator[](idx) = val; // copy element } @@ -554,30 +556,27 @@ inline void Foam::DynamicList::push_back const label idx = List::size(); resize(idx + 1); - this->operator[](idx) = std::move(val); // move assign element + UList::operator[](idx) = std::move(val); // move assign element } template inline void Foam::DynamicList::push_back ( - const UList& lst + const UList& list ) { - if (this == &lst) + if (this == &list) { FatalErrorInFunction << "Attempted push_back to self" << abort(FatalError); } - label idx = List::size(); - resize(idx + lst.size()); + const label idx = List::size(); + resize(idx + list.size()); - for (const T& val : lst) - { - this->operator[](idx++) = val; // copy element - } + std::copy(list.begin(), list.end(), this->begin(idx)); } @@ -585,32 +584,26 @@ template template inline void Foam::DynamicList::push_back ( - const FixedList& lst + const FixedList& list ) { - label idx = List::size(); - resize(idx + lst.size()); + const label idx = List::size(); + resize(idx + list.size()); - for (const T& val : lst) - { - this->operator[](idx++) = val; // copy element - } + std::copy(list.begin(), list.end(), this->begin(idx)); } template inline void Foam::DynamicList::push_back ( - std::initializer_list lst + std::initializer_list list ) { - label idx = List::size(); - resize(idx + lst.size()); + const label idx = List::size(); + resize(idx + list.size()); - for (const T& val : lst) - { - this->operator[](idx++) = val; // copy element - } + std::copy(list.begin(), list.end(), this->begin(idx)); } @@ -618,17 +611,23 @@ template template inline void Foam::DynamicList::push_back ( - const IndirectListBase& lst + const IndirectListBase& list ) { - label idx = List::size(); - const label n = lst.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. - resize(idx + n); + const label idx = this->size(); + const label n = list.size(); - for (label i=0; ibegin(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::push_back << abort(FatalError); } - label idx = List::size(); + const label idx = List::size(); resize(idx + list.size()); - for (T& val : list) - { - Foam::Swap(this->operator[](idx++), val); // moved content - } + std::move(list.begin(), list.end(), this->begin(idx)); list.clear(); } @@ -795,7 +791,7 @@ inline T& Foam::DynamicList::operator() resize(i + 1); } - return this->operator[](i); + return UList::operator[](i); } diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListIO.C b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListIO.C index 46d15ecc7f..b22175cd80 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListIO.C +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListIO.C @@ -259,7 +259,7 @@ Foam::Istream& Foam::DynamicList::readList(Istream& is) ); // Fill with the value - this->fill_uniform(elem); + UList::operator=(elem); } } diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedList.C b/src/OpenFOAM/containers/Lists/FixedList/FixedList.C index 0c8f0f13d9..01e7752c18 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedList.C +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedList.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2017-2021 OpenCFD Ltd. + Copyright (C) 2017-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,7 +27,6 @@ License \*---------------------------------------------------------------------------*/ #include "FixedList.H" -#include "ListLoopM.H" // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // @@ -51,11 +50,15 @@ Foam::label Foam::FixedList::find(const T& val, label pos) const { 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)) { - if (list[pos] == val) + if (this->v_[pos] == val) { return pos; } @@ -77,11 +80,9 @@ Foam::label Foam::FixedList::rfind(const T& val, label pos) const pos = label(N)-1; } - List_CONST_ACCESS(T, *this, list); - while (pos >= 0) { - if (list[pos] == val) + if (this->v_[pos] == val) { return pos; } @@ -148,44 +149,30 @@ void Foam::FixedList::swapLast(const label i) template bool Foam::FixedList::operator==(const FixedList& list) const { - List_CONST_ACCESS(T, *this, lhs); - List_CONST_ACCESS(T, (list), rhs); - - // List sizes are identical by definition (template parameter) - for (unsigned i = 0; i < N; ++i) - { - if (!(lhs[i] == rhs[i])) - { - return false; - } - } - - // Contents appear to be identical. - return true; + // Can dispatch with + // - std::execution::parallel_unsequenced_policy + // - std::execution::unsequenced_policy + return + ( + // List sizes are identical by definition (template parameter) + std::equal(this->cbegin(), this->cend(), list.cbegin()) + ); } template bool Foam::FixedList::operator<(const FixedList& list) const { - List_CONST_ACCESS(T, *this, lhs); - List_CONST_ACCESS(T, (list), rhs); - // List sizes are identical by definition (template parameter) - for (unsigned i=0; icbegin(), this->cend(), + list.cbegin(), list.cend() + ); } diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H index ee935de25c..9a3f190d80 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H @@ -239,7 +239,7 @@ public: //- Return the forward circular index, i.e. next index //- 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) inline const T& fcValue(const label i) const; @@ -249,7 +249,7 @@ public: //- Return the reverse circular index, i.e. previous index //- 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) inline const T& rcValue(const label i) const; @@ -297,9 +297,15 @@ public: // Edit //- 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); + //- 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 + //- Any resizing is ignored (Fatal with bad sizing in full debug). inline void resize_nocopy(const label n); //- Dummy function, to make FixedList consistent with List diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H index 0cf3310a9b..95b45f4c6b 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H @@ -56,20 +56,16 @@ inline Foam::FixedList::FixedList(const Foam::zero) template inline Foam::FixedList::FixedList(const FixedList& list) { - for (unsigned i=0; i inline Foam::FixedList::FixedList(FixedList&& list) { - for (unsigned i=0; i inline Foam::FixedList::FixedList(std::initializer_list list) { checkSize(list.size()); - - auto iter = list.begin(); - for (unsigned i=0; i inline Foam::FixedList::FixedList(const UList& list) { checkSize(list.size()); - - for (unsigned i=0; i::FixedList const FixedList& indices ) { - for (unsigned i=0; i::FixedList const FixedList& indices ) { - for (unsigned i=0; i::back() const noexcept template -inline Foam::label Foam::FixedList::fcIndex(const label i) const +inline Foam::label Foam::FixedList::fcIndex(const label i) const noexcept { return (i == N-1 ? 0 : i+1); } @@ -245,7 +231,7 @@ inline T& Foam::FixedList::fcValue(const label i) template -inline Foam::label Foam::FixedList::rcIndex(const label i) const +inline Foam::label Foam::FixedList::rcIndex(const label i) const noexcept { return (i ? i-1 : N-1); } @@ -307,6 +293,7 @@ inline bool Foam::FixedList::uniform() const { if (empty()) return false; // <- Compile-time disabled anyhow + // std::all_of() for (unsigned i=1; i::resize(const label n) } +template +inline void Foam::FixedList::resize_fill(const label n, const T& val) +{ + #ifdef FULLDEBUG + checkSize(n); + #endif + this->fill(val); +} + + template inline void Foam::FixedList::resize_nocopy(const label n) { @@ -348,10 +345,7 @@ template inline void Foam::FixedList::fill(const T& val) { // Usually small enough that parallel execution is pointless... - for (unsigned i=0; i inline void Foam::FixedList::fill(const Foam::zero) { // Usually small enough that parallel execution is pointless... - for (unsigned i=0; i::transfer(FixedList& list) return; // Self-assignment is a no-op } - for (unsigned i=0; i inline void Foam::FixedList::operator=(const UList& list) { checkSize(list.size()); - - for (unsigned i=0; i inline void Foam::FixedList::operator=(std::initializer_list list) { checkSize(list.size()); - - auto iter = list.begin(); - for (unsigned i=0; i inline void Foam::FixedList::operator=(const T& val) { @@ -466,12 +451,11 @@ inline void Foam::FixedList::operator=(const FixedList& list) return; // Self-assignment is a no-op } - for (unsigned i=0; i inline void Foam::FixedList::operator=(FixedList&& list) { @@ -480,10 +464,8 @@ inline void Foam::FixedList::operator=(FixedList&& list) return; // Self-assignment is a no-op } - for (unsigned i=0; i::doResize(const label len) // With sign-check to avoid spurious -Walloc-size-larger-than const label overlap = min(this->size_, len); - if (!overlap) + if (overlap > 0) { - // Can discard old content before allocating new storage. - // - when used as storage for DynamicList, it is possible to have - // a zero-sized List with a non-null data pointer. - - delete[] this->v_; + // Recover overlapping content when resizing + T* old = this->v_; this->size_ = 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 { - // Recover old (overlapping) content when resizing - - T* nv = new T[len]; - - // Like std::copy(this->v_, this->v_ + overlap, nv); - // but with move semantics! - - #ifdef USEMEMCPY - if (is_contiguous::value) - { - std::memcpy - ( - static_cast(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]); - } - } - + // No overlapping content delete[] this->v_; this->size_ = len; - this->v_ = nv; + this->v_ = new T[len]; } } else @@ -138,7 +117,7 @@ Foam::List::List(const label len, const T& val) if (len) { doAlloc(); - this->fill_uniform(val); + UList::operator=(val); } } @@ -158,13 +137,7 @@ Foam::List::List(const label len, const Foam::zero) if (len) { doAlloc(); - - // fill_uniform() - List_ACCESS(T, (*this), vp); - for (label i = 0; i < len; ++i) - { - vp[i] = Zero; - } + UList::operator=(Foam::zero{}); } } @@ -249,20 +222,8 @@ Foam::List::List(const UList& list, const labelUList& indices) : UList(nullptr, indices.size()) { - const label len = indices.size(); - - if (len) - { - doAlloc(); - - // Copy indirect - List_ACCESS(T, (*this), vp); - - for (label i=0; i < len; ++i) - { - vp[i] = list[indices[i]]; - } - } + doAlloc(); + copyList(list, indices); // <- deepCopy() } @@ -274,21 +235,10 @@ Foam::List::List const FixedList& indices ) : - UList(nullptr, label(N)) + UList(nullptr, indices.size()) { - const label len = label(N); - - { - doAlloc(); - - // Copy indirect - List_ACCESS(T, (*this), vp); - - for (label i = 0; i < len; ++i) - { - vp[i] = list[indices[i]]; - } - } + doAlloc(); + copyList(list, indices); // <- deepCopy() } @@ -296,11 +246,8 @@ template template Foam::List::List(const FixedList& list) : - UList(nullptr, label(N)) -{ - doAlloc(); - copyList(list); -} + List(list.begin(), list.end(), list.size()) +{} template @@ -319,8 +266,11 @@ Foam::List::List(const IndirectListBase& list) : UList(nullptr, list.size()) { - doAlloc(); - copyList(list); + if (this->size_ > 0) + { + doAlloc(); + UList::deepCopy(list); + } } @@ -450,15 +400,9 @@ template template void Foam::List::operator=(const FixedList& list) { - reAlloc(static_cast