diff --git a/applications/test/CircularBuffer/Make/files b/applications/test/CircularBuffer/Make/files index 72687d66703cac0cd5ab4cfd3c26d0bbf9b4cfaa..c0cbca5498aca0b1aac7733723bfe710f67aac95 100644 --- a/applications/test/CircularBuffer/Make/files +++ b/applications/test/CircularBuffer/Make/files @@ -1,3 +1,3 @@ -Test-CircularBuffer.C +Test-CircularBuffer.cxx EXE = $(FOAM_USER_APPBIN)/Test-CircularBuffer diff --git a/applications/test/CircularBuffer/Test-CircularBuffer.C b/applications/test/CircularBuffer/Test-CircularBuffer.cxx similarity index 100% rename from applications/test/CircularBuffer/Test-CircularBuffer.C rename to applications/test/CircularBuffer/Test-CircularBuffer.cxx diff --git a/applications/test/List/Test-List.cxx b/applications/test/List/Test-List.cxx index 9b747a5395e799ef898edf977757d16f4aecd83c..96571f642cb20f150f421d4ee93900107e259229 100644 --- a/applications/test/List/Test-List.cxx +++ b/applications/test/List/Test-List.cxx @@ -140,8 +140,46 @@ int main(int argc, char *argv[]) argList::addBoolOption("ListList", "Test list of list functionality"); argList::addBoolOption("flag"); + argList::addBoolOption("reserve", "Test ListPolicy for reserve_size"); + #include "setRootCase.H" + if (args.found("reserve")) + { + using namespace Foam::ListPolicy; + + using control = std::pair<label, label>; + + for + ( + const auto& tup : + { + control{ 10, 5 }, + control{ 20, 25 } + } + ) + { + const auto [len, capacity] = tup; + + Info<< "test " << tup << nl; + + auto size = reserve_size<16,2>(len, capacity); + Info<< " => " << size << " (ratio 2)" << nl; + + size = reserve_size<16,3,2>(len, capacity); + Info<< " => " << size << " (ratio 3/2)" << nl; + + size = reserve_size<16,13,8>(len, capacity); + Info<< " => " << size << " (ratio " << (13.0/8) << ')' << nl; + + size = reserve_size<16,25,16>(len, capacity); + Info<< " => " << size << " (ratio " << (25.0/16) << ')' << nl; + } + + Info<< nl << "\nEnd" << endl; + return 0; + } + { List<label> ident(15); Foam::identity(ident, 0); diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedList.H b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H index b55c7313ca2ca95eaeae4a7c2babdc6f5e6a4f9b..5bdbbceb6a1b57054205c9955c6c7a31714c5f1b 100644 --- a/src/OpenFOAM/containers/Bits/PackedList/PackedList.H +++ b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H @@ -393,6 +393,11 @@ public: // Never shrinks the allocated size. inline void reserve(const label numElem); + //- Reserve allocation space for at least this size + //- (uses the specified size without any other resizing strategy). + // Never shrinks the allocated size. + inline void reserve_exact(const label numElem); + //- Clear the list, i.e. set addressable size to zero. // Does not adjust the underlying storage inline void clear(); diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H b/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H index cb58bf6d9aaaf73d25a7a8d1ab0a95768840024a..8bdd10ddcc7bf15cf6052de2fc74de43f1801b8e 100644 --- a/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H +++ b/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H @@ -547,7 +547,26 @@ inline void Foam::PackedList<Width>::reserve(const label numElem) blocks_.resize ( // SizeMin=16, allocation doubling - max(16, max(newLen, 2*oldLen)), + Foam::max(16, Foam::max(newLen, 2*oldLen)), + 0u + ); + } +} + + +template<unsigned Width> +inline void Foam::PackedList<Width>::reserve_exact(const label numElem) +{ + const label oldLen = blocks_.size(); + const label newLen = num_blocks(numElem); + + // Allocate more capacity if necessary + if (oldLen < newLen) + { + blocks_.resize + ( + // SizeMin=16 + Foam::max(16, newLen), 0u ); } diff --git a/src/OpenFOAM/containers/Buffers/CircularBuffer.C b/src/OpenFOAM/containers/Buffers/CircularBuffer.C index 30e1661320aaa6ad05a00a0054f70fb542985450..706befd3f17434ad6499f7565ca242666acdee69 100644 --- a/src/OpenFOAM/containers/Buffers/CircularBuffer.C +++ b/src/OpenFOAM/containers/Buffers/CircularBuffer.C @@ -38,7 +38,14 @@ void Foam::CircularBuffer<T>::doReserve { // Increase capacity (doubling) const label newCapacity = - max(min_size(), max(len+1, label(2*storage_.size()))); + Foam::max(min_size(), Foam::max(len+1, label(2*storage_.size()))); + + // OR + // Foam::ListPolicy::reserve_size<min_size(), 2> + // ( + // len+1, + // storage_.size() + // ); if (nocopy || empty()) { diff --git a/src/OpenFOAM/containers/Buffers/CircularBufferI.H b/src/OpenFOAM/containers/Buffers/CircularBufferI.H index dadbf0ddb61cbe23741da58df33adc5f4ec94cfa..a4d5b218c0ad7ab0857be863afce103317eaf9e9 100644 --- a/src/OpenFOAM/containers/Buffers/CircularBufferI.H +++ b/src/OpenFOAM/containers/Buffers/CircularBufferI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2022-2023 OpenCFD Ltd. + Copyright (C) 2022-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -122,7 +122,7 @@ inline constexpr Foam::CircularBuffer<T>::CircularBuffer() noexcept template<class T> inline Foam::CircularBuffer<T>::CircularBuffer(const label len) : - storage_(max(min_size(), len + 1)), + storage_(Foam::max(min_size(), len+1)), begin_(0), end_(0) {} diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H index 1ab95b9f1cc463f7f0bb5ac0645205a74d867d03..78385c9b5bf28009b50f5c636cf9223e7cffd00d 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2023 OpenCFD Ltd. + Copyright (C) 2016-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -165,6 +165,10 @@ public: explicit DynamicList(Istream& is); + //- Destructor, sync allocated size before List destruction + ~DynamicList() { List<T>::setAddressableSize(capacity_); } + + // Member Functions // Capacity @@ -208,6 +212,12 @@ public: // Never shrinks the allocated size, use setCapacity() for that. inline void reserve_nocopy(const label len); + //- Reserve allocation space for at least this size, allocating new + //- space if required and \em retaining old content. + //- If allocation is required, uses the specified size + //- without any other resizing logic. + inline void reserve_exact(const label len); + //- Alter addressable list size, allocating new space if required //- while \em recovering old content. // If no reallocation is required, the contents remain untouched. diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H index 8ad549eecd6c149df461b6cc4cd3fb2757239688..a3c004cd8ae094e8fca80ed0bbb6a33b98ecf9ab 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2023 OpenCFD Ltd. + Copyright (C) 2016-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -66,7 +66,7 @@ inline void Foam::DynamicList<T, SizeMin>::doCapacity } // Addressable length, possibly truncated by new capacity - const label currLen = min(List<T>::size(), newCapacity); + const label currLen = Foam::min(List<T>::size(), newCapacity); // Corner case... if (List<T>::size() == newCapacity) @@ -104,8 +104,9 @@ inline void Foam::DynamicList<T, SizeMin>::doReserve // Preserve addressed size const label currLen = List<T>::size(); - // Increase capacity (doubling) - capacity_ = max(SizeMin, max(len, label(2*capacity_))); + // Increase capacity (eg, doubling) + capacity_ = + Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_); if (nocopy) { @@ -355,6 +356,24 @@ inline void Foam::DynamicList<T, SizeMin>::reserve_nocopy } +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::reserve_exact +( + const label len +) +{ + if (capacity_ < len) + { + // Preserve addressed size + const label currLen = List<T>::size(); + + capacity_ = len; + List<T>::resize(capacity_); + List<T>::setAddressableSize(currLen); + } +} + + template<class T, int SizeMin> inline void Foam::DynamicList<T, SizeMin>::resize ( diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListIO.C b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListIO.C index 996c51cff15008cf9934969df9c20304ba0eb8d0..63e9cf3561b6bc270e2551c69d4db909a9a732ac 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListIO.C +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListIO.C @@ -153,7 +153,7 @@ bool Foam::DynamicList<T, SizeMin>::readBracketList(Istream& is) List<T> currChunk(std::move(*(chunks[chunki]))); chunks[chunki].reset(nullptr); - const label localLen = min(currChunk.size(), totalCount); + const label localLen = Foam::min(currChunk.size(), totalCount); dest = std::move ( diff --git a/src/OpenFOAM/containers/Lists/List/List.C b/src/OpenFOAM/containers/Lists/List/List.C index 61e23d1e73d958ebaa838e3fe7bbb80a10bf0862..bdf09f58c576f4757c1a79add657fcc6e93d9599 100644 --- a/src/OpenFOAM/containers/Lists/List/List.C +++ b/src/OpenFOAM/containers/Lists/List/List.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2017-2023 OpenCFD Ltd. + Copyright (C) 2017-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -44,7 +44,7 @@ void Foam::List<T>::doResize(const label len) if (len > 0) { // With sign-check to avoid spurious -Walloc-size-larger-than - const label overlap = min(this->size_, len); + const label overlap = Foam::min(this->size_, len); if (overlap > 0) { diff --git a/src/OpenFOAM/containers/Lists/List/ListIO.C b/src/OpenFOAM/containers/Lists/List/ListIO.C index 490860c1df47e891e8702c04151d361fcfc54c13..b5c7ebfc43368be8558b44ceb3851556fb1cefda 100644 --- a/src/OpenFOAM/containers/Lists/List/ListIO.C +++ b/src/OpenFOAM/containers/Lists/List/ListIO.C @@ -153,7 +153,7 @@ bool Foam::List<T>::readBracketList(Istream& is) List<T> currChunk(std::move(*(chunks[chunki]))); chunks[chunki].reset(nullptr); - const label localLen = min(currChunk.size(), totalCount); + const label localLen = Foam::min(currChunk.size(), totalCount); dest = std::move ( diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C index 4824a41915645eb916e0f06e3dc957a2222c45cf..db6e00a88aadf12abd6a192997de9141c911af39 100644 --- a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C +++ b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2015-2024 OpenCFD Ltd. + Copyright (C) 2015-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -645,7 +645,7 @@ void Foam::inplaceSubset const label outlen = (select.size() - select.count()); - const label len = min(input.size(), select.size()); + const label len = Foam::min(input.size(), select.size()); for (label i=0; i < len; ++i) { @@ -1285,9 +1285,7 @@ void Foam::ListOps::setValue const T& val ) { - const label len = list.size(); - const label count = locations.size(); - const label end = min(count, len); + const label end = Foam::min(list.size(), locations.size()); // The efficiency is modest for (label index = 0; index < end; ++index) diff --git a/src/OpenFOAM/containers/Lists/policy/ListPolicy.H b/src/OpenFOAM/containers/Lists/policy/ListPolicy.H index 1482c155f944923f6e2429f317ebfd3816057f17..ed81c10d8f644142ab518b2e0baa2ba1ac10041d 100644 --- a/src/OpenFOAM/containers/Lists/policy/ListPolicy.H +++ b/src/OpenFOAM/containers/Lists/policy/ListPolicy.H @@ -86,6 +86,63 @@ template<> struct no_linebreak<word> : std::true_type {}; template<> struct no_linebreak<wordRe> : std::true_type {}; +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +//- Calculate a reserve size (eg, doubling) based on the request length +//- and the current capacity +template<int SizeMin, int Numerator, class IntType> +inline IntType reserve_size(IntType requested, IntType capacity) +{ + static_assert(Numerator > 1, "Invalid numerator"); + + // The caller already checks this: + // if (requested < capacity) { return capacity; } + + IntType size(capacity*Numerator); + if (size < requested) + { + size = requested; + } + if constexpr (SizeMin > 0) // The min size is optional + { + if (size < SizeMin) + { + size = SizeMin; + } + } + return size; +} + + +//- Calculate a reserve size based on the request length +//- and the current capacity +template<int SizeMin, int Numerator, int Denominator, class IntType> +inline IntType reserve_size(IntType requested, IntType capacity) +{ + static_assert(Numerator > Denominator, "Invalid numerator"); + static_assert(Denominator > 0, "Invalid denominator"); + + // The caller already checks this: + // if (requested < capacity) { return capacity; } + + // Very unlikely that capacity is less than Denominator, + // so divide before multiply to avoid overflow + IntType size((capacity/Denominator)*Numerator); + if (size < requested) + { + size = requested; + } + if constexpr (SizeMin > 0) // The min size is optional + { + if (size < SizeMin) + { + size = SizeMin; + } + } + return size; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // //- Classification of list/container uniformity. diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H index 09f44c928a2234457b063988a465bc66603a5ab4..ee33bbef2d2391be473f95be6a97172937a3b6e6 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -96,8 +96,8 @@ public: inline explicit PtrDynList(UList<T*>& list); - //- Destructor - ~PtrDynList() = default; + //- Destructor, sync allocated size before list destruction + ~PtrDynList() { PtrList<T>::setAddressableSize(capacity_); } // Member Functions @@ -110,6 +110,11 @@ public: //- Reserve allocation space for at least this size. inline void reserve(const label len); + //- Reserve allocation space for at least this size. + //- If allocation is required, uses the specified size + //- without any other resizing logic. + inline void reserve_exact(const label len); + //- Alter the addressed list size. inline void resize(const label newLen); diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H index ba4f0ad11bb1c947527307ba49fca292940a8fa7..fccedeccfbde5895f9c64c5a736771f139f188f5 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -122,8 +122,9 @@ inline void Foam::PtrDynList<T, SizeMin>::reserve(const label len) // Preserve addressed size const label currLen = PtrList<T>::size(); - // Increase capacity (doubling) - capacity_ = max(SizeMin, max(len, label(2*capacity_))); + // Increase capacity (eg, doubling) + capacity_ = + Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_); PtrList<T>::resize(capacity_); PtrList<T>::setAddressableSize(currLen); @@ -131,6 +132,21 @@ inline void Foam::PtrDynList<T, SizeMin>::reserve(const label len) } +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::reserve_exact(const label len) +{ + if (capacity_ < len) + { + // Preserve addressed size + const label currLen = PtrList<T>::size(); + + capacity_ = len; + PtrList<T>::resize(capacity_); + PtrList<T>::setAddressableSize(currLen); + } +} + + template<class T, int SizeMin> inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen) { @@ -140,8 +156,9 @@ inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen) if (capacity_ < newLen) { - // Increase capacity (doubling) - capacity_ = max(SizeMin, max(newLen, label(2*capacity_))); + // Increase capacity (eg, doubling) + capacity_ = + Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_); PtrList<T>::resize(capacity_); } @@ -165,8 +182,9 @@ inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label newLen) { if (capacity_ < newLen) { - // Increase capacity (doubling) - capacity_ = max(SizeMin, max(newLen, label(2*capacity_))); + // Increase capacity (eg, doubling) + capacity_ = + Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_); PtrList<T>::resize_null(capacity_); } diff --git a/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H index ea9ef6abe058bae6f7d2b98d83eed61ed0c0d726..5d3638c5b1f7ea2d24e55c9556473b1967b7372d 100644 --- a/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H +++ b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H @@ -521,6 +521,8 @@ public: // Increase capacity (doubling) newCapacity = Foam::max(label(len), label(2*storage_.size())); + // ratio=1.5: + // Foam::max(label(len), label((storage_.size()/2)*3)); } // Info<<"request:" << len diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H index 602e6f1cce085e36ec46ddfacfa798342a4aa9b4..5f73c83e117d2889b10e25575bca5f85d7eab7aa 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2023 OpenCFD Ltd. + Copyright (C) 2016-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -147,6 +147,17 @@ public: template<int AnySizeMin> inline DynamicField(DynamicList<T, AnySizeMin>&& content) noexcept; + //- Copy or move construct from DynamicField + template<int AnySizeMin> + inline DynamicField(DynamicField<T, AnySizeMin>& content, bool reuse); + + //- Copy or move construct from DynamicList + template<int AnySizeMin> + inline DynamicField(DynamicList<T, AnySizeMin>& content, bool reuse); + + //- Copy or move construct from List + inline DynamicField(List<T>& content, bool reuse); + //- Construct by 1 to 1 mapping from the given field inline DynamicField ( @@ -176,6 +187,10 @@ public: inline tmp<DynamicField<T, SizeMin>> clone() const; + //- Destructor, sync allocated size before list destruction + ~DynamicField() { List<T>::setAddressableSize(capacity_); } + + // Member Functions // Capacity @@ -219,6 +234,12 @@ public: // Never shrinks the allocated size, use setCapacity() for that. inline void reserve_nocopy(const label len); + //- Reserve allocation space for at least this size, allocating new + //- space if required and \em retaining old content. + //- If allocation is required, uses the specified size + //- without any other resizing logic. + inline void reserve_exact(const label len); + //- Alter addressable list size, allocating new space if required //- while \em recovering old content. // If no reallocation is required, the contents remain untouched. diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H index 453c602450e673cf609daa504a4672a7962af6b6..18012d91f2bd88363e5a0df23900fa3e3aeb7217 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2023 OpenCFD Ltd. + Copyright (C) 2016-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -64,7 +64,7 @@ inline void Foam::DynamicField<T, SizeMin>::doCapacity } // Addressable length, possibly truncated by new capacity - const label currLen = min(List<T>::size(), newCapacity); + const label currLen = Foam::min(List<T>::size(), newCapacity); // Corner case - see comments in DynamicList doCapacity if (List<T>::size() == newCapacity) @@ -98,8 +98,9 @@ inline void Foam::DynamicField<T, SizeMin>::doReserve // Preserve addressed size const label currLen = List<T>::size(); - // Increase capacity (doubling) - capacity_ = max(SizeMin, max(len, label(2*capacity_))); + // Increase capacity (eg, doubling) + capacity_ = + Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_); if (nocopy) { @@ -268,6 +269,77 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField } +template<class T, int SizeMin> +template<int AnySizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField +( + DynamicField<T, AnySizeMin>& content, + bool reuse +) +: + Field<T>(), + capacity_(0) +{ + if (reuse) + { + Field<T>::transfer(static_cast<List<T>&>(content)); + capacity_ = content.capacity(); + content.setCapacity_unsafe(0); + } + else + { + Field<T>::operator=(content); + capacity_ = content.size(); + } +} + + +template<class T, int SizeMin> +template<int AnySizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField +( + DynamicList<T, AnySizeMin>& content, + bool reuse +) +: + Field<T>(), + capacity_(0) +{ + if (reuse) + { + Field<T>::transfer(static_cast<List<T>&>(content)); + capacity_ = content.capacity(); + content.setCapacity_unsafe(0); + } + else + { + Field<T>::operator=(content); + capacity_ = content.size(); + } +} + + +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField +( + List<T>& content, + bool reuse +) +: + Field<T>(), + capacity_(content.size()) +{ + if (reuse) + { + Field<T>::transfer(content); + } + else + { + Field<T>::operator=(content); + } +} + + template<class T, int SizeMin> inline Foam::DynamicField<T, SizeMin>::DynamicField ( @@ -381,6 +453,24 @@ inline void Foam::DynamicField<T, SizeMin>::reserve_nocopy } +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::reserve_exact +( + const label len +) +{ + if (capacity_ < len) + { + // Preserve addressed size + const label currLen = List<T>::size(); + + capacity_ = len; + List<T>::resize(capacity_); + List<T>::setAddressableSize(currLen); + } +} + + template<class T, int SizeMin> inline void Foam::DynamicField<T, SizeMin>::resize ( diff --git a/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C b/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C index bd942e25d1078ae0f898d1b27c62116751fa2ff8..15cf5e75650edc7fef27a26e4dde73633562b230 100644 --- a/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C +++ b/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C @@ -1083,10 +1083,19 @@ Foam::labelList Foam::surfaceFeatures::selectFeatureEdges { DynamicList<label> selectedEdges; - if (regionEdges) + // Presizing { - selectedEdges.setCapacity(selectedEdges.size() + nRegionEdges()); + label count = 0; + + if (regionEdges) count += nRegionEdges(); + if (externalEdges) count += nExternalEdges(); + if (internalEdges) count += nInternalEdges(); + + selectedEdges.reserve_exact(count); + } + if (regionEdges) + { for (label i = 0; i < externalStart_; i++) { selectedEdges.append(featureEdges_[i]); @@ -1095,8 +1104,6 @@ Foam::labelList Foam::surfaceFeatures::selectFeatureEdges if (externalEdges) { - selectedEdges.setCapacity(selectedEdges.size() + nExternalEdges()); - for (label i = externalStart_; i < internalStart_; i++) { selectedEdges.append(featureEdges_[i]); @@ -1105,8 +1112,6 @@ Foam::labelList Foam::surfaceFeatures::selectFeatureEdges if (internalEdges) { - selectedEdges.setCapacity(selectedEdges.size() + nInternalEdges()); - for (label i = internalStart_; i < featureEdges_.size(); i++) { selectedEdges.append(featureEdges_[i]);