/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2016-2019 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template template inline void Foam::DynamicField::assignDynField ( const ListType& list ) { const label newSize = list.size(); if (capacity_ >= newSize) { // Can copy w/o reallocating - adjust addressable size accordingly. Field::size(list.size()); Field::operator=(list); } else { // Ensure list size consistency prior to copying. Field::size(capacity_); Field::operator=(list); capacity_ = Field::size(); } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template inline constexpr Foam::DynamicField::DynamicField() noexcept : Field(), capacity_(0) {} template inline Foam::DynamicField::DynamicField(const label len) : Field(len), capacity_(Field::size()) { Field::size(0); } template inline Foam::DynamicField::DynamicField ( const label len, const T& val ) : Field(len, val), capacity_(Field::size()) {} template inline Foam::DynamicField::DynamicField ( const label len, const zero ) : Field(len, Zero), capacity_(Field::size()) {} template inline Foam::DynamicField::DynamicField ( const DynamicField& list ) : Field(list), capacity_(Field::size()) {} template template inline Foam::DynamicField::DynamicField ( const DynamicField& list ) : Field(list), capacity_(Field::size()) {} template inline Foam::DynamicField::DynamicField ( const UList& list ) : Field(list), capacity_(Field::size()) {} template template inline Foam::DynamicField::DynamicField ( const IndirectListBase& list ) : Field(list), capacity_(Field::size()) {} template inline Foam::DynamicField::DynamicField ( List&& content ) : Field(std::move(content)), capacity_(Field::size()) {} template inline Foam::DynamicField::DynamicField ( DynamicField&& content ) : Field(), capacity_(0) { transfer(content); } template template inline Foam::DynamicField::DynamicField ( DynamicField&& content ) : Field(), capacity_(0) { transfer(content); } template inline Foam::DynamicField::DynamicField ( const UList& mapF, const labelUList& mapAddressing ) : Field(mapF, mapAddressing), capacity_(Field::size()) {} template inline Foam::DynamicField::DynamicField ( const UList& mapF, const labelListList& mapAddressing, const scalarListList& weights ) : Field(mapF, mapAddressing, weights), capacity_(Field::size()) {} //- Construct by mapping from the given field template inline Foam::DynamicField::DynamicField ( const UList& mapF, const FieldMapper& map ) : Field(mapF, map), capacity_(Field::size()) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template inline Foam::label Foam::DynamicField::capacity() const noexcept { return capacity_; } template inline void Foam::DynamicField::setCapacity ( const label nElem ) { label nextFree = Field::size(); capacity_ = nElem; if (nextFree > capacity_) { // truncate addressed sizes too nextFree = capacity_; } // We could also enforce sizing granularity Field::setSize(capacity_); Field::size(nextFree); } template inline void Foam::DynamicField::reserve ( const label nElem ) { // Allocate more capacity if necessary if (nElem > capacity_) { capacity_ = max ( SizeMin, max ( nElem, // label(SizeInc + capacity_ * SizeMult / SizeDiv) label(2*capacity_) ) ); // Adjust allocated size, leave addressed size untouched const label nextFree = Field::size(); Field::setSize(capacity_); Field::size(nextFree); } } template inline void Foam::DynamicField::setSize ( const label nElem ) { // Allocate more capacity if necessary if (nElem > capacity_) { capacity_ = max ( SizeMin, max ( nElem, // label(SizeInc + capacity_ * SizeMult / SizeDiv) label(2*capacity_) ) ); Field::setSize(capacity_); } // Adjust addressed size Field::size(nElem); } template inline void Foam::DynamicField::setSize ( const label nElem, const T& val ) { label nextFree = Field::size(); setSize(nElem); // Set new elements to constant value while (nextFree < nElem) { this->operator[](nextFree++) = val; } } template inline void Foam::DynamicField::resize ( const label nElem ) { this->setSize(nElem); } template inline void Foam::DynamicField::resize ( const label nElem, const T& val ) { this->setSize(nElem, val); } template inline void Foam::DynamicField::clear() { Field::size(0); } template inline void Foam::DynamicField::clearStorage() { Field::clear(); capacity_ = 0; } template inline Foam::label Foam::DynamicField::expandStorage() { const label nextFree = Field::size(); // Allow addressing into the entire list Field::size(capacity_); return nextFree; } template inline Foam::DynamicField& Foam::DynamicField::shrink() { label nextFree = Field::size(); if (capacity_ > nextFree) { // Use the full list when resizing Field::size(capacity_); // The new size capacity_ = nextFree; Field::setSize(capacity_); Field::size(nextFree); } return *this; } template template inline void Foam::DynamicField::swap ( DynamicField& lst ) { if (this == &lst) { return; // Self-swap is a no-op } DynamicList& cur = *this; // Make addressable size identical to the allocated capacity const label oldSize1 = cur.expandStorage(); const label oldSize2 = lst.expandStorage(); // Swap storage Field::swap(lst); // Match capacity to the underlying allocated list size cur.setCapacity(cur.size()); lst.setCapacity(lst.size()); // Set addressable size cur.setSize(oldSize2); lst.setSize(oldSize1); } template inline void Foam::DynamicField::transfer(List& list) { // Take over storage, clear addressing for list. capacity_ = list.size(); Field::transfer(list); } template template inline void Foam::DynamicField::transfer ( DynamicList& list ) { // Take over storage as-is (without shrink, without using SizeMin) // clear addressing and storage for old list. capacity_ = list.capacity(); Field::transfer(static_cast&>(list)); list.clearStorage(); // Ensure capacity=0 } template template inline void Foam::DynamicField::transfer ( DynamicField& list ) { if (this == &list) { return; // Self-assignment is a no-op } // Take over storage as-is (without shrink, without using SizeMin) // clear addressing and storage for old list. capacity_ = list.capacity(); Field::transfer(static_cast&>(list)); list.clearStorage(); // Ensure capacity=0 } template inline Foam::DynamicField& Foam::DynamicField::append ( const T& val ) { const label idx = List::size(); setSize(idx + 1); this->operator[](idx) = val; // copy element return *this; } template inline Foam::DynamicField& Foam::DynamicField::append ( const UList& list ) { if (this == &list) { FatalErrorInFunction << "Attempted appending to self" << abort(FatalError); } label idx = List::size(); setSize(idx + list.size()); for (const T& val : list) { this->operator[](idx++) = val; // copy element } return *this; } template inline T Foam::DynamicField::remove() { // Location of last element and simultaneously the new size const label idx = List::size() - 1; if (idx < 0) { FatalErrorInFunction << "List is empty" << abort(FatalError); } const T& val = List::operator[](idx); List::size(idx); return val; } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template inline T& Foam::DynamicField::operator() ( const label i ) { if (i >= Field::size()) { setSize(i + 1); } return this->operator[](i); } template inline void Foam::DynamicField::operator= ( const T& val ) { UList::operator=(val); } template inline void Foam::DynamicField::operator= ( const UList& list ) { assignDynField(list); } template inline void Foam::DynamicField::operator= ( const DynamicField& list ) { if (this == &list) { return; // Self-assignment is a no-op } assignDynField(list); } template inline void Foam::DynamicField::operator= ( List&& list ) { transfer(list); } template inline void Foam::DynamicField::operator= ( DynamicField&& list ) { transfer(list); } template template inline void Foam::DynamicField::operator= ( DynamicField&& list ) { transfer(list); } // ************************************************************************* //